include "logger.h" and errno.h from asterisk.h - usage shows that they
[asterisk/asterisk.git] / codecs / codec_speex.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19
20 /*! \file
21  *
22  * \brief Translate between signed linear and Speex (Open Codec)
23  *
24  * \note This work was motivated by Jeremy McNamara 
25  * hacked to be configurable by anthm and bkw 9/28/2004
26  *
27  * \ingroup codecs
28  *
29  * \extref The Speex library - http://www.speex.org
30  *
31  */
32
33 /*** MODULEINFO
34         <depend>speex</depend>
35  ***/
36
37 #include "asterisk.h"
38
39 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
40
41 #include <fcntl.h>
42 #include <netinet/in.h>
43 #include <speex/speex.h>
44
45 /* We require a post 1.1.8 version of Speex to enable preprocessing
46    and better type handling */   
47 #ifdef _SPEEX_TYPES_H
48 #include <speex/speex_preprocess.h>
49 #endif
50
51 #include "asterisk/lock.h"
52 #include "asterisk/translate.h"
53 #include "asterisk/module.h"
54 #include "asterisk/config.h"
55 #include "asterisk/options.h"
56 #include "asterisk/channel.h"
57 #include "asterisk/utils.h"
58
59 /* Sample frame data */
60 #include "slin_speex_ex.h"
61 #include "speex_slin_ex.h"
62
63 /* codec variables */
64 static int quality = 3;
65 static int complexity = 2;
66 static int enhancement = 0;
67 static int vad = 0;
68 static int vbr = 0;
69 static float vbr_quality = 4;
70 static int abr = 0;
71 static int dtx = 0;     /* set to 1 to enable silence detection */
72
73 static int preproc = 0;
74 static int pp_vad = 0;
75 static int pp_agc = 0;
76 static float pp_agc_level = 8000; /* XXX what is this 8000 ? */
77 static int pp_denoise = 0;
78 static int pp_dereverb = 0;
79 static float pp_dereverb_decay = 0.4;
80 static float pp_dereverb_level = 0.3;
81
82 #define TYPE_SILENCE     0x2
83 #define TYPE_HIGH        0x0
84 #define TYPE_LOW         0x1
85 #define TYPE_MASK        0x3
86
87 #define BUFFER_SAMPLES  8000
88 #define SPEEX_SAMPLES   160
89
90 struct speex_coder_pvt {
91         void *speex;
92         SpeexBits bits;
93         int framesize;
94         int silent_state;
95 #ifdef _SPEEX_TYPES_H
96         SpeexPreprocessState *pp;
97         spx_int16_t buf[BUFFER_SAMPLES];
98 #else
99         int16_t buf[BUFFER_SAMPLES];    /* input, waiting to be compressed */
100 #endif
101 };
102
103
104 static int lintospeex_new(struct ast_trans_pvt *pvt)
105 {
106         struct speex_coder_pvt *tmp = pvt->pvt;
107
108         if (!(tmp->speex = speex_encoder_init(&speex_nb_mode)))
109                 return -1;
110
111         speex_bits_init(&tmp->bits);
112         speex_bits_reset(&tmp->bits);
113         speex_encoder_ctl(tmp->speex, SPEEX_GET_FRAME_SIZE, &tmp->framesize);
114         speex_encoder_ctl(tmp->speex, SPEEX_SET_COMPLEXITY, &complexity);
115 #ifdef _SPEEX_TYPES_H
116         if (preproc) {
117                 tmp->pp = speex_preprocess_state_init(tmp->framesize, 8000); /* XXX what is this 8000 ? */
118                 speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_VAD, &pp_vad);
119                 speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_AGC, &pp_agc);
120                 speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &pp_agc_level);
121                 speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DENOISE, &pp_denoise);
122                 speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB, &pp_dereverb);
123                 speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &pp_dereverb_decay);
124                 speex_preprocess_ctl(tmp->pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &pp_dereverb_level);
125         }
126 #endif
127         if (!abr && !vbr) {
128                 speex_encoder_ctl(tmp->speex, SPEEX_SET_QUALITY, &quality);
129                 if (vad)
130                         speex_encoder_ctl(tmp->speex, SPEEX_SET_VAD, &vad);
131         }
132         if (vbr) {
133                 speex_encoder_ctl(tmp->speex, SPEEX_SET_VBR, &vbr);
134                 speex_encoder_ctl(tmp->speex, SPEEX_SET_VBR_QUALITY, &vbr_quality);
135         }
136         if (abr)
137                 speex_encoder_ctl(tmp->speex, SPEEX_SET_ABR, &abr);
138         if (dtx)
139                 speex_encoder_ctl(tmp->speex, SPEEX_SET_DTX, &dtx); 
140         tmp->silent_state = 0;
141
142         return 0;
143 }
144
145 static int speextolin_new(struct ast_trans_pvt *pvt)
146 {
147         struct speex_coder_pvt *tmp = pvt->pvt;
148         
149         if (!(tmp->speex = speex_decoder_init(&speex_nb_mode)))
150                 return -1;
151
152         speex_bits_init(&tmp->bits);
153         speex_decoder_ctl(tmp->speex, SPEEX_GET_FRAME_SIZE, &tmp->framesize);
154         if (enhancement)
155                 speex_decoder_ctl(tmp->speex, SPEEX_SET_ENH, &enhancement);
156
157         return 0;
158 }
159
160 static struct ast_frame *lintospeex_sample(void)
161 {
162         static struct ast_frame f;
163         f.frametype = AST_FRAME_VOICE;
164         f.subclass = AST_FORMAT_SLINEAR;
165         f.datalen = sizeof(slin_speex_ex);
166         /* Assume 8000 Hz */
167         f.samples = sizeof(slin_speex_ex)/2;
168         f.mallocd = 0;
169         f.offset = 0;
170         f.src = __PRETTY_FUNCTION__;
171         f.data = slin_speex_ex;
172         return &f;
173 }
174
175 static struct ast_frame *speextolin_sample(void)
176 {
177         static struct ast_frame f;
178         f.frametype = AST_FRAME_VOICE;
179         f.subclass = AST_FORMAT_SPEEX;
180         f.datalen = sizeof(speex_slin_ex);
181         /* All frames are 20 ms long */
182         f.samples = SPEEX_SAMPLES;
183         f.mallocd = 0;
184         f.offset = 0;
185         f.src = __PRETTY_FUNCTION__;
186         f.data = speex_slin_ex;
187         return &f;
188 }
189
190 /*! \brief convert and store into outbuf */
191 static int speextolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
192 {
193         struct speex_coder_pvt *tmp = pvt->pvt;
194
195         /* Assuming there's space left, decode into the current buffer at
196            the tail location.  Read in as many frames as there are */
197         int x;
198         int res;
199         int16_t *dst = (int16_t *)pvt->outbuf;
200         /* XXX fout is a temporary buffer, may have different types */
201 #ifdef _SPEEX_TYPES_H
202         spx_int16_t fout[1024];
203 #else
204         float fout[1024];
205 #endif
206
207         if (f->datalen == 0) {  /* Native PLC interpolation */
208                 if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) {
209                         ast_log(LOG_WARNING, "Out of buffer space\n");
210                         return -1;
211                 }
212 #ifdef _SPEEX_TYPES_H
213                 speex_decode_int(tmp->speex, NULL, dst + pvt->samples);
214 #else
215                 speex_decode(tmp->speex, NULL, fout);
216                 for (x=0;x<tmp->framesize;x++) {
217                         dst[pvt->samples + x] = (int16_t)fout[x];
218                 }
219 #endif
220                 pvt->samples += tmp->framesize;
221                 pvt->datalen += 2 * tmp->framesize; /* 2 bytes/sample */
222                 return 0;
223         }
224
225         /* Read in bits */
226         speex_bits_read_from(&tmp->bits, f->data, f->datalen);
227         for (;;) {
228 #ifdef _SPEEX_TYPES_H
229                 res = speex_decode_int(tmp->speex, &tmp->bits, fout);
230 #else
231                 res = speex_decode(tmp->speex, &tmp->bits, fout);
232 #endif
233                 if (res < 0)
234                         break;
235                 if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) {
236                         ast_log(LOG_WARNING, "Out of buffer space\n");
237                         return -1;
238                 }
239                 for (x = 0 ; x < tmp->framesize; x++)
240                         dst[pvt->samples + x] = (int16_t)fout[x];
241                 pvt->samples += tmp->framesize;
242                 pvt->datalen += 2 * tmp->framesize; /* 2 bytes/sample */
243         }
244         return 0;
245 }
246
247 /*! \brief store input frame in work buffer */
248 static int lintospeex_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
249 {
250         struct speex_coder_pvt *tmp = pvt->pvt;
251
252         /* XXX We should look at how old the rest of our stream is, and if it
253            is too old, then we should overwrite it entirely, otherwise we can
254            get artifacts of earlier talk that do not belong */
255         memcpy(tmp->buf + pvt->samples, f->data, f->datalen);
256         pvt->samples += f->samples;
257         return 0;
258 }
259
260 /*! \brief convert work buffer and produce output frame */
261 static struct ast_frame *lintospeex_frameout(struct ast_trans_pvt *pvt)
262 {
263         struct speex_coder_pvt *tmp = pvt->pvt;
264         int is_speech=1;
265         int datalen = 0;        /* output bytes */
266         int samples = 0;        /* output samples */
267
268         /* We can't work on anything less than a frame in size */
269         if (pvt->samples < tmp->framesize)
270                 return NULL;
271         speex_bits_reset(&tmp->bits);
272         while (pvt->samples >= tmp->framesize) {
273 #ifdef _SPEEX_TYPES_H
274                 /* Preprocess audio */
275                 if (preproc)
276                         is_speech = speex_preprocess(tmp->pp, tmp->buf + samples, NULL);
277                 /* Encode a frame of data */
278                 if (is_speech) {
279                         /* If DTX enabled speex_encode returns 0 during silence */
280                         is_speech = speex_encode_int(tmp->speex, tmp->buf + samples, &tmp->bits) || !dtx;
281                 } else {
282                         /* 5 zeros interpreted by Speex as silence (submode 0) */
283                         speex_bits_pack(&tmp->bits, 0, 5);
284                 }
285 #else
286                 {
287                         float fbuf[1024];
288                         int x;
289                         /* Convert to floating point */
290                         for (x = 0; x < tmp->framesize; x++)
291                                 fbuf[x] = tmp->buf[samples + x];
292                         /* Encode a frame of data */
293                         is_speech = speex_encode(tmp->speex, fbuf, &tmp->bits) || !dtx;
294                 }
295 #endif
296                 samples += tmp->framesize;
297                 pvt->samples -= tmp->framesize;
298         }
299
300         /* Move the data at the end of the buffer to the front */
301         if (pvt->samples)
302                 memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
303
304         /* Use AST_FRAME_CNG to signify the start of any silence period */
305         if (is_speech) {
306                 tmp->silent_state = 0;
307         } else {
308                 if (tmp->silent_state) {
309                         return NULL;
310                 } else {
311                         tmp->silent_state = 1;
312                         speex_bits_reset(&tmp->bits);
313                         memset(&pvt->f, 0, sizeof(pvt->f));
314                         pvt->f.frametype = AST_FRAME_CNG;
315                         pvt->f.samples = samples;
316                         /* XXX what now ? format etc... */
317                 }
318         }
319
320         /* Terminate bit stream */
321         speex_bits_pack(&tmp->bits, 15, 5);
322         datalen = speex_bits_write(&tmp->bits, pvt->outbuf, pvt->t->buf_size);
323         return ast_trans_frameout(pvt, datalen, samples);
324 }
325
326 static void speextolin_destroy(struct ast_trans_pvt *arg)
327 {
328         struct speex_coder_pvt *pvt = arg->pvt;
329
330         speex_decoder_destroy(pvt->speex);
331         speex_bits_destroy(&pvt->bits);
332 }
333
334 static void lintospeex_destroy(struct ast_trans_pvt *arg)
335 {
336         struct speex_coder_pvt *pvt = arg->pvt;
337 #ifdef _SPEEX_TYPES_H
338         if (preproc)
339                 speex_preprocess_state_destroy(pvt->pp);
340 #endif
341         speex_encoder_destroy(pvt->speex);
342         speex_bits_destroy(&pvt->bits);
343 }
344
345 static struct ast_translator speextolin = {
346         .name = "speextolin", 
347         .srcfmt = AST_FORMAT_SPEEX,
348         .dstfmt =  AST_FORMAT_SLINEAR,
349         .newpvt = speextolin_new,
350         .framein = speextolin_framein,
351         .destroy = speextolin_destroy,
352         .sample = speextolin_sample,
353         .desc_size = sizeof(struct speex_coder_pvt),
354         .buffer_samples = BUFFER_SAMPLES,
355         .buf_size = BUFFER_SAMPLES * 2,
356         .native_plc = 1,
357 };
358
359 static struct ast_translator lintospeex = {
360         .name = "lintospeex", 
361         .srcfmt = AST_FORMAT_SLINEAR,
362         .dstfmt = AST_FORMAT_SPEEX,
363         .newpvt = lintospeex_new,
364         .framein = lintospeex_framein,
365         .frameout = lintospeex_frameout,
366         .destroy = lintospeex_destroy,
367         .sample = lintospeex_sample,
368         .desc_size = sizeof(struct speex_coder_pvt),
369         .buffer_samples = BUFFER_SAMPLES,
370         .buf_size = BUFFER_SAMPLES * 2, /* XXX maybe a lot less ? */
371 };
372
373 static int parse_config(int reload) 
374 {
375         struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
376         struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
377         struct ast_variable *var;
378         int res;
379         float res_f;
380
381         if (cfg == NULL || cfg == CONFIG_STATUS_FILEUNCHANGED)
382                 return -1;
383         if (cfg == CONFIG_STATUS_FILEUNCHANGED)
384                 return 0;
385
386         for (var = ast_variable_browse(cfg, "speex"); var; var = var->next) {
387                 if (!strcasecmp(var->name, "quality")) {
388                         res = abs(atoi(var->value));
389                         if (res > -1 && res < 11) {
390                                 ast_verb(3, "CODEC SPEEX: Setting Quality to %d\n",res);
391                                 quality = res;
392                         } else 
393                                 ast_log(LOG_ERROR,"Error Quality must be 0-10\n");
394                 } else if (!strcasecmp(var->name, "complexity")) {
395                         res = abs(atoi(var->value));
396                         if (res > -1 && res < 11) {
397                                 ast_verb(3, "CODEC SPEEX: Setting Complexity to %d\n",res);
398                                 complexity = res;
399                         } else 
400                                 ast_log(LOG_ERROR,"Error! Complexity must be 0-10\n");
401                 } else if (!strcasecmp(var->name, "vbr_quality")) {
402                         if (sscanf(var->value, "%f", &res_f) == 1 && res_f >= 0 && res_f <= 10) {
403                                 ast_verb(3, "CODEC SPEEX: Setting VBR Quality to %f\n",res_f);
404                                 vbr_quality = res_f;
405                         } else
406                                 ast_log(LOG_ERROR,"Error! VBR Quality must be 0-10\n");
407                 } else if (!strcasecmp(var->name, "abr_quality")) {
408                         ast_log(LOG_ERROR,"Error! ABR Quality setting obsolete, set ABR to desired bitrate\n");
409                 } else if (!strcasecmp(var->name, "enhancement")) {
410                         enhancement = ast_true(var->value) ? 1 : 0;
411                         ast_verb(3, "CODEC SPEEX: Perceptual Enhancement Mode. [%s]\n",enhancement ? "on" : "off");
412                 } else if (!strcasecmp(var->name, "vbr")) {
413                         vbr = ast_true(var->value) ? 1 : 0;
414                         ast_verb(3, "CODEC SPEEX: VBR Mode. [%s]\n",vbr ? "on" : "off");
415                 } else if (!strcasecmp(var->name, "abr")) {
416                         res = abs(atoi(var->value));
417                         if (res >= 0) {
418                                         if (res > 0)
419                                         ast_verb(3, "CODEC SPEEX: Setting ABR target bitrate to %d\n",res);
420                                         else
421                                         ast_verb(3, "CODEC SPEEX: Disabling ABR\n");
422                                 abr = res;
423                         } else 
424                                 ast_log(LOG_ERROR,"Error! ABR target bitrate must be >= 0\n");
425                 } else if (!strcasecmp(var->name, "vad")) {
426                         vad = ast_true(var->value) ? 1 : 0;
427                         ast_verb(3, "CODEC SPEEX: VAD Mode. [%s]\n",vad ? "on" : "off");
428                 } else if (!strcasecmp(var->name, "dtx")) {
429                         dtx = ast_true(var->value) ? 1 : 0;
430                         ast_verb(3, "CODEC SPEEX: DTX Mode. [%s]\n",dtx ? "on" : "off");
431                 } else if (!strcasecmp(var->name, "preprocess")) {
432                         preproc = ast_true(var->value) ? 1 : 0;
433                         ast_verb(3, "CODEC SPEEX: Preprocessing. [%s]\n",preproc ? "on" : "off");
434                 } else if (!strcasecmp(var->name, "pp_vad")) {
435                         pp_vad = ast_true(var->value) ? 1 : 0;
436                         ast_verb(3, "CODEC SPEEX: Preprocessor VAD. [%s]\n",pp_vad ? "on" : "off");
437                 } else if (!strcasecmp(var->name, "pp_agc")) {
438                         pp_agc = ast_true(var->value) ? 1 : 0;
439                         ast_verb(3, "CODEC SPEEX: Preprocessor AGC. [%s]\n",pp_agc ? "on" : "off");
440                 } else if (!strcasecmp(var->name, "pp_agc_level")) {
441                         if (sscanf(var->value, "%f", &res_f) == 1 && res_f >= 0) {
442                                 ast_verb(3, "CODEC SPEEX: Setting preprocessor AGC Level to %f\n",res_f);
443                                 pp_agc_level = res_f;
444                         } else
445                                 ast_log(LOG_ERROR,"Error! Preprocessor AGC Level must be >= 0\n");
446                 } else if (!strcasecmp(var->name, "pp_denoise")) {
447                         pp_denoise = ast_true(var->value) ? 1 : 0;
448                         ast_verb(3, "CODEC SPEEX: Preprocessor Denoise. [%s]\n",pp_denoise ? "on" : "off");
449                 } else if (!strcasecmp(var->name, "pp_dereverb")) {
450                         pp_dereverb = ast_true(var->value) ? 1 : 0;
451                         ast_verb(3, "CODEC SPEEX: Preprocessor Dereverb. [%s]\n",pp_dereverb ? "on" : "off");
452                 } else if (!strcasecmp(var->name, "pp_dereverb_decay")) {
453                         if (sscanf(var->value, "%f", &res_f) == 1 && res_f >= 0) {
454                                 ast_verb(3, "CODEC SPEEX: Setting preprocessor Dereverb Decay to %f\n",res_f);
455                                 pp_dereverb_decay = res_f;
456                         } else
457                                 ast_log(LOG_ERROR,"Error! Preprocessor Dereverb Decay must be >= 0\n");
458                 } else if (!strcasecmp(var->name, "pp_dereverb_level")) {
459                         if (sscanf(var->value, "%f", &res_f) == 1 && res_f >= 0) {
460                                 ast_verb(3, "CODEC SPEEX: Setting preprocessor Dereverb Level to %f\n",res_f);
461                                 pp_dereverb_level = res_f;
462                         } else
463                                 ast_log(LOG_ERROR,"Error! Preprocessor Dereverb Level must be >= 0\n");
464                 }
465         }
466         ast_config_destroy(cfg);
467         return 0;
468 }
469
470 static int reload(void) 
471 {
472         if (parse_config(1))
473                 return AST_MODULE_LOAD_DECLINE;
474         return AST_MODULE_LOAD_SUCCESS;
475 }
476
477 static int unload_module(void)
478 {
479         int res;
480
481         res = ast_unregister_translator(&lintospeex);
482         res |= ast_unregister_translator(&speextolin);
483
484         return res;
485 }
486
487 static int load_module(void)
488 {
489         int res;
490
491         if (parse_config(0))
492                 return AST_MODULE_LOAD_DECLINE;
493         res=ast_register_translator(&speextolin);
494         if (!res) 
495                 res=ast_register_translator(&lintospeex);
496         else
497                 ast_unregister_translator(&speextolin);
498         if (res)
499                 return AST_MODULE_LOAD_FAILURE;
500         return AST_MODULE_LOAD_SUCCESS;
501 }
502
503 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Speex Coder/Decoder",
504                 .load = load_module,
505                 .unload = unload_module,
506                 .reload = reload,
507                );