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