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