2 * iaxclient: a cross-platform IAX softphone library
5 * Copyright (C) 2003-2004, Horizon Wimba, Inc.
6 * Copyright (C) 2007, Wimba, Inc.
9 * Steve Kann <stevek@stevek.com>
11 * This program is free software, distributed under the terms of
12 * the GNU Lesser (Library) General Public License.
15 #include "codec_speex.h"
16 #include "iaxclient_lib.h"
17 #include "speex/speex.h"
27 static void destroy ( struct iaxc_audio_codec *c)
29 struct State * encstate = (struct State *) c->encstate;
30 struct State * decstate = (struct State *) c->decstate;
32 speex_bits_destroy(&encstate->bits);
33 speex_bits_destroy(&decstate->bits);
34 speex_encoder_destroy(encstate->state);
35 speex_decoder_destroy(decstate->state);
44 static int decode( struct iaxc_audio_codec *c,
45 int *inlen, unsigned char *in, int *outlen, short *out )
47 struct State * decstate = (struct State *) c->decstate;
51 speex_decode_int(decstate->state, NULL, out);
52 *outlen -= decstate->frame_size;
56 speex_bits_read_from(&decstate->bits, (char *) in, *inlen);
59 while ( speex_bits_remaining(&decstate->bits) &&
60 *outlen >= decstate->frame_size )
62 int ret = speex_decode_int(decstate->state, &decstate->bits, out);
64 // from speex/speex.h, speex_decode returns:
65 // @return return status (0 for no error, -1 for end of stream, -2 other)
68 /* one frame of output */
69 *outlen -= decstate->frame_size;
70 out += decstate->frame_size;
73 /* at end of stream, or just a terminator */
74 int bits_left = speex_bits_remaining(&decstate->bits) % 8;
76 speex_bits_advance(&decstate->bits, bits_left);
81 /* maybe there's not a whole frame somehow? */
82 fprintf(stderr, "decode_int returned non-zero => %d\n",ret);
89 static int encode( struct iaxc_audio_codec *c,
90 int *inlen, short *in, int *outlen, unsigned char *out )
93 struct State * encstate = (struct State *) c->encstate;
95 /* need to encode minimum of encstate->frame_size samples */
97 /* only add terminator at end of bits */
98 speex_bits_reset(&encstate->bits);
100 /* need to encode minimum of encstate->frame_size samples */
101 while(*inlen >= encstate->frame_size)
103 //fprintf(stderr, "encode: inlen=%d outlen=%d\n", *inlen, *outlen);
104 speex_encode_int(encstate->state, in, &encstate->bits);
105 *inlen -= encstate->frame_size;
106 in += encstate->frame_size;
110 speex_bits_pack(&encstate->bits, 15, 5);
112 bytes = speex_bits_write(&encstate->bits, (char *) out, *outlen);
114 /* can an error happen here? no bytes? */
120 struct iaxc_audio_codec *codec_audio_speex_new(struct iaxc_speex_settings *set)
122 struct State * encstate;
123 struct State * decstate;
124 struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
130 strcpy(c->name,"speex");
131 c->format = IAXC_FORMAT_SPEEX;
134 c->destroy = destroy;
136 c->encstate = calloc(sizeof(struct State),1);
137 c->decstate = calloc(sizeof(struct State),1);
139 /* leaks a bit on no-memory */
140 if(!(c->encstate && c->decstate))
143 encstate = (struct State *) c->encstate;
144 decstate = (struct State *) c->decstate;
146 sm = speex_lib_get_mode(SPEEX_MODEID_NB);
148 encstate->state = speex_encoder_init(sm);
149 decstate->state = speex_decoder_init(sm);
150 speex_bits_init(&encstate->bits);
151 speex_bits_init(&decstate->bits);
152 speex_bits_reset(&encstate->bits);
153 speex_bits_reset(&decstate->bits);
155 speex_decoder_ctl(decstate->state, SPEEX_SET_ENH, &set->decode_enhance);
157 speex_encoder_ctl(encstate->state, SPEEX_SET_COMPLEXITY, &set->complexity);
159 if(set->quality >= 0) {
161 speex_encoder_ctl(encstate->state, SPEEX_SET_VBR_QUALITY, &set->quality);
163 int quality = (int)set->quality;
164 speex_encoder_ctl(encstate->state, SPEEX_SET_QUALITY, &quality);
167 if(set->bitrate >= 0)
168 speex_encoder_ctl(encstate->state, SPEEX_SET_BITRATE, &set->bitrate);
170 speex_encoder_ctl(encstate->state, SPEEX_SET_VBR, &set->vbr);
172 speex_encoder_ctl(encstate->state, SPEEX_SET_ABR, &set->abr);
174 /* set up frame sizes (normally, this is 20ms worth) */
175 speex_encoder_ctl(encstate->state,SPEEX_GET_FRAME_SIZE,&encstate->frame_size);
176 speex_decoder_ctl(decstate->state,SPEEX_GET_FRAME_SIZE,&decstate->frame_size);
178 c->minimum_frame_size = 160;
180 if(encstate->frame_size > c->minimum_frame_size)
181 c->minimum_frame_size = encstate->frame_size;
182 if(decstate->frame_size > c->minimum_frame_size)
183 c->minimum_frame_size = decstate->frame_size;
185 if(!(encstate->state && decstate->state))