00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #define TYPE_HIGH 0x0
00031 #define TYPE_LOW 0x1
00032 #define TYPE_SILENCE 0x2
00033 #define TYPE_DONTSEND 0x3
00034 #define TYPE_MASK 0x3
00035
00036 #include <sys/types.h>
00037 #include <fcntl.h>
00038 #include <stdlib.h>
00039 #include <unistd.h>
00040 #include <netinet/in.h>
00041 #include <string.h>
00042 #include <stdio.h>
00043
00044 #include "asterisk.h"
00045
00046 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00047
00048 #include "asterisk/lock.h"
00049 #include "asterisk/translate.h"
00050 #include "asterisk/module.h"
00051 #include "asterisk/logger.h"
00052 #include "asterisk/channel.h"
00053
00054 #ifdef ANNEX_B
00055 #include "g723.1b/typedef2.h"
00056 #include "g723.1b/cst2.h"
00057 #include "g723.1b/coder2.h"
00058 #include "g723.1b/decod2.h"
00059 #include "g723.1b/deccng2.h"
00060 #include "g723.1b/codcng2.h"
00061 #include "g723.1b/vad2.h"
00062 #else
00063 #include "g723.1/typedef.h"
00064 #include "g723.1/cst_lbc.h"
00065 #include "g723.1/coder.h"
00066 #include "g723.1/decod.h"
00067 #include "g723.1/dec_cng.h"
00068 #include "g723.1/cod_cng.h"
00069 #include "g723.1/vad.h"
00070 #endif
00071
00072
00073 #include "slin_g723_ex.h"
00074 #include "g723_slin_ex.h"
00075
00076 AST_MUTEX_DEFINE_STATIC(localuser_lock);
00077 static int localusecnt=0;
00078
00079 #ifdef ANNEX_B
00080 static char *tdesc = "Annex B (floating point) G.723.1/PCM16 Codec Translator";
00081 #else
00082 static char *tdesc = "Annex A (fixed point) G.723.1/PCM16 Codec Translator";
00083 #endif
00084
00085
00086 Flag UsePf = True;
00087 Flag UseHp = True;
00088 Flag UseVx = True;
00089
00090 enum Crate WrkRate = Rate63;
00091
00092 struct g723_encoder_pvt {
00093 struct cod_state cod;
00094 struct ast_frame f;
00095
00096 char offset[AST_FRIENDLY_OFFSET];
00097
00098 char outbuf[8000];
00099
00100 short buf[8000];
00101 int tail;
00102 };
00103
00104 struct g723_decoder_pvt {
00105 struct dec_state dec;
00106 struct ast_frame f;
00107
00108 char offset[AST_FRIENDLY_OFFSET];
00109
00110 short buf[8000];
00111 int tail;
00112 };
00113
00114 static struct ast_translator_pvt *g723tolin_new(void)
00115 {
00116 struct g723_decoder_pvt *tmp;
00117 tmp = malloc(sizeof(struct g723_decoder_pvt));
00118 if (tmp) {
00119 Init_Decod(&tmp->dec);
00120 Init_Dec_Cng(&tmp->dec);
00121 tmp->tail = 0;
00122 localusecnt++;
00123 ast_update_use_count();
00124 }
00125 return (struct ast_translator_pvt *)tmp;
00126 }
00127
00128 static struct ast_frame *lintog723_sample(void)
00129 {
00130 static struct ast_frame f;
00131 f.frametype = AST_FRAME_VOICE;
00132 f.subclass = AST_FORMAT_SLINEAR;
00133 f.datalen = sizeof(slin_g723_ex);
00134
00135 f.samples = sizeof(slin_g723_ex)/2;
00136 f.mallocd = 0;
00137 f.offset = 0;
00138 f.src = __PRETTY_FUNCTION__;
00139 f.data = slin_g723_ex;
00140 return &f;
00141 }
00142
00143 static struct ast_frame *g723tolin_sample(void)
00144 {
00145 static struct ast_frame f;
00146 f.frametype = AST_FRAME_VOICE;
00147 f.subclass = AST_FORMAT_G723_1;
00148 f.datalen = sizeof(g723_slin_ex);
00149
00150 f.samples = 240;
00151 f.mallocd = 0;
00152 f.offset = 0;
00153 f.src = __PRETTY_FUNCTION__;
00154 f.data = g723_slin_ex;
00155 return &f;
00156 }
00157
00158 static struct ast_translator_pvt *lintog723_new(void)
00159 {
00160 struct g723_encoder_pvt *tmp;
00161 tmp = malloc(sizeof(struct g723_encoder_pvt));
00162 if (tmp) {
00163 Init_Coder(&tmp->cod);
00164
00165 if( UseVx ) {
00166 Init_Vad(&tmp->cod);
00167 Init_Cod_Cng(&tmp->cod);
00168 }
00169 localusecnt++;
00170 ast_update_use_count();
00171 tmp->tail = 0;
00172 }
00173 return (struct ast_translator_pvt *)tmp;
00174 }
00175
00176 static struct ast_frame *g723tolin_frameout(struct ast_translator_pvt *pvt)
00177 {
00178 struct g723_decoder_pvt *tmp = (struct g723_decoder_pvt *)pvt;
00179 if (!tmp->tail)
00180 return NULL;
00181
00182
00183 tmp->f.frametype = AST_FRAME_VOICE;
00184 tmp->f.subclass = AST_FORMAT_SLINEAR;
00185 tmp->f.datalen = tmp->tail * 2;
00186
00187 tmp->f.samples = tmp->tail;
00188 tmp->f.mallocd = 0;
00189 tmp->f.offset = AST_FRIENDLY_OFFSET;
00190 tmp->f.src = __PRETTY_FUNCTION__;
00191 tmp->f.data = tmp->buf;
00192
00193 tmp->tail = 0;
00194
00195 #if 0
00196
00197 {
00198 static int fd2 = -1;
00199 if (fd2 == -1) {
00200 fd2 = open("g723.example", O_WRONLY | O_CREAT | O_TRUNC, 0644);
00201 }
00202 write(fd2, tmp->f.data, tmp->f.datalen);
00203 }
00204 #endif
00205 return &tmp->f;
00206 }
00207
00208 static int g723_len(unsigned char buf)
00209 {
00210 switch(buf & TYPE_MASK) {
00211 case TYPE_DONTSEND:
00212 return 0;
00213 break;
00214 case TYPE_SILENCE:
00215 return 4;
00216 break;
00217 case TYPE_HIGH:
00218 return 24;
00219 break;
00220 case TYPE_LOW:
00221 return 20;
00222 break;
00223 default:
00224 ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", buf & TYPE_MASK);
00225 }
00226 return -1;
00227 }
00228
00229 static int g723tolin_framein(struct ast_translator_pvt *pvt, struct ast_frame *f)
00230 {
00231 struct g723_decoder_pvt *tmp = (struct g723_decoder_pvt *)pvt;
00232 int len = 0;
00233 int res;
00234 #ifdef ANNEX_B
00235 FLOAT tmpdata[Frame];
00236 int x;
00237 #endif
00238 while(len < f->datalen) {
00239
00240
00241 res = g723_len(((unsigned char *)f->data + len)[0]);
00242 if (res < 0) {
00243 ast_log(LOG_WARNING, "Invalid data\n");
00244 return -1;
00245 }
00246 if (res + len > f->datalen) {
00247 ast_log(LOG_WARNING, "Measured length exceeds frame length\n");
00248 return -1;
00249 }
00250 if (tmp->tail + Frame < sizeof(tmp->buf)/2) {
00251 #ifdef ANNEX_B
00252 Decod(&tmp->dec, tmpdata, f->data + len, 0);
00253 for (x=0;x<Frame;x++)
00254 (tmp->buf + tmp->tail)[x] = (short)(tmpdata[x]);
00255 #else
00256 Decod(&tmp->dec, tmp->buf + tmp->tail, f->data + len, 0);
00257 #endif
00258 tmp->tail+=Frame;
00259 } else {
00260 ast_log(LOG_WARNING, "Out of buffer space\n");
00261 return -1;
00262 }
00263 len += res;
00264 }
00265 return 0;
00266 }
00267
00268 static int lintog723_framein(struct ast_translator_pvt *pvt, struct ast_frame *f)
00269 {
00270
00271
00272
00273
00274 struct g723_encoder_pvt *tmp = (struct g723_encoder_pvt *)pvt;
00275 if (tmp->tail + f->datalen/2 < sizeof(tmp->buf) / 2) {
00276 memcpy(&tmp->buf[tmp->tail], f->data, f->datalen);
00277 tmp->tail += f->datalen/2;
00278 } else {
00279 ast_log(LOG_WARNING, "Out of buffer space\n");
00280 return -1;
00281 }
00282 return 0;
00283 }
00284
00285 static struct ast_frame *lintog723_frameout(struct ast_translator_pvt *pvt)
00286 {
00287 struct g723_encoder_pvt *tmp = (struct g723_encoder_pvt *)pvt;
00288 #ifdef ANNEX_B
00289 int x;
00290 FLOAT tmpdata[Frame];
00291 #endif
00292 int cnt=0;
00293
00294 if (tmp->tail < Frame)
00295 return NULL;
00296 tmp->f.frametype = AST_FRAME_VOICE;
00297 tmp->f.subclass = AST_FORMAT_G723_1;
00298 tmp->f.offset = AST_FRIENDLY_OFFSET;
00299 tmp->f.src = __PRETTY_FUNCTION__;
00300 tmp->f.samples = 0;
00301 tmp->f.mallocd = 0;
00302 while(tmp->tail >= Frame) {
00303
00304 if (cnt + 24 >= sizeof(tmp->outbuf)) {
00305 ast_log(LOG_WARNING, "Out of buffer space\n");
00306 return NULL;
00307 }
00308 #ifdef ANNEX_B
00309 for (x=0;x<Frame;x++)
00310 tmpdata[x] = tmp->buf[x];
00311 Coder(&tmp->cod, tmpdata, tmp->outbuf + cnt);
00312 #else
00313 Coder(&tmp->cod, tmp->buf, tmp->outbuf + cnt);
00314 #endif
00315
00316 tmp->f.samples += 240;
00317 cnt += g723_len(tmp->outbuf[cnt]);
00318 tmp->tail -= Frame;
00319
00320 if (tmp->tail)
00321 memmove(tmp->buf, tmp->buf + Frame, tmp->tail * 2);
00322 }
00323 tmp->f.datalen = cnt;
00324 tmp->f.data = tmp->outbuf;
00325 #if 0
00326
00327 {
00328 static int fd = -1;
00329 int delay = htonl(30);
00330 short size;
00331 if (fd < 0)
00332 fd = open("trans.g723", O_WRONLY | O_CREAT | O_TRUNC, 0644);
00333 if (fd < 0)
00334 ast_log(LOG_WARNING, "Unable to create demo\n");
00335 write(fd, &delay, 4);
00336 size = htons(tmp->f.datalen);
00337 write(fd, &size, 2);
00338 write(fd, tmp->f.data, tmp->f.datalen);
00339 }
00340 #endif
00341 return &tmp->f;
00342 }
00343
00344 static void g723_destroy(struct ast_translator_pvt *pvt)
00345 {
00346 free(pvt);
00347 localusecnt--;
00348 ast_update_use_count();
00349 }
00350
00351 static struct ast_translator g723tolin =
00352 #ifdef ANNEX_B
00353 { "g723tolinb",
00354 #else
00355 { "g723tolin",
00356 #endif
00357 AST_FORMAT_G723_1, AST_FORMAT_SLINEAR,
00358 g723tolin_new,
00359 g723tolin_framein,
00360 g723tolin_frameout,
00361 g723_destroy,
00362 g723tolin_sample
00363 };
00364
00365 static struct ast_translator lintog723 =
00366 #ifdef ANNEX_B
00367 { "lintog723b",
00368 #else
00369 { "lintog723",
00370 #endif
00371 AST_FORMAT_SLINEAR, AST_FORMAT_G723_1,
00372 lintog723_new,
00373 lintog723_framein,
00374 lintog723_frameout,
00375 g723_destroy,
00376 lintog723_sample
00377 };
00378
00379 int unload_module(void)
00380 {
00381 int res;
00382 ast_mutex_lock(&localuser_lock);
00383 res = ast_unregister_translator(&lintog723);
00384 if (!res)
00385 res = ast_unregister_translator(&g723tolin);
00386 if (localusecnt)
00387 res = -1;
00388 ast_mutex_unlock(&localuser_lock);
00389 return res;
00390 }
00391
00392 int load_module(void)
00393 {
00394 int res;
00395 res=ast_register_translator(&g723tolin);
00396 if (!res)
00397 res=ast_register_translator(&lintog723);
00398 else
00399 ast_unregister_translator(&g723tolin);
00400 return res;
00401 }
00402
00403 char *description(void)
00404 {
00405 return tdesc;
00406 }
00407
00408 int usecount(void)
00409 {
00410 int res;
00411 STANDARD_USECOUNT(res);
00412 return res;
00413 }
00414
00415 char *key(void)
00416 {
00417 return ASTERISK_GPL_KEY;
00418 }