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