add support for Zaptel transcoders
[asterisk/asterisk.git] / codecs / codec_g723_1.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * The G.723.1 code is not included in the Asterisk distribution because
5  * it is covered with patents, and in spite of statements to the contrary,
6  * the "technology" is extremely expensive to license.
7  * 
8  * Copyright (C) 1999 - 2005, Digium, Inc.
9  *
10  * Mark Spencer <markster@digium.com>
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 G.723.1
26  *
27  * \ingroup codecs
28  */
29
30 /*** MODULEINFO
31         <defaultenabled>no</defaultenabled>
32  ***/
33
34 #include "asterisk.h"
35
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
37
38 #include <sys/types.h>
39 #include <fcntl.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <netinet/in.h>
43 #include <string.h>
44 #include <stdio.h>
45
46 #include "asterisk/lock.h"
47 #include "asterisk/translate.h"
48 #include "asterisk/module.h"
49 #include "asterisk/logger.h"
50 #include "asterisk/channel.h"
51 #include "asterisk/utils.h"
52
53 #ifdef ANNEX_B
54 #include "g723.1b/typedef2.h"
55 #include "g723.1b/cst2.h"
56 #include "g723.1b/coder2.h"
57 #include "g723.1b/decod2.h"
58 #include "g723.1b/deccng2.h"
59 #include "g723.1b/codcng2.h"
60 #include "g723.1b/vad2.h"
61 #else
62 #include "g723.1/typedef.h"
63 #include "g723.1/cst_lbc.h"
64 #include "g723.1/coder.h"
65 #include "g723.1/decod.h"
66 #include "g723.1/dec_cng.h"
67 #include "g723.1/cod_cng.h"
68 #include "g723.1/vad.h"
69 #endif
70
71 /* Sample frame data */
72 #include "slin_g723_ex.h"
73 #include "g723_slin_ex.h"
74
75 #define TYPE_HIGH        0x0
76 #define TYPE_LOW         0x1
77 #define TYPE_SILENCE     0x2
78 #define TYPE_DONTSEND    0x3
79 #define TYPE_MASK        0x3
80
81 /* g723_1 has 240 samples per buffer.
82  * We want a buffer which is a multiple...
83  */
84 #define G723_SAMPLES    240
85 #define BUFFER_SAMPLES  8160    /* 240 * 34 */
86
87 /* Globals */
88 Flag UsePf = True;
89 Flag UseHp = True;
90 Flag UseVx = True;
91
92 enum Crate WrkRate = Rate63;
93
94 struct g723_encoder_pvt {
95         struct cod_state cod;
96         int16_t buf[BUFFER_SAMPLES];    /* input buffer */
97 };
98
99 struct g723_decoder_pvt {
100         struct dec_state dec;
101 };
102
103 static struct ast_trans_pvt *g723tolin_new(struct ast *pvt)
104 {
105         struct g723_decoder_pvt *tmp = pvt;
106
107         Init_Decod(&tmp->dec);
108         Init_Dec_Cng(&tmp->dec);
109         return tmp;
110 }
111
112 static struct ast_frame *lintog723_sample(void)
113 {
114         static struct ast_frame f;
115         f.frametype = AST_FRAME_VOICE;
116         f.subclass = AST_FORMAT_SLINEAR;
117         f.datalen = sizeof(slin_g723_ex);
118         f.samples = sizeof(slin_g723_ex)/2;
119         f.mallocd = 0;
120         f.offset = 0;
121         f.src = __PRETTY_FUNCTION__;
122         f.data = slin_g723_ex;
123         return &f;
124 }
125
126 static struct ast_frame *g723tolin_sample(void)
127 {
128         static struct ast_frame f;
129         f.frametype = AST_FRAME_VOICE;
130         f.subclass = AST_FORMAT_G723_1;
131         f.datalen = sizeof(g723_slin_ex);
132         /* All frames are 30 ms long */
133         f.samples = 240;
134         f.mallocd = 0;
135         f.offset = 0;
136         f.src = __PRETTY_FUNCTION__;
137         f.data = g723_slin_ex;
138         return &f;
139 }
140
141 static void *lintog723_new(void *pvt)
142 {
143         struct g723_encoder_pvt *tmp = pvt;
144         Init_Coder(&tmp->cod);
145         /* Init Comfort Noise Functions */
146         if( UseVx ) {
147                 Init_Vad(&tmp->cod);
148                 Init_Cod_Cng(&tmp->cod);
149         }
150         return tmp;
151 }
152
153 static int g723_len(unsigned char buf)
154 {
155         switch(buf & TYPE_MASK) {
156         case TYPE_DONTSEND:
157                 return 0;
158                 break;
159         case TYPE_SILENCE:
160                 return 4;
161                 break;
162         case TYPE_HIGH:
163                 return 24;
164                 break;
165         case TYPE_LOW:
166                 return 20;
167                 break;
168         default:
169                 ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", buf & TYPE_MASK);
170         }
171         return -1;
172 }
173
174 static int g723tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
175 {
176         struct g723_decoder_pvt *tmp = pvt->pvt;
177         int len = 0;
178         int res;
179         int16_t *dst = pvt->outbuf;
180 #ifdef  ANNEX_B
181         FLOAT tmpdata[Frame];
182         int x;
183 #endif
184         unsigned char *src = f->data;
185
186         while(len < f->datalen) {
187                 /* Assuming there's space left, decode into the current buffer at
188                    the tail location */
189                 res = g723_len(src[len]);
190                 if (res < 0) {
191                         ast_log(LOG_WARNING, "Invalid data\n");
192                         return -1;
193                 }
194                 if (res + len > f->datalen) {
195                         ast_log(LOG_WARNING, "Measured length exceeds frame length\n");
196                         return -1;
197                 }
198                 if (pvt->samples + Frame > BUFFER_SAMPLES) {    
199                         ast_log(LOG_WARNING, "Out of buffer space\n");
200                         return -1;
201                 }
202 #ifdef ANNEX_B
203                 Decod(&tmp->dec, tmpdata, f->data + len, 0);
204                 for (x=0;x<Frame;x++)
205                         dst[pvt->samples + x] = (int16_t)(tmpdata[x]); 
206 #else
207                 Decod(&tmp->dec, dst + pvt->samples, f->data + len, 0);
208 #endif
209                 pvt->samples += Frame;
210                 pvt->datalen += 2*Frame; /* 2 bytes/sample */
211                 len += res;
212         }
213         return 0;
214 }
215
216 static int lintog723_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
217 {
218         /* Just add the frames to our stream */
219         /* XXX We should look at how old the rest of our stream is, and if it
220            is too old, then we should overwrite it entirely, otherwise we can
221            get artifacts of earlier talk that do not belong */
222         struct g723_encoder_pvt *tmp = pvt->pvt;
223
224         if (tmp->samples + f->samples > BUFFER_SAMPLES) {
225                 ast_log(LOG_WARNING, "Out of buffer space\n");
226                 return -1;
227         }
228         memcpy(&tmp->buf[pvt->samples], f->data, f->datalen);
229         pvt->samples += f->samples;
230         return 0;
231 }
232
233 static struct ast_frame *lintog723_frameout(void *pvt)
234 {
235         struct g723_encoder_pvt *tmp = (struct g723_encoder_pvt *)pvt;
236         int samples = 0;        /* how many samples in buffer */
237 #ifdef ANNEX_B
238         int x;
239         FLOAT tmpdata[Frame];
240 #endif
241         int cnt = 0;    /* how many bytes so far */
242
243         /* We can't work on anything less than a frame in size */
244         if (pvt->samples < Frame)
245                 return NULL;
246         while (pvt->samples >= Frame) {
247                 /* Encode a frame of data */
248                 /* at most 24 bytes/frame... */
249                 if (cnt + 24 > pvt->buf_size) {
250                         ast_log(LOG_WARNING, "Out of buffer space\n");
251                         return NULL;
252                 }
253 #ifdef ANNEX_B
254                 for ( x = 0; x < Frame ; x++)
255                         tmpdata[x] = tmp->buf[x];
256                 Coder(&tmp->cod, tmpdata, pvt->outbuf + cnt);
257 #else
258                 Coder(&tmp->cod, tmp->buf, pvt->outbuf + cnt);
259 #endif
260                 /* Assume 8000 Hz */
261                 samples += G723_SAMPLES;
262                 cnt += g723_len(tmp->outbuf[cnt]);
263                 pvt->samples -= Frame;
264                 /* Move the data at the end of the buffer to the front */
265                 /* XXX inefficient... */
266                 if (pvt->samples)
267                         memmove(tmp->buf, tmp->buf + Frame, pvt->samples * 2);
268         }
269         return ast_trans_frameout(pvt, cnt, samples);
270 }
271
272 static struct ast_translator g723tolin = {
273         .name =
274 #ifdef ANNEX_B
275         "g723btolin", 
276 #else
277         "g723tolin", 
278 #endif
279         .srcfmt = AST_FORMAT_G723_1,
280         .dstfmt =  AST_FORMAT_SLINEAR,
281         .newpvt = g723tolin_new,
282         .framein = g723tolin_framein,
283         .sample = g723tolin_sample,
284         .desc_size = sizeof(struct ...),
285 };
286
287 static struct ast_translator lintog723 = {
288         .name =
289 #ifdef ANNEX_B
290         "lintog723b", 
291 #else
292         "lintog723", 
293 #endif
294         .srcfmt = AST_FORMAT_SLINEAR,
295         .dstfmt =  AST_FORMAT_G723_1,
296         .new = lintog723_new,
297         .framein = lintog723_framein,
298         .frameout = lintog723_frameout,
299         .destroy = g723_destroy,
300         .sample = lintog723_sample,
301         .desc_size = sizeof(struct ...),
302 };
303
304 /*! \brief standard module glue */
305
306 static int unload_module(void *mod)
307 {
308         int res;
309         res = ast_unregister_translator(&lintog723);
310         res |= ast_unregister_translator(&g723tolin);
311         return res;
312 }
313
314 static int load_module(void *mod)
315 {
316         int res;
317         res=ast_register_translator(&g723tolin, mod);
318         if (!res) 
319                 res=ast_register_translator(&lintog723, mod);
320         else
321                 ast_unregister_translator(&g723tolin);
322         return res;
323 }
324
325 static const char *description(void)
326 {
327 #ifdef ANNEX_B
328         return "Annex B (floating point) G.723.1/PCM16 Codec Translator";
329 #else
330         return "Annex A (fixed point) G.723.1/PCM16 Codec Translator";
331 #endif
332
333 }
334
335 static const char *key(void)
336 {
337         return ASTERISK_GPL_KEY;
338 }
339
340 STD_MOD(MOD_1, reload, NULL, NULL);