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