dfcdc798827dc22282416f3e486652c97320b840
[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 "asterisk.h"
31
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
33
34 #include "asterisk/translate.h"
35 #include "asterisk/config.h"
36 #include "asterisk/module.h"
37 #include "asterisk/utils.h"
38
39 #include "lpc10/lpc10.h"
40
41 /* Sample frame data */
42 #include "slin_lpc10_ex.h"
43 #include "lpc10_slin_ex.h"
44
45 /* We use a very strange format here...  I have no idea why...  The frames are 180
46    samples long, which isn't even an even number of milliseconds...  Not only that
47    but we hvae to waste two bits of each frame to keep them ending on a byte boundary
48    because the frames are 54 bits long */
49
50 #define LPC10_BYTES_IN_COMPRESSED_FRAME (LPC10_BITS_IN_COMPRESSED_FRAME + 7)/8
51
52 #define BUFFER_SAMPLES  8000
53
54 struct lpc10_coder_pvt {
55         union {
56                 struct lpc10_encoder_state *enc;
57                 struct lpc10_decoder_state *dec;
58         } lpc10;
59         /* Enough to store a full second */
60         short buf[BUFFER_SAMPLES];
61         int longer;
62 };
63
64 static int lpc10_enc_new(struct ast_trans_pvt *pvt)
65 {
66         struct lpc10_coder_pvt *tmp = pvt->pvt;
67
68         return (tmp->lpc10.enc = create_lpc10_encoder_state()) ? 0 : -1;
69 }
70
71 static int lpc10_dec_new(struct ast_trans_pvt *pvt)
72 {
73         struct lpc10_coder_pvt *tmp = pvt->pvt;
74
75         return (tmp->lpc10.dec = create_lpc10_decoder_state()) ? 0 : -1;
76 }
77
78 static struct ast_frame *lintolpc10_sample(void)
79 {
80         static struct ast_frame f;
81         f.frametype = AST_FRAME_VOICE;
82         f.subclass = AST_FORMAT_SLINEAR;
83         f.datalen = sizeof(slin_lpc10_ex);
84         /* Assume 8000 Hz */
85         f.samples = LPC10_SAMPLES_PER_FRAME;
86         f.mallocd = 0;
87         f.offset = 0;
88         f.src = __PRETTY_FUNCTION__;
89         f.data.ptr = slin_lpc10_ex;
90         return &f;
91 }
92
93 static struct ast_frame *lpc10tolin_sample(void)
94 {
95         static struct ast_frame f;
96         f.frametype = AST_FRAME_VOICE;
97         f.subclass = AST_FORMAT_LPC10;
98         f.datalen = sizeof(lpc10_slin_ex);
99         /* All frames are 22 ms long (maybe a little more -- why did he choose
100            LPC10_SAMPLES_PER_FRAME sample frames anyway?? */
101         f.samples = LPC10_SAMPLES_PER_FRAME;
102         f.mallocd = 0;
103         f.offset = 0;
104         f.src = __PRETTY_FUNCTION__;
105         f.data.ptr = lpc10_slin_ex;
106         return &f;
107 }
108
109 static void extract_bits(INT32 *bits, unsigned char *c)
110 {
111         int x;
112         for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
113                 if (*c & (0x80 >> (x & 7)))
114                         bits[x] = 1;
115                 else
116                         bits[x] = 0;
117                 if ((x & 7) == 7)
118                         c++;
119         }
120 }
121
122 /* XXX note lpc10_encode() produces one bit per word in bits[] */
123 static void build_bits(unsigned char *c, INT32 *bits)
124 {
125         unsigned char mask=0x80;
126         int x;
127         *c = 0;
128         for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
129                 if (bits[x])
130                         *c |= mask;
131                 mask = mask >> 1;
132                 if ((x % 8)==7) {
133                         c++;
134                         *c = 0;
135                         mask = 0x80;
136                 }
137         }
138 }
139
140 static int lpc10tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
141 {
142         struct lpc10_coder_pvt *tmp = pvt->pvt;
143         int16_t *dst = (int16_t *)pvt->outbuf;
144         int len = 0;
145
146         while (len + LPC10_BYTES_IN_COMPRESSED_FRAME <= f->datalen) {
147                 int x;
148                 float tmpbuf[LPC10_SAMPLES_PER_FRAME];
149                 INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; /* XXX see note */
150                 if (pvt->samples + LPC10_SAMPLES_PER_FRAME > BUFFER_SAMPLES) {
151                         ast_log(LOG_WARNING, "Out of buffer space\n");
152                         return -1;
153                 }
154                 extract_bits(bits, f->data.ptr + len);
155                 if (lpc10_decode(bits, tmpbuf, tmp->lpc10.dec)) {
156                         ast_log(LOG_WARNING, "Invalid lpc10 data\n");
157                         return -1;
158                 }
159                 for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
160                         /* Convert to a short between -1.0 and 1.0 */
161                         dst[pvt->samples + x] = (int16_t)(32768.0 * tmpbuf[x]);
162                 }
163
164                 pvt->samples += LPC10_SAMPLES_PER_FRAME;
165                 pvt->datalen += 2*LPC10_SAMPLES_PER_FRAME;
166                 len += LPC10_BYTES_IN_COMPRESSED_FRAME;
167         }
168         if (len != f->datalen) 
169                 printf("Decoded %d, expected %d\n", len, f->datalen);
170         return 0;
171 }
172
173 static int lintolpc10_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
174 {
175         struct lpc10_coder_pvt *tmp = pvt->pvt;
176
177         /* Just add the frames to our stream */
178         if (pvt->samples + f->samples > BUFFER_SAMPLES) {
179                 ast_log(LOG_WARNING, "Out of buffer space\n");
180                 return -1;
181         }
182         memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
183         pvt->samples += f->samples;
184         return 0;
185 }
186
187 static struct ast_frame *lintolpc10_frameout(struct ast_trans_pvt *pvt)
188 {
189         struct lpc10_coder_pvt *tmp = pvt->pvt;
190         int x;
191         int datalen = 0;        /* output frame */
192         int samples = 0;        /* output samples */
193         float tmpbuf[LPC10_SAMPLES_PER_FRAME];
194         INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME];     /* XXX what ??? */
195         /* We can't work on anything less than a frame in size */
196         if (pvt->samples < LPC10_SAMPLES_PER_FRAME)
197                 return NULL;
198         while (pvt->samples >=  LPC10_SAMPLES_PER_FRAME) {
199                 /* Encode a frame of data */
200                 for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++)
201                         tmpbuf[x] = (float)tmp->buf[x + samples] / 32768.0;
202                 lpc10_encode(tmpbuf, bits, tmp->lpc10.enc);
203                 build_bits((unsigned char *) pvt->outbuf + datalen, bits);
204                 datalen += LPC10_BYTES_IN_COMPRESSED_FRAME;
205                 samples += LPC10_SAMPLES_PER_FRAME;
206                 pvt->samples -= LPC10_SAMPLES_PER_FRAME;
207                 /* Use one of the two left over bits to record if this is a 22 or 23 ms frame...
208                    important for IAX use */
209                 tmp->longer = 1 - tmp->longer;
210         }
211         /* Move the data at the end of the buffer to the front */
212         if (pvt->samples)
213                 memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
214         return ast_trans_frameout(pvt, datalen, samples);
215 }
216
217
218 static void lpc10_destroy(struct ast_trans_pvt *arg)
219 {
220         struct lpc10_coder_pvt *pvt = arg->pvt;
221         /* Enc and DEC are both just allocated, so they can be freed */
222         ast_free(pvt->lpc10.enc);
223 }
224
225 static struct ast_translator lpc10tolin = {
226         .name = "lpc10tolin", 
227         .srcfmt = AST_FORMAT_LPC10,
228         .dstfmt = AST_FORMAT_SLINEAR,
229         .newpvt = lpc10_dec_new,
230         .framein = lpc10tolin_framein,
231         .destroy = lpc10_destroy,
232         .sample = lpc10tolin_sample,
233         .desc_size = sizeof(struct lpc10_coder_pvt),
234         .buffer_samples = BUFFER_SAMPLES,
235         .plc_samples = LPC10_SAMPLES_PER_FRAME,
236         .buf_size = BUFFER_SAMPLES * 2,
237 };
238
239 static struct ast_translator lintolpc10 = {
240         .name = "lintolpc10", 
241         .srcfmt = AST_FORMAT_SLINEAR,
242         .dstfmt = AST_FORMAT_LPC10,
243         .newpvt = lpc10_enc_new,
244         .framein = lintolpc10_framein,
245         .frameout = lintolpc10_frameout,
246         .destroy = lpc10_destroy,
247         .sample = lintolpc10_sample,
248         .desc_size = sizeof(struct lpc10_coder_pvt),
249         .buffer_samples = BUFFER_SAMPLES,
250         .buf_size = LPC10_BYTES_IN_COMPRESSED_FRAME * (1 + BUFFER_SAMPLES / LPC10_SAMPLES_PER_FRAME),
251 };
252
253 static int parse_config(int reload)
254 {
255         struct ast_variable *var;
256         struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
257         struct ast_config *cfg = ast_config_load("codecs.conf", config_flags);
258         if (cfg == NULL)
259                 return 0;
260         if (cfg == CONFIG_STATUS_FILEUNCHANGED)
261                 return 0;
262         for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
263                 if (!strcasecmp(var->name, "genericplc")) {
264                         lpc10tolin.useplc = ast_true(var->value) ? 1 : 0;
265                         ast_verb(3, "codec_lpc10: %susing generic PLC\n",
266                                         lpc10tolin.useplc ? "" : "not ");
267                 }
268         }
269         ast_config_destroy(cfg);
270         return 0;
271 }
272
273 static int reload(void)
274 {
275         if (parse_config(1))
276                 return AST_MODULE_LOAD_DECLINE;
277         return AST_MODULE_LOAD_SUCCESS;
278 }
279
280
281 static int unload_module(void)
282 {
283         int res;
284
285         res = ast_unregister_translator(&lintolpc10);
286         res |= ast_unregister_translator(&lpc10tolin);
287
288         return res;
289 }
290
291 static int load_module(void)
292 {
293         int res;
294
295         if (parse_config(0))
296                 return AST_MODULE_LOAD_DECLINE;
297         res = ast_register_translator(&lpc10tolin);
298         if (!res) 
299                 res = ast_register_translator(&lintolpc10);
300         else
301                 ast_unregister_translator(&lpc10tolin);
302         if (res)
303                 return AST_MODULE_LOAD_FAILURE;
304         return AST_MODULE_LOAD_SUCCESS;
305 }
306
307 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "LPC10 2.4kbps Coder/Decoder",
308                 .load = load_module,
309                 .unload = unload_module,
310                 .reload = reload,
311                );