00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "codec_speex.h"
00016 #include "iaxclient_lib.h"
00017 #include "speex/speex.h"
00018
00019 struct State
00020 {
00021 void *state;
00022 int frame_size;
00023 SpeexBits bits;
00024 };
00025
00026
00027 static void destroy ( struct iaxc_audio_codec *c)
00028 {
00029 struct State * encstate = (struct State *) c->encstate;
00030 struct State * decstate = (struct State *) c->decstate;
00031
00032 speex_bits_destroy(&encstate->bits);
00033 speex_bits_destroy(&decstate->bits);
00034 speex_encoder_destroy(encstate->state);
00035 speex_decoder_destroy(decstate->state);
00036
00037 free(c->encstate);
00038 free(c->decstate);
00039
00040 free(c);
00041 }
00042
00043
00044 static int decode( struct iaxc_audio_codec *c,
00045 int *inlen, unsigned char *in, int *outlen, short *out )
00046 {
00047 struct State * decstate = (struct State *) c->decstate;
00048
00049 if ( *inlen == 0 )
00050 {
00051 speex_decode_int(decstate->state, NULL, out);
00052 *outlen -= decstate->frame_size;
00053 return 0;
00054 }
00055
00056 speex_bits_read_from(&decstate->bits, (char *) in, *inlen);
00057 *inlen = 0;
00058
00059 while ( speex_bits_remaining(&decstate->bits) &&
00060 *outlen >= decstate->frame_size )
00061 {
00062 int ret = speex_decode_int(decstate->state, &decstate->bits, out);
00063
00064
00065
00066 if (ret == 0)
00067 {
00068
00069 *outlen -= decstate->frame_size;
00070 out += decstate->frame_size;
00071 } else if (ret == -1)
00072 {
00073
00074 int bits_left = speex_bits_remaining(&decstate->bits) % 8;
00075 if(bits_left >= 5)
00076 speex_bits_advance(&decstate->bits, bits_left);
00077 else
00078 break;
00079 } else
00080 {
00081
00082 fprintf(stderr, "decode_int returned non-zero => %d\n",ret);
00083 break;
00084 }
00085 }
00086 return 0;
00087 }
00088
00089 static int encode( struct iaxc_audio_codec *c,
00090 int *inlen, short *in, int *outlen, unsigned char *out )
00091 {
00092 int bytes;
00093 struct State * encstate = (struct State *) c->encstate;
00094
00095
00096
00097
00098 speex_bits_reset(&encstate->bits);
00099
00100
00101 while(*inlen >= encstate->frame_size)
00102 {
00103
00104 speex_encode_int(encstate->state, in, &encstate->bits);
00105 *inlen -= encstate->frame_size;
00106 in += encstate->frame_size;
00107 }
00108
00109
00110 speex_bits_pack(&encstate->bits, 15, 5);
00111
00112 bytes = speex_bits_write(&encstate->bits, (char *) out, *outlen);
00113
00114
00115 *outlen -= bytes;
00116
00117 return 0;
00118 }
00119
00120 struct iaxc_audio_codec *codec_audio_speex_new(struct iaxc_speex_settings *set)
00121 {
00122 struct State * encstate;
00123 struct State * decstate;
00124 struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
00125 const SpeexMode *sm;
00126
00127 if(!c)
00128 return c;
00129
00130 strcpy(c->name,"speex");
00131 c->format = IAXC_FORMAT_SPEEX;
00132 c->encode = encode;
00133 c->decode = decode;
00134 c->destroy = destroy;
00135
00136 c->encstate = calloc(sizeof(struct State),1);
00137 c->decstate = calloc(sizeof(struct State),1);
00138
00139
00140 if(!(c->encstate && c->decstate))
00141 return NULL;
00142
00143 encstate = (struct State *) c->encstate;
00144 decstate = (struct State *) c->decstate;
00145
00146 sm = speex_lib_get_mode(SPEEX_MODEID_NB);
00147
00148 encstate->state = speex_encoder_init(sm);
00149 decstate->state = speex_decoder_init(sm);
00150 speex_bits_init(&encstate->bits);
00151 speex_bits_init(&decstate->bits);
00152 speex_bits_reset(&encstate->bits);
00153 speex_bits_reset(&decstate->bits);
00154
00155 speex_decoder_ctl(decstate->state, SPEEX_SET_ENH, &set->decode_enhance);
00156
00157 speex_encoder_ctl(encstate->state, SPEEX_SET_COMPLEXITY, &set->complexity);
00158
00159 if(set->quality >= 0) {
00160 if(set->vbr) {
00161 speex_encoder_ctl(encstate->state, SPEEX_SET_VBR_QUALITY, &set->quality);
00162 } else {
00163 int quality = (int)set->quality;
00164 speex_encoder_ctl(encstate->state, SPEEX_SET_QUALITY, &quality);
00165 }
00166 }
00167 if(set->bitrate >= 0)
00168 speex_encoder_ctl(encstate->state, SPEEX_SET_BITRATE, &set->bitrate);
00169 if(set->vbr)
00170 speex_encoder_ctl(encstate->state, SPEEX_SET_VBR, &set->vbr);
00171 if(set->abr)
00172 speex_encoder_ctl(encstate->state, SPEEX_SET_ABR, &set->abr);
00173
00174
00175 speex_encoder_ctl(encstate->state,SPEEX_GET_FRAME_SIZE,&encstate->frame_size);
00176 speex_decoder_ctl(decstate->state,SPEEX_GET_FRAME_SIZE,&decstate->frame_size);
00177
00178 c->minimum_frame_size = 160;
00179
00180 if(encstate->frame_size > c->minimum_frame_size)
00181 c->minimum_frame_size = encstate->frame_size;
00182 if(decstate->frame_size > c->minimum_frame_size)
00183 c->minimum_frame_size = decstate->frame_size;
00184
00185 if(!(encstate->state && decstate->state))
00186 return NULL;
00187
00188 return c;
00189 }
00190