Memory leak fixes Bug #4216
[asterisk/asterisk.git] / codecs / codec_lpc10.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Translate between signed linear and LPC10 (Linear Predictor Code)
5  *
6  * The lpc10 code is from a library used by nautilus, modified to be a bit
7  * nicer to the compiler.
8  *
9  * See http://www.arl.wustl.edu/~jaf/ 
10  * 
11  * Copyright (C) 1999 - 2005  Digium,inc 
12  *
13  * Mark Spencer <markster@digium.com>
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License
17  */
18
19
20 #include "asterisk/lock.h"
21 #include "asterisk/translate.h"
22 #include "asterisk/config.h"
23 #include "asterisk/options.h"
24 #include "asterisk/module.h"
25 #include "asterisk/logger.h"
26 #include "asterisk/channel.h"
27 #include <fcntl.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <netinet/in.h>
31 #include <string.h>
32 #include <stdio.h>
33
34 #include "lpc10/lpc10.h"
35
36 /* Sample frame data */
37 #include "slin_lpc10_ex.h"
38 #include "lpc10_slin_ex.h"
39
40 /* We use a very strange format here...  I have no idea why...  The frames are 180
41    samples long, which isn't even an even number of milliseconds...  Not only that
42    but we hvae to waste two bits of each frame to keep them ending on a byte boundary
43    because the frames are 54 bits long */
44
45 #define LPC10_BYTES_IN_COMPRESSED_FRAME (LPC10_BITS_IN_COMPRESSED_FRAME + 7)/8
46
47 AST_MUTEX_DEFINE_STATIC(localuser_lock);
48 static int localusecnt=0;
49
50 static char *tdesc = "LPC10 2.4kbps (signed linear) Voice Coder";
51
52 static int useplc = 0;
53
54 struct ast_translator_pvt {
55         union {
56                 struct lpc10_encoder_state *enc;
57                 struct lpc10_decoder_state *dec;
58         } lpc10;
59         struct ast_frame f;
60         /* Space to build offset */
61         char offset[AST_FRIENDLY_OFFSET];
62         /* Buffer for our outgoing frame */
63         short outbuf[8000];
64         /* Enough to store a full second */
65         short buf[8000];
66         int tail;
67         int longer;
68         plc_state_t plc; /* god only knows why I bothered to implement PLC for LPC10 :) */
69 };
70
71 #define lpc10_coder_pvt ast_translator_pvt
72
73 static struct ast_translator_pvt *lpc10_enc_new(void)
74 {
75         struct lpc10_coder_pvt *tmp;
76         tmp = malloc(sizeof(struct lpc10_coder_pvt));
77         if (tmp) {
78                 if (!(tmp->lpc10.enc = create_lpc10_encoder_state())) {
79                         free(tmp);
80                         tmp = NULL;
81                 }
82                 tmp->tail = 0;
83                 tmp->longer = 0;
84                 localusecnt++;
85         }
86         return tmp;
87 }
88
89 static struct ast_translator_pvt *lpc10_dec_new(void)
90 {
91         struct lpc10_coder_pvt *tmp;
92         tmp = malloc(sizeof(struct lpc10_coder_pvt));
93         if (tmp) {
94                 if (!(tmp->lpc10.dec = create_lpc10_decoder_state())) {
95                         free(tmp);
96                         tmp = NULL;
97                 }
98                 tmp->tail = 0;
99                 tmp->longer = 0;
100                 plc_init(&tmp->plc);
101                 localusecnt++;
102         }
103         return tmp;
104 }
105 static struct ast_frame *lintolpc10_sample(void)
106 {
107         static struct ast_frame f;
108         f.frametype = AST_FRAME_VOICE;
109         f.subclass = AST_FORMAT_SLINEAR;
110         f.datalen = sizeof(slin_lpc10_ex);
111         /* Assume 8000 Hz */
112         f.samples = LPC10_SAMPLES_PER_FRAME;
113         f.mallocd = 0;
114         f.offset = 0;
115         f.src = __PRETTY_FUNCTION__;
116         f.data = slin_lpc10_ex;
117         return &f;
118 }
119
120 static struct ast_frame *lpc10tolin_sample(void)
121 {
122         static struct ast_frame f;
123         f.frametype = AST_FRAME_VOICE;
124         f.subclass = AST_FORMAT_LPC10;
125         f.datalen = sizeof(lpc10_slin_ex);
126         /* All frames are 22 ms long (maybe a little more -- why did he choose
127            LPC10_SAMPLES_PER_FRAME sample frames anyway?? */
128         f.samples = LPC10_SAMPLES_PER_FRAME;
129         f.mallocd = 0;
130         f.offset = 0;
131         f.src = __PRETTY_FUNCTION__;
132         f.data = lpc10_slin_ex;
133         return &f;
134 }
135
136 static struct ast_frame *lpc10tolin_frameout(struct ast_translator_pvt *tmp)
137 {
138         if (!tmp->tail)
139                 return NULL;
140         /* Signed linear is no particular frame size, so just send whatever
141            we have in the buffer in one lump sum */
142         tmp->f.frametype = AST_FRAME_VOICE;
143         tmp->f.subclass = AST_FORMAT_SLINEAR;
144         tmp->f.datalen = tmp->tail * 2;
145         /* Assume 8000 Hz */
146         tmp->f.samples = tmp->tail;
147         tmp->f.mallocd = 0;
148         tmp->f.offset = AST_FRIENDLY_OFFSET;
149         tmp->f.src = __PRETTY_FUNCTION__;
150         tmp->f.data = tmp->buf;
151         /* Reset tail pointer */
152         tmp->tail = 0;
153
154 #if 0
155         /* Save a sample frame */
156         { static int samplefr = 0;
157         if (samplefr == 80) {
158                 int fd;
159                 fd = open("lpc10.example", O_WRONLY | O_CREAT, 0644);
160                 write(fd, tmp->f.data, tmp->f.datalen);
161                 close(fd);
162         }               
163         samplefr++;
164         }
165 #endif
166         return &tmp->f; 
167 }
168
169 static void extract_bits(INT32 *bits, unsigned char *c)
170 {
171         int x;
172         for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
173                 if (*c & (0x80 >> (x & 7)))
174                         bits[x] = 1;
175                 else
176                         bits[x] = 0;
177                 if ((x & 7) == 7)
178                         c++;
179         }
180 }
181
182 static void build_bits(unsigned char *c, INT32 *bits)
183 {
184         unsigned char mask=0x80;
185         int x;
186         *c = 0;
187         for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
188                 if (bits[x])
189                         *c |= mask;
190                 mask = mask >> 1;
191                 if ((x % 8)==7) {
192                         c++;
193                         *c = 0;
194                         mask = 0x80;
195                 }
196         }
197 }
198
199 static int lpc10tolin_framein(struct ast_translator_pvt *tmp, struct ast_frame *f)
200 {
201         /* Assuming there's space left, decode into the current buffer at
202            the tail location */
203         int x;
204         int len=0;
205         float tmpbuf[LPC10_SAMPLES_PER_FRAME];
206         short *sd;
207         INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];
208
209         if(f->datalen == 0) { /* perform PLC with nominal framesize of LPC10_SAMPLES_PER_FRAME */
210               if((tmp->tail + LPC10_SAMPLES_PER_FRAME) > sizeof(tmp->buf)/2) {
211                   ast_log(LOG_WARNING, "Out of buffer space\n");
212                   return -1;
213               }
214               if(useplc) {
215                   plc_fillin(&tmp->plc, tmp->buf+tmp->tail, LPC10_SAMPLES_PER_FRAME);
216                   tmp->tail += LPC10_SAMPLES_PER_FRAME;
217               }
218               return 0;
219         }
220
221         while(len + LPC10_BYTES_IN_COMPRESSED_FRAME <= f->datalen) {
222                 if (tmp->tail + LPC10_SAMPLES_PER_FRAME < sizeof(tmp->buf)/2) {
223                         sd = tmp->buf + tmp->tail;
224                         extract_bits(bits, f->data + len);
225                         if (lpc10_decode(bits, tmpbuf, tmp->lpc10.dec)) {
226                                 ast_log(LOG_WARNING, "Invalid lpc10 data\n");
227                                 return -1;
228                         }
229                         for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
230                                 /* Convert to a real between -1.0 and 1.0 */
231                                 sd[x] = 32768.0 * tmpbuf[x];
232                         }
233
234                         if(useplc) plc_rx(&tmp->plc, tmp->buf + tmp->tail, LPC10_SAMPLES_PER_FRAME);
235                         
236                         tmp->tail+=LPC10_SAMPLES_PER_FRAME;
237                 } else {
238                         ast_log(LOG_WARNING, "Out of buffer space\n");
239                         return -1;
240                 }
241                 len += LPC10_BYTES_IN_COMPRESSED_FRAME;
242         }
243         if (len != f->datalen) 
244                 printf("Decoded %d, expected %d\n", len, f->datalen);
245         return 0;
246 }
247
248 static int lintolpc10_framein(struct ast_translator_pvt *tmp, struct ast_frame *f)
249 {
250         /* Just add the frames to our stream */
251         /* XXX We should look at how old the rest of our stream is, and if it
252            is too old, then we should overwrite it entirely, otherwise we can
253            get artifacts of earlier talk that do not belong */
254         if (tmp->tail + f->datalen < sizeof(tmp->buf) / 2) {
255                 memcpy((tmp->buf + tmp->tail), f->data, f->datalen);
256                 tmp->tail += f->datalen/2;
257         } else {
258                 ast_log(LOG_WARNING, "Out of buffer space\n");
259                 return -1;
260         }
261         return 0;
262 }
263
264 static struct ast_frame *lintolpc10_frameout(struct ast_translator_pvt *tmp)
265 {
266         int x;
267         int consumed = 0;
268         float tmpbuf[LPC10_SAMPLES_PER_FRAME];
269         INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];
270         /* We can't work on anything less than a frame in size */
271         if (tmp->tail < LPC10_SAMPLES_PER_FRAME)
272                 return NULL;
273         /* Start with an empty frame */
274         tmp->f.samples = 0;
275         tmp->f.datalen = 0;
276         tmp->f.frametype = AST_FRAME_VOICE;
277         tmp->f.subclass = AST_FORMAT_LPC10;
278         while(tmp->tail >=  LPC10_SAMPLES_PER_FRAME) {
279                 if (tmp->f.datalen + LPC10_BYTES_IN_COMPRESSED_FRAME > sizeof(tmp->outbuf)) {
280                         ast_log(LOG_WARNING, "Out of buffer space\n");
281                         return NULL;
282                 }
283                 /* Encode a frame of data */
284                 for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
285                         tmpbuf[x] = (float)tmp->buf[x+consumed] / 32768.0;
286                 }
287                 lpc10_encode(tmpbuf, bits, tmp->lpc10.enc);
288                 build_bits(((unsigned char *)tmp->outbuf) + tmp->f.datalen, bits);
289                 tmp->f.datalen += LPC10_BYTES_IN_COMPRESSED_FRAME;
290                 tmp->f.samples += LPC10_SAMPLES_PER_FRAME;
291                 /* Use one of the two left over bits to record if this is a 22 or 23 ms frame...
292                    important for IAX use */
293                 tmp->longer = 1 - tmp->longer;
294 #if 0   /* what the heck was this for? */
295                 ((char *)(tmp->f.data))[consumed - 1] |= tmp->longer;
296 #endif          
297                 tmp->tail -= LPC10_SAMPLES_PER_FRAME;
298                 consumed += LPC10_SAMPLES_PER_FRAME;
299         }
300         tmp->f.mallocd = 0;
301         tmp->f.offset = AST_FRIENDLY_OFFSET;
302         tmp->f.src = __PRETTY_FUNCTION__;
303         tmp->f.data = tmp->outbuf;
304         /* Move the data at the end of the buffer to the front */
305         if (tmp->tail)
306                 memmove(tmp->buf, tmp->buf + consumed, tmp->tail * 2);
307 #if 0
308         /* Save a sample frame */
309         { static int samplefr = 0;
310         if (samplefr == 0) {
311                 int fd;
312                 fd = open("lpc10.example", O_WRONLY | O_CREAT, 0644);
313                 write(fd, tmp->f.data, tmp->f.datalen);
314                 close(fd);
315         }               
316         samplefr++;
317         }
318 #endif
319         return &tmp->f; 
320 }
321
322 static void lpc10_destroy(struct ast_translator_pvt *pvt)
323 {
324         /* Enc and DEC are both just allocated, so they can be freed */
325         free(pvt->lpc10.enc);
326         free(pvt);
327         localusecnt--;
328 }
329
330 static struct ast_translator lpc10tolin =
331         { "lpc10tolin", 
332            AST_FORMAT_LPC10, AST_FORMAT_SLINEAR,
333            lpc10_dec_new,
334            lpc10tolin_framein,
335            lpc10tolin_frameout,
336            lpc10_destroy,
337            lpc10tolin_sample
338            };
339
340 static struct ast_translator lintolpc10 =
341         { "lintolpc10", 
342            AST_FORMAT_SLINEAR, AST_FORMAT_LPC10,
343            lpc10_enc_new,
344            lintolpc10_framein,
345            lintolpc10_frameout,
346            lpc10_destroy,
347            lintolpc10_sample
348            };
349
350 static void parse_config(void)
351 {
352         struct ast_config *cfg;
353         struct ast_variable *var;
354         if ((cfg = ast_config_load("codecs.conf"))) {
355                 if ((var = ast_variable_browse(cfg, "plc"))) {
356                         while (var) {
357                                if (!strcasecmp(var->name, "genericplc")) {
358                                        useplc = ast_true(var->value) ? 1 : 0;
359                                        if (option_verbose > 2)
360                                                ast_verbose(VERBOSE_PREFIX_3 "codec_lpc10: %susing generic PLC\n", useplc ? "" : "not ");
361                                }
362                                var = var->next;
363                         }
364                 }
365                 ast_config_destroy(cfg);
366         }
367 }
368
369 int reload(void)
370 {
371         parse_config();
372         return 0;
373 }
374
375
376 int unload_module(void)
377 {
378         int res;
379         ast_mutex_lock(&localuser_lock);
380         res = ast_unregister_translator(&lintolpc10);
381         if (!res)
382                 res = ast_unregister_translator(&lpc10tolin);
383         if (localusecnt)
384                 res = -1;
385         ast_mutex_unlock(&localuser_lock);
386         return res;
387 }
388
389 int load_module(void)
390 {
391         int res;
392         parse_config();
393         res=ast_register_translator(&lpc10tolin);
394         if (!res) 
395                 res=ast_register_translator(&lintolpc10);
396         else
397                 ast_unregister_translator(&lpc10tolin);
398         return res;
399 }
400
401 char *description(void)
402 {
403         return tdesc;
404 }
405
406 int usecount(void)
407 {
408         int res;
409         STANDARD_USECOUNT(res);
410         return res;
411 }
412
413 char *key()
414 {
415         return ASTERISK_GPL_KEY;
416 }