Bring in the new loader code as described in mantis #4377
[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 #define TYPE_HIGH        0x0
31 #define TYPE_LOW         0x1
32 #define TYPE_SILENCE     0x2
33 #define TYPE_DONTSEND    0x3
34 #define TYPE_MASK        0x3
35
36 #include <sys/types.h>
37 #include <fcntl.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <netinet/in.h>
41 #include <string.h>
42 #include <stdio.h>
43
44 #include "asterisk.h"
45
46 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
47
48 #include "asterisk/lock.h"
49 #include "asterisk/translate.h"
50 #include "asterisk/module.h"
51 #include "asterisk/logger.h"
52 #include "asterisk/channel.h"
53 #include "asterisk/utils.h"
54
55 #ifdef ANNEX_B
56 #include "g723.1b/typedef2.h"
57 #include "g723.1b/cst2.h"
58 #include "g723.1b/coder2.h"
59 #include "g723.1b/decod2.h"
60 #include "g723.1b/deccng2.h"
61 #include "g723.1b/codcng2.h"
62 #include "g723.1b/vad2.h"
63 #else
64 #include "g723.1/typedef.h"
65 #include "g723.1/cst_lbc.h"
66 #include "g723.1/coder.h"
67 #include "g723.1/decod.h"
68 #include "g723.1/dec_cng.h"
69 #include "g723.1/cod_cng.h"
70 #include "g723.1/vad.h"
71 #endif
72
73 /* Sample frame data */
74 #include "slin_g723_ex.h"
75 #include "g723_slin_ex.h"
76
77 AST_MUTEX_DEFINE_STATIC(localuser_lock);
78 static int localusecnt=0;
79
80 #ifdef ANNEX_B
81 static char *tdesc = "Annex B (floating point) G.723.1/PCM16 Codec Translator";
82 #else
83 static char *tdesc = "Annex A (fixed point) G.723.1/PCM16 Codec Translator";
84 #endif
85
86 /* Globals */
87 Flag UsePf = True;
88 Flag UseHp = True;
89 Flag UseVx = True;
90
91 enum Crate WrkRate = Rate63;
92
93 struct g723_encoder_pvt {
94         struct cod_state cod;
95         struct ast_frame f;
96         /* Space to build offset */
97         char offset[AST_FRIENDLY_OFFSET];
98         /* Buffer for our outgoing frame */
99         char outbuf[8000];
100         /* Enough to store a full second */
101         short buf[8000];
102         int tail;
103 };
104
105 struct g723_decoder_pvt {
106         struct dec_state dec;
107         struct ast_frame f;
108         /* Space to build offset */
109         char offset[AST_FRIENDLY_OFFSET];
110         /* Enough to store a full second */
111         short buf[8000];
112         int tail;
113 };
114
115 static struct ast_translator_pvt *g723tolin_new(void)
116 {
117         struct g723_decoder_pvt *tmp;   
118         if ((tmp = ast_malloc(sizeof(*tmp)))) {
119                 Init_Decod(&tmp->dec);
120             Init_Dec_Cng(&tmp->dec);
121                 tmp->tail = 0;
122                 localusecnt++;
123                 ast_update_use_count();
124         }
125         return (struct ast_translator_pvt *)tmp;
126 }
127
128 static struct ast_frame *lintog723_sample(void)
129 {
130         static struct ast_frame f;
131         f.frametype = AST_FRAME_VOICE;
132         f.subclass = AST_FORMAT_SLINEAR;
133         f.datalen = sizeof(slin_g723_ex);
134         /* Assume 8000 Hz */
135         f.samples = sizeof(slin_g723_ex)/2;
136         f.mallocd = 0;
137         f.offset = 0;
138         f.src = __PRETTY_FUNCTION__;
139         f.data = slin_g723_ex;
140         return &f;
141 }
142
143 static struct ast_frame *g723tolin_sample(void)
144 {
145         static struct ast_frame f;
146         f.frametype = AST_FRAME_VOICE;
147         f.subclass = AST_FORMAT_G723_1;
148         f.datalen = sizeof(g723_slin_ex);
149         /* All frames are 30 ms long */
150         f.samples = 240;
151         f.mallocd = 0;
152         f.offset = 0;
153         f.src = __PRETTY_FUNCTION__;
154         f.data = g723_slin_ex;
155         return &f;
156 }
157
158 static struct ast_translator_pvt *lintog723_new(void)
159 {
160         struct g723_encoder_pvt *tmp;   
161         if ((tmp = ast_malloc(sizeof(*tmp)))) {
162                 Init_Coder(&tmp->cod);
163             /* Init Comfort Noise Functions */
164                  if( UseVx ) {
165                         Init_Vad(&tmp->cod);
166                 Init_Cod_Cng(&tmp->cod);
167          }
168                 localusecnt++;
169                 ast_update_use_count();
170                 tmp->tail = 0;
171         }
172         return (struct ast_translator_pvt *)tmp;
173 }
174
175 static struct ast_frame *g723tolin_frameout(struct ast_translator_pvt *pvt)
176 {
177         struct g723_decoder_pvt *tmp = (struct g723_decoder_pvt *)pvt;
178         if (!tmp->tail)
179                 return NULL;
180         /* Signed linear is no particular frame size, so just send whatever
181            we have in the buffer in one lump sum */
182         tmp->f.frametype = AST_FRAME_VOICE;
183         tmp->f.subclass = AST_FORMAT_SLINEAR;
184         tmp->f.datalen = tmp->tail * 2;
185         /* Assume 8000 Hz */
186         tmp->f.samples = tmp->tail;
187         tmp->f.mallocd = 0;
188         tmp->f.offset = AST_FRIENDLY_OFFSET;
189         tmp->f.src = __PRETTY_FUNCTION__;
190         tmp->f.data = tmp->buf;
191         /* Reset tail pointer */
192         tmp->tail = 0;
193
194 #if 0
195         /* Save the frames */
196         { 
197                 static int fd2 = -1;
198                 if (fd2 == -1) {
199                         fd2 = open("g723.example", O_WRONLY | O_CREAT | O_TRUNC, 0644);
200                 }
201                 write(fd2, tmp->f.data, tmp->f.datalen);
202         }               
203 #endif
204         return &tmp->f; 
205 }
206
207 static int g723_len(unsigned char buf)
208 {
209         switch(buf & TYPE_MASK) {
210         case TYPE_DONTSEND:
211                 return 0;
212                 break;
213         case TYPE_SILENCE:
214                 return 4;
215                 break;
216         case TYPE_HIGH:
217                 return 24;
218                 break;
219         case TYPE_LOW:
220                 return 20;
221                 break;
222         default:
223                 ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", buf & TYPE_MASK);
224         }
225         return -1;
226 }
227
228 static int g723tolin_framein(struct ast_translator_pvt *pvt, struct ast_frame *f)
229 {
230         struct g723_decoder_pvt *tmp = (struct g723_decoder_pvt *)pvt;
231         int len = 0;
232         int res;
233 #ifdef  ANNEX_B
234         FLOAT tmpdata[Frame];
235         int x;
236 #endif
237         while(len < f->datalen) {
238                 /* Assuming there's space left, decode into the current buffer at
239                    the tail location */
240                 res = g723_len(((unsigned char *)f->data + len)[0]);
241                 if (res < 0) {
242                         ast_log(LOG_WARNING, "Invalid data\n");
243                         return -1;
244                 }
245                 if (res + len > f->datalen) {
246                         ast_log(LOG_WARNING, "Measured length exceeds frame length\n");
247                         return -1;
248                 }
249                 if (tmp->tail + Frame < sizeof(tmp->buf)/2) {   
250 #ifdef ANNEX_B
251                         Decod(&tmp->dec, tmpdata, f->data + len, 0);
252                         for (x=0;x<Frame;x++)
253                                 (tmp->buf + tmp->tail)[x] = (short)(tmpdata[x]); 
254 #else
255                         Decod(&tmp->dec, tmp->buf + tmp->tail, f->data + len, 0);
256 #endif
257                         tmp->tail+=Frame;
258                 } else {
259                         ast_log(LOG_WARNING, "Out of buffer space\n");
260                         return -1;
261                 }
262                 len += res;
263         }
264         return 0;
265 }
266
267 static int lintog723_framein(struct ast_translator_pvt *pvt, struct ast_frame *f)
268 {
269         /* Just add the frames to our stream */
270         /* XXX We should look at how old the rest of our stream is, and if it
271            is too old, then we should overwrite it entirely, otherwise we can
272            get artifacts of earlier talk that do not belong */
273         struct g723_encoder_pvt *tmp = (struct g723_encoder_pvt *)pvt;
274         if (tmp->tail + f->datalen/2 < sizeof(tmp->buf) / 2) {
275                 memcpy(&tmp->buf[tmp->tail], f->data, f->datalen);
276                 tmp->tail += f->datalen/2;
277         } else {
278                 ast_log(LOG_WARNING, "Out of buffer space\n");
279                 return -1;
280         }
281         return 0;
282 }
283
284 static struct ast_frame *lintog723_frameout(struct ast_translator_pvt *pvt)
285 {
286         struct g723_encoder_pvt *tmp = (struct g723_encoder_pvt *)pvt;
287 #ifdef ANNEX_B
288         int x;
289         FLOAT tmpdata[Frame];
290 #endif
291         int cnt=0;
292         /* We can't work on anything less than a frame in size */
293         if (tmp->tail < Frame)
294                 return NULL;
295         tmp->f.frametype = AST_FRAME_VOICE;
296         tmp->f.subclass = AST_FORMAT_G723_1;
297         tmp->f.offset = AST_FRIENDLY_OFFSET;
298         tmp->f.src = __PRETTY_FUNCTION__;
299         tmp->f.samples = 0;
300         tmp->f.mallocd = 0;
301         while(tmp->tail >= Frame) {
302                 /* Encode a frame of data */
303                 if (cnt + 24 >= sizeof(tmp->outbuf)) {
304                         ast_log(LOG_WARNING, "Out of buffer space\n");
305                         return NULL;
306                 }
307 #ifdef ANNEX_B
308                 for (x=0;x<Frame;x++)
309                         tmpdata[x] = tmp->buf[x];
310                 Coder(&tmp->cod, tmpdata, tmp->outbuf + cnt);
311 #else
312                 Coder(&tmp->cod, tmp->buf, tmp->outbuf + cnt);
313 #endif
314                 /* Assume 8000 Hz */
315                 tmp->f.samples += 240;
316                 cnt += g723_len(tmp->outbuf[cnt]);
317                 tmp->tail -= Frame;
318                 /* Move the data at the end of the buffer to the front */
319                 if (tmp->tail)
320                         memmove(tmp->buf, tmp->buf + Frame, tmp->tail * 2);
321         }
322         tmp->f.datalen = cnt;
323         tmp->f.data = tmp->outbuf;
324 #if 0
325         /* Save to a g723 sample output file... */
326         { 
327                 static int fd = -1;
328                 int delay = htonl(30);
329                 short size;
330                 if (fd < 0)
331                         fd = open("trans.g723", O_WRONLY | O_CREAT | O_TRUNC, 0644);
332                 if (fd < 0)
333                         ast_log(LOG_WARNING, "Unable to create demo\n");
334                 write(fd, &delay, 4);
335                 size = htons(tmp->f.datalen);
336                 write(fd, &size, 2);
337                 write(fd, tmp->f.data, tmp->f.datalen);
338         }
339 #endif
340         return &tmp->f; 
341 }
342
343 static void g723_destroy(struct ast_translator_pvt *pvt)
344 {
345         free(pvt);
346         localusecnt--;
347         ast_update_use_count();
348 }
349
350 static struct ast_translator g723tolin =
351 #ifdef ANNEX_B
352         { "g723tolinb", 
353 #else
354         { "g723tolin", 
355 #endif
356            AST_FORMAT_G723_1, AST_FORMAT_SLINEAR,
357            g723tolin_new,
358            g723tolin_framein,
359            g723tolin_frameout,
360            g723_destroy,
361            g723tolin_sample
362            };
363
364 static struct ast_translator lintog723 =
365 #ifdef ANNEX_B
366         { "lintog723b", 
367 #else
368         { "lintog723", 
369 #endif
370            AST_FORMAT_SLINEAR, AST_FORMAT_G723_1,
371            lintog723_new,
372            lintog723_framein,
373            lintog723_frameout,
374            g723_destroy,
375            lintog723_sample
376            };
377
378 int unload_module(void)
379 {
380         int res;
381         ast_mutex_lock(&localuser_lock);
382         res = ast_unregister_translator(&lintog723);
383         if (!res)
384                 res = ast_unregister_translator(&g723tolin);
385         if (localusecnt)
386                 res = -1;
387         ast_mutex_unlock(&localuser_lock);
388         return res;
389 }
390
391 int load_module(void)
392 {
393         int res;
394         res=ast_register_translator(&g723tolin);
395         if (!res) 
396                 res=ast_register_translator(&lintog723);
397         else
398                 ast_unregister_translator(&g723tolin);
399         return res;
400 }
401
402 char *description(void)
403 {
404         return tdesc;
405 }
406
407 int usecount(void)
408 {
409         int res;
410         OLD_STANDARD_USECOUNT(res);
411         return res;
412 }
413
414 char *key(void)
415 {
416         return ASTERISK_GPL_KEY;
417 }