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