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