80ec375f8216f519449cd2547b439309faf8ee78
[asterisk/asterisk.git] / codecs / codec_adpcm.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Based on frompcm.c and topcm.c from the Emiliano MIPL browser/
5  * interpreter.  See http://www.bsdtelephony.com.mx
6  *
7  * Copyright (c) 2001 - 2005 Digium, Inc.
8  * All rights reserved.
9  *
10  * Karl Sackett <krs@linux-support.net>, 2001-03-21
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 codec_adpcm.c - translate between signed linear and Dialogic ADPCM
26  * 
27  * \ingroup codecs
28  */
29
30
31 #include <fcntl.h>
32 #include <netinet/in.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37
38 #include "asterisk.h"
39
40 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
41
42 #include "asterisk/lock.h"
43 #include "asterisk/logger.h"
44 #include "asterisk/linkedlists.h"
45 #include "asterisk/module.h"
46 #include "asterisk/config.h"
47 #include "asterisk/options.h"
48 #include "asterisk/translate.h"
49 #include "asterisk/channel.h"
50 #include "asterisk/utils.h"
51
52 /* define NOT_BLI to use a faster but not bit-level identical version */
53 /* #define NOT_BLI */
54
55 #define BUFFER_SAMPLES   8096   /* size for the translation buffers */
56
57 /* Sample frame data */
58
59 #include "slin_adpcm_ex.h"
60 #include "adpcm_slin_ex.h"
61
62 /*
63  * Step size index shift table 
64  */
65
66 static int indsft[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
67
68 /*
69  * Step size table, where stpsz[i]=floor[16*(11/10)^i]
70  */
71
72 static int stpsz[49] = {
73   16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73,
74   80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279,
75   307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
76   1060, 1166, 1282, 1411, 1552
77 };
78
79 /*
80  * Decoder/Encoder state
81  *   States for both encoder and decoder are synchronized
82  */
83 struct adpcm_state {
84         int ssindex;
85         int signal;
86         int zero_count;
87         int next_flag;
88 };
89
90 /*
91  * Decode(encoded)
92  *  Decodes the encoded nibble from the adpcm file.
93  *
94  * Results:
95  *  Returns the encoded difference.
96  *
97  * Side effects:
98  *  Sets the index to the step size table for the next encode.
99  */
100
101 static inline short decode(int encoded, struct adpcm_state *state)
102 {
103         int diff;
104         int step;
105         int sign;
106
107         step = stpsz[state->ssindex];
108
109         sign = encoded & 0x08;
110         encoded &= 0x07;
111 #ifdef NOT_BLI
112         diff = (((encoded << 1) + 1) * step) >> 3;
113 #else /* BLI code */
114         diff = step >> 3;
115         if (encoded & 4)
116                 diff += step;
117         if (encoded & 2)
118                 diff += step >> 1;
119         if (encoded & 1)
120                 diff += step >> 2;
121         if ((encoded >> 1) & step & 0x1)
122                 diff++;
123 #endif
124         if (sign)
125                 diff = -diff;
126
127         if (state->next_flag & 0x1)
128                 state->signal -= 8;
129         else if (state->next_flag & 0x2)
130                 state->signal += 8;
131
132         state->signal += diff;
133
134         if (state->signal > 2047)
135                 state->signal = 2047;
136         else if (state->signal < -2047)
137                 state->signal = -2047;
138
139         state->next_flag = 0;
140
141 #ifdef AUTO_RETURN
142         if (encoded)
143                 state->zero_count = 0;
144         else if (++(state->zero_count) == 24) {
145                 state->zero_count = 0;
146                 if (state->signal > 0)
147                         state->next_flag = 0x1;
148                 else if (state->signal < 0)
149                         state->next_flag = 0x2;
150         }
151 #endif
152
153         state->ssindex += indsft[encoded];
154         if (state->ssindex < 0)
155                 state->ssindex = 0;
156         else if (state->ssindex > 48)
157                 state->ssindex = 48;
158
159         return state->signal << 4;
160 }
161
162 /*
163  * Adpcm
164  *  Takes a signed linear signal and encodes it as ADPCM
165  *  For more information see http://support.dialogic.com/appnotes/adpcm.pdf
166  *
167  * Results:
168  *  Foo.
169  *
170  * Side effects:
171  *  signal gets updated with each pass.
172  */
173
174 static inline int adpcm(short csig, struct adpcm_state *state)
175 {
176         int diff;
177         int step;
178         int encoded;
179
180         /* 
181          * Clip csig if too large or too small
182          */
183         csig >>= 4;
184
185         step = stpsz[state->ssindex];
186         diff = csig - state->signal;
187
188 #ifdef NOT_BLI
189         if (diff < 0) {
190                 encoded = (-diff << 2) / step;
191                 if (encoded > 7)
192                         encoded = 7;
193                 encoded |= 0x08;
194         } else {
195                 encoded = (diff << 2) / step;
196                 if (encoded > 7)
197                         encoded = 7;
198         }
199 #else /* BLI code */
200         if (diff < 0) {
201                 encoded = 8;
202                 diff = -diff;
203         } else
204                 encoded = 0;
205         if (diff >= step) {
206                 encoded |= 4;
207                 diff -= step;
208         }
209         step >>= 1;
210         if (diff >= step) {
211                 encoded |= 2;
212                 diff -= step;
213         }
214         step >>= 1;
215         if (diff >= step)
216                 encoded |= 1;
217 #endif /* NOT_BLI */
218
219         /* feedback to state */
220         decode(encoded, state);
221         
222         return encoded;
223 }
224
225 /*----------------- Asterisk-codec glue ------------*/
226
227 /*! \brief Workspace for translating signed linear signals to ADPCM. */
228 struct adpcm_encoder_pvt {
229         struct adpcm_state state;
230         int16_t inbuf[BUFFER_SAMPLES];  /* Unencoded signed linear values */
231 };
232
233 /*! \brief Workspace for translating ADPCM signals to signed linear. */
234 struct adpcm_decoder_pvt {
235         struct adpcm_state state;
236 };
237
238 /*! \brief decode 4-bit adpcm frame data and store in output buffer */
239 static int adpcmtolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
240 {
241         struct adpcm_decoder_pvt *tmp = pvt->pvt;
242         int x = f->datalen;
243         unsigned char *src = f->data;
244         int16_t *dst = (int16_t *)pvt->outbuf + pvt->samples;
245
246         while (x--) {
247                 *dst++ = decode((*src >> 4) & 0xf, &tmp->state);
248                 *dst++ = decode(*src++ & 0x0f, &tmp->state);
249         }
250         pvt->samples += f->samples;
251         pvt->datalen += 2*f->samples;
252         return 0;
253 }
254
255 /*! \brief fill input buffer with 16-bit signed linear PCM values. */
256 static int lintoadpcm_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
257 {
258         struct adpcm_encoder_pvt *tmp = pvt->pvt;
259
260         memcpy(&tmp->inbuf[pvt->samples], f->data, f->datalen);
261         pvt->samples += f->samples;
262         return 0;
263 }
264
265 /*! \brief convert inbuf and store into frame */
266 static struct ast_frame *lintoadpcm_frameout(struct ast_trans_pvt *pvt)
267 {
268         struct adpcm_encoder_pvt *tmp = pvt->pvt;
269         struct ast_frame *f;
270         int i;
271         int samples = pvt->samples;     /* save original number */
272   
273         if (samples < 2)
274                 return NULL;
275
276         pvt->samples &= ~1; /* atomic size is 2 samples */
277
278         for (i = 0; i < pvt->samples; i += 2) {
279                 pvt->outbuf[i/2] =
280                         (adpcm(tmp->inbuf[i  ], &tmp->state) << 4) |
281                         (adpcm(tmp->inbuf[i+1], &tmp->state)     );
282         };
283
284         f = ast_trans_frameout(pvt, pvt->samples/2, 0);
285
286         /*
287          * If there is a left over sample, move it to the beginning
288          * of the input buffer.
289          */
290
291         if (samples & 1) {      /* move the leftover sample at beginning */
292                 tmp->inbuf[0] = tmp->inbuf[samples - 1];
293                 pvt->samples = 1;
294         }
295         return f;
296 }
297
298
299 /*! \brief AdpcmToLin_Sample */
300 static struct ast_frame *adpcmtolin_sample(void)
301 {
302         static struct ast_frame f;
303         f.frametype = AST_FRAME_VOICE;
304         f.subclass = AST_FORMAT_ADPCM;
305         f.datalen = sizeof(adpcm_slin_ex);
306         f.samples = sizeof(adpcm_slin_ex) * 2;
307         f.mallocd = 0;
308         f.offset = 0;
309         f.src = __PRETTY_FUNCTION__;
310         f.data = adpcm_slin_ex;
311         return &f;
312 }
313
314 /*! \brief LinToAdpcm_Sample */
315 static struct ast_frame *lintoadpcm_sample(void)
316 {
317         static struct ast_frame f;
318         f.frametype = AST_FRAME_VOICE;
319         f.subclass = AST_FORMAT_SLINEAR;
320         f.datalen = sizeof(slin_adpcm_ex);
321         /* Assume 8000 Hz */
322         f.samples = sizeof(slin_adpcm_ex) / 2;
323         f.mallocd = 0;
324         f.offset = 0;
325         f.src = __PRETTY_FUNCTION__;
326         f.data = slin_adpcm_ex;
327         return &f;
328 }
329
330 static struct ast_translator adpcmtolin = {
331         .name = "adpcmtolin",
332         .srcfmt = AST_FORMAT_ADPCM,
333         .dstfmt = AST_FORMAT_SLINEAR,
334         .framein = adpcmtolin_framein,
335         .sample = adpcmtolin_sample,
336         .desc_size = sizeof(struct adpcm_decoder_pvt),
337         .buffer_samples = BUFFER_SAMPLES,
338         .buf_size = BUFFER_SAMPLES * 2,
339         .plc_samples = 160,
340 };
341
342 static struct ast_translator lintoadpcm = {
343         .name = "lintoadpcm",
344         .srcfmt = AST_FORMAT_SLINEAR,
345         .dstfmt = AST_FORMAT_ADPCM,
346         .framein = lintoadpcm_framein,
347         .frameout = lintoadpcm_frameout,
348         .sample = lintoadpcm_sample,
349         .desc_size = sizeof (struct adpcm_encoder_pvt),
350         .buffer_samples = BUFFER_SAMPLES,
351         .buf_size = BUFFER_SAMPLES/ 2,  /* 2 samples per byte */
352 };
353
354 static void parse_config(void)
355 {
356         struct ast_config *cfg = ast_config_load("codecs.conf");
357         struct ast_variable *var;
358         if (cfg == NULL)
359                 return;
360         for (var = ast_variable_browse(cfg, "plc"); var ; var = var->next) {
361                 if (!strcasecmp(var->name, "genericplc")) {
362                         adpcmtolin.useplc = ast_true(var->value) ? 1 : 0;
363                         if (option_verbose > 2)
364                                 ast_verbose(VERBOSE_PREFIX_3 "codec_adpcm: %susing generic PLC\n", adpcmtolin.useplc ? "" : "not ");
365                 }
366         }
367         ast_config_destroy(cfg);
368 }
369
370 /*! \brief standard module glue */
371 static int reload(void *mod)
372 {
373         parse_config();
374         return 0;
375 }
376
377 static int unload_module(void *mod)
378 {
379         int res;
380         res = ast_unregister_translator(&lintoadpcm);
381         res |= ast_unregister_translator(&adpcmtolin);
382         return res;
383 }
384
385 static int load_module(void *mod)
386 {
387         int res;
388         parse_config();
389         res = ast_register_translator(&adpcmtolin, mod);
390         if (!res)
391                 res = ast_register_translator(&lintoadpcm, mod);
392         else
393                 ast_unregister_translator(&adpcmtolin);
394         return res;
395 }
396
397 static const char *description(void)
398 {
399         return "Adaptive Differential PCM Coder/Decoder";
400 }
401
402 static const char *key(void)
403 {
404         return ASTERISK_GPL_KEY;
405 }
406
407 STD_MOD(MOD_1, reload, NULL, NULL);