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