2 * iaxclient: a cross-platform IAX softphone library
5 * Copyright (C) 2003-2006, Horizon Wimba, Inc.
6 * Copyright (C) 2007, Wimba, Inc.
9 * Steve Kann <stevek@stevek.com>
10 * Michael Van Donselaar <mvand@vandonselaar.org>
11 * Shawn Lawrence <shawn.lawrence@terracecomm.com>
13 * This program is free software, distributed under the terms of
14 * the GNU Lesser (Library) General Public License.
17 #include "audio_encode.h"
18 #include "iaxclient_lib.h"
19 #include "iax-client.h"
21 #include "codec_gsm.h"
23 #include "codec_ulaw.h"
24 #include "codec_alaw.h"
26 #include "codec_speex.h"
27 #include <speex/speex_preprocess.h>
30 #include "codec_ilbc.h"
33 float iaxci_silence_threshold = AUDIO_ENCODE_SILENCE_DB;
35 static float input_level = 0.0f;
36 static float output_level = 0.0f;
38 static SpeexPreprocessState *st = NULL;
39 static int speex_state_size = 0;
40 static int speex_state_rate = 0;
42 int iaxci_filters = IAXC_FILTER_AGC|IAXC_FILTER_DENOISE|IAXC_FILTER_AAGC|IAXC_FILTER_CN;
44 /* use to measure time since last audio was processed */
45 static struct timeval timeLastInput ;
46 static struct timeval timeLastOutput ;
48 static struct iaxc_speex_settings speex_settings =
50 1, /* decode_enhance */
51 -1, /* float quality */
59 static float vol_to_db(float vol)
61 /* avoid calling log10() on zero which yields inf or
62 * negative numbers which yield nan */
64 return AUDIO_ENCODE_SILENCE_DB;
66 return log10f(vol) * 20.0f;
69 static int do_level_callback()
71 static struct timeval last = {0,0};
78 if ( last.tv_sec != 0 && iaxci_usecdiff(&now, &last) < 100000 )
83 /* if input has not been processed in the last second, set to silent */
84 input_db = iaxci_usecdiff(&now, &timeLastInput) < 1000000 ?
85 vol_to_db(input_level) : AUDIO_ENCODE_SILENCE_DB;
87 /* if output has not been processed in the last second, set to silent */
88 output_db = iaxci_usecdiff(&now, &timeLastOutput) < 1000000 ?
89 vol_to_db(output_level) : AUDIO_ENCODE_SILENCE_DB;
91 iaxci_do_levels_callback(input_db, output_db);
96 static void set_speex_filters()
103 i = 1; /* always make VAD decision */
104 speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_VAD, &i);
105 i = (iaxci_filters & IAXC_FILTER_AGC) ? 1 : 0;
106 speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);
107 i = (iaxci_filters & IAXC_FILTER_DENOISE) ? 1 : 0;
108 speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i);
111 * We can tweak these parameters to play with VAD sensitivity.
112 * For now, we use the default values since it seems they are a good starting point.
113 * However, if need be, this is the code that needs to change
116 speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_START, &i);
118 speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &i);
121 static void calculate_level(short *audio, int len, float *level)
126 for ( i = 0; i < len; i++ )
128 const int sample = abs(audio[i]);
129 big_sample = sample > big_sample ?
133 *level += ((float)big_sample / 32767.0f - *level) / 5.0f;
137 static int input_postprocess(void *audio, int len, int rate)
139 static float lowest_volume = 1.0f;
143 if ( !st || speex_state_size != len || speex_state_rate != rate )
146 speex_preprocess_state_destroy(st);
147 st = speex_preprocess_state_init(len,rate);
148 speex_state_size = len;
149 speex_state_rate = rate;
153 calculate_level((short *)audio, len, &input_level);
155 /* only preprocess if we're interested in VAD, AGC, or DENOISE */
156 if ( (iaxci_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC)) ||
157 iaxci_silence_threshold > 0.0f )
158 silent = !speex_preprocess(st, (spx_int16_t *)audio, NULL);
160 /* Analog AGC: Bring speex AGC gain out to mixer, with lots of hysteresis */
161 /* use a higher continuation threshold for AAGC than for VAD itself */
163 iaxci_silence_threshold != 0.0f &&
164 (iaxci_filters & IAXC_FILTER_AGC) &&
165 (iaxci_filters & IAXC_FILTER_AAGC)
172 if ( (i & 0x3f) == 0 )
175 #ifdef SPEEX_PREPROCESS_GET_AGC_LOUDNESS
176 speex_preprocess_ctl(st, SPEEX_PREPROCESS_GET_AGC_LOUDNESS, &loudness);
178 loudness = st->loudness2;
180 if ( loudness > 8000.0f || loudness < 4000.0f )
182 const float level = iaxc_input_level_get();
184 if ( loudness > 16000.0f && level > 0.5f )
186 /* lower quickly if we're really too hot */
187 iaxc_input_level_set(level - 0.2f);
189 else if ( loudness > 8000.0f && level >= 0.15f )
191 /* lower less quickly if we're a bit too hot */
192 iaxc_input_level_set(level - 0.1f);
194 else if ( loudness < 4000.0f && level <= 0.9f )
196 /* raise slowly if we're cold */
197 iaxc_input_level_set(level + 0.1f);
203 /* This is ugly. Basically just don't get volume level if speex thought
204 * we were silent. Just set it to 0 in that case */
205 if ( iaxci_silence_threshold > 0.0f && silent )
210 volume = vol_to_db(input_level);
212 if ( volume < lowest_volume )
213 lowest_volume = volume;
215 if ( iaxci_silence_threshold > 0.0f )
218 return volume < iaxci_silence_threshold;
221 static int output_postprocess(void *audio, int len)
223 calculate_level((short *)audio, len, &output_level);
230 static struct iaxc_audio_codec *create_codec(int format)
232 switch (format & IAXC_AUDIO_FORMAT_MASK)
235 case IAXC_FORMAT_GSM:
236 return codec_audio_gsm_new();
238 case IAXC_FORMAT_ULAW:
239 return codec_audio_ulaw_new();
240 case IAXC_FORMAT_ALAW:
241 return codec_audio_alaw_new();
242 case IAXC_FORMAT_SPEEX:
243 return codec_audio_speex_new(&speex_settings);
245 case IAXC_FORMAT_ILBC:
246 return codec_audio_ilbc_new();
249 /* ERROR: codec not supported */
250 fprintf(stderr, "ERROR: Codec not supported: %d\n", format);
255 EXPORT void iaxc_set_speex_settings(int decode_enhance, float quality,
256 int bitrate, int vbr, int abr, int complexity)
258 speex_settings.decode_enhance = decode_enhance;
259 speex_settings.quality = quality;
260 speex_settings.bitrate = bitrate;
261 speex_settings.vbr = vbr;
262 speex_settings.abr = abr;
263 speex_settings.complexity = complexity;
266 int audio_send_encoded_audio(struct iaxc_call *call, int callNo, void *data,
267 int format, int samples)
269 unsigned char outbuf[1024];
272 int insize = samples;
274 /* update last input timestamp */
275 timeLastInput = iax_tvnow();
277 silent = input_postprocess(data, insize, 8000);
282 { /* send a Comfort Noise Frame */
284 if ( iaxci_filters & IAXC_FILTER_CN )
285 iax_send_cng(call->session, 10, NULL, 0);
287 return 0; /* poof! no encoding! */
290 /* we're going to send voice now */
293 /* destroy encoder if it is incorrect type */
294 if(call->encoder && call->encoder->format != format)
296 call->encoder->destroy(call->encoder);
297 call->encoder = NULL;
300 /* just break early if there's no format defined: this happens for the
301 * first couple of frames of new calls */
302 if(format == 0) return 0;
304 /* create encoder if necessary */
307 call->encoder = create_codec(format);
312 /* ERROR: no codec */
313 fprintf(stderr, "ERROR: Codec could not be created: %d\n", format);
317 if(call->encoder->encode(call->encoder, &insize, (short *)data,
320 /* ERROR: codec error */
321 fprintf(stderr, "ERROR: encode error: %d\n", format);
325 if(samples-insize == 0)
327 fprintf(stderr, "ERROR encoding (no samples output (samples=%d)\n", samples);
331 // Send the encoded audio data back to the app if required
332 // TODO: fix the stupid way in which the encoded audio size is returned
333 if ( iaxc_get_audio_prefs() & IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED )
334 iaxci_do_audio_callback(callNo, 0, IAXC_SOURCE_LOCAL, 1,
335 call->encoder->format & IAXC_AUDIO_FORMAT_MASK,
336 sizeof(outbuf) - outsize, outbuf);
338 if(iax_send_voice(call->session,format, outbuf,
339 sizeof(outbuf) - outsize, samples-insize) == -1)
341 fprintf(stderr, "Failed to send voice! %s\n", iax_errstr);
348 /* decode encoded audio; return the number of bytes decoded
349 * negative indicates error */
350 int audio_decode_audio(struct iaxc_call * call, void * out, void * data, int len,
351 int format, int * samples)
354 int outsize = *samples;
356 timeLastOutput = iax_tvnow();
360 fprintf(stderr, "audio_decode_audio: Format is zero (should't happen)!\n");
364 /* destroy decoder if it is incorrect type */
365 if ( call->decoder && call->decoder->format != format )
367 call->decoder->destroy(call->decoder);
368 call->decoder = NULL;
371 /* create decoder if necessary */
372 if ( !call->decoder )
374 call->decoder = create_codec(format);
377 if ( !call->decoder )
379 fprintf(stderr, "ERROR: Codec could not be created: %d\n",
384 if ( call->decoder->decode(call->decoder,
385 &insize, (unsigned char *)data,
386 &outsize, (short *)out) )
388 fprintf(stderr, "ERROR: decode error: %d\n", format);
392 output_postprocess(out, *samples - outsize);
398 EXPORT int iaxc_get_filters(void)
400 return iaxci_filters;
403 EXPORT void iaxc_set_filters(int filters)
405 iaxci_filters = filters;
409 EXPORT void iaxc_set_silence_threshold(float thr)
411 iaxci_silence_threshold = thr;