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