#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/translate.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "g723.1/typedef.h"
#include "g723.1/cst_lbc.h"
#include "g723.1/coder.h"
#include "g723.1/decod.h"
#include "g723.1/dec_cng.h"
#include "g723.1/cod_cng.h"
#include "g723.1/vad.h"
#include "slin_g723_ex.h"
#include "g723_slin_ex.h"
Include dependency graph for codec_g723_1.c:
Go to the source code of this file.
Data Structures | |
struct | g723_decoder_pvt |
struct | g723_encoder_pvt |
Defines | |
#define | TYPE_DONTSEND 0x3 |
#define | TYPE_HIGH 0x0 |
#define | TYPE_LOW 0x1 |
#define | TYPE_MASK 0x3 |
#define | TYPE_SILENCE 0x2 |
Functions | |
AST_MUTEX_DEFINE_STATIC (localuser_lock) | |
char * | description (void) |
Provides a description of the module. | |
static void | g723_destroy (struct ast_translator_pvt *pvt) |
static int | g723_len (unsigned char buf) |
static int | g723tolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) |
static struct ast_frame * | g723tolin_frameout (struct ast_translator_pvt *pvt) |
static struct ast_translator_pvt * | g723tolin_new (void) |
static struct ast_frame * | g723tolin_sample (void) |
char * | key (void) |
Returns the ASTERISK_GPL_KEY. | |
static int | lintog723_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) |
static struct ast_frame * | lintog723_frameout (struct ast_translator_pvt *pvt) |
static struct ast_translator_pvt * | lintog723_new (void) |
static struct ast_frame * | lintog723_sample (void) |
int | load_module (void) |
Initialize the module. | |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
static struct ast_translator | g723tolin |
static struct ast_translator | lintog723 |
static int | localusecnt = 0 |
static char * | tdesc = "Annex A (fixed point) G.723.1/PCM16 Codec Translator" |
Flag | UseHp = True |
Flag | UsePf = True |
Flag | UseVx = True |
enum Crate | WrkRate = Rate63 |
Definition in file codec_g723_1.c.
|
Definition at line 33 of file codec_g723_1.c. |
|
Definition at line 30 of file codec_g723_1.c. |
|
Definition at line 31 of file codec_g723_1.c. |
|
Definition at line 34 of file codec_g723_1.c. |
|
Definition at line 32 of file codec_g723_1.c. |
|
|
|
Provides a description of the module.
Definition at line 403 of file codec_g723_1.c. 00404 { 00405 return tdesc; 00406 }
|
|
Definition at line 344 of file codec_g723_1.c. References ast_update_use_count(), and free. 00345 { 00346 free(pvt); 00347 localusecnt--; 00348 ast_update_use_count(); 00349 }
|
|
Definition at line 208 of file codec_g723_1.c. References ast_log(), LOG_WARNING, TYPE_DONTSEND, TYPE_HIGH, TYPE_LOW, TYPE_MASK, and TYPE_SILENCE. 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 }
|
|
Definition at line 229 of file codec_g723_1.c. References ast_log(), g723_decoder_pvt::buf, ast_frame::data, ast_frame::datalen, g723_decoder_pvt::dec, g723_decoder_pvt::f, g723_len(), LOG_WARNING, and g723_decoder_pvt::tail. 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 /* Assuming there's space left, decode into the current buffer at 00240 the tail location */ 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 }
|
|
Definition at line 176 of file codec_g723_1.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, g723_decoder_pvt::buf, ast_frame::data, ast_frame::datalen, g723_decoder_pvt::f, ast_frame::frametype, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, ast_frame::subclass, and g723_decoder_pvt::tail. 00177 { 00178 struct g723_decoder_pvt *tmp = (struct g723_decoder_pvt *)pvt; 00179 if (!tmp->tail) 00180 return NULL; 00181 /* Signed linear is no particular frame size, so just send whatever 00182 we have in the buffer in one lump sum */ 00183 tmp->f.frametype = AST_FRAME_VOICE; 00184 tmp->f.subclass = AST_FORMAT_SLINEAR; 00185 tmp->f.datalen = tmp->tail * 2; 00186 /* Assume 8000 Hz */ 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 /* Reset tail pointer */ 00193 tmp->tail = 0; 00194 00195 #if 0 00196 /* Save the frames */ 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 }
|
|
Definition at line 114 of file codec_g723_1.c. References ast_update_use_count(), g723_decoder_pvt::dec, malloc, and g723_decoder_pvt::tail. 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 }
|
|
Definition at line 143 of file codec_g723_1.c. References AST_FORMAT_G723_1, AST_FRAME_VOICE, ast_frame::data, ast_frame::datalen, ast_frame::frametype, g723_slin_ex, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass. 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 /* All frames are 30 ms long */ 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 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 415 of file codec_g723_1.c. References ASTERISK_GPL_KEY. 00416 { 00417 return ASTERISK_GPL_KEY; 00418 }
|
|
Definition at line 268 of file codec_g723_1.c. References ast_log(), g723_encoder_pvt::buf, ast_frame::data, ast_frame::datalen, g723_encoder_pvt::f, LOG_WARNING, and g723_encoder_pvt::tail. 00269 { 00270 /* Just add the frames to our stream */ 00271 /* XXX We should look at how old the rest of our stream is, and if it 00272 is too old, then we should overwrite it entirely, otherwise we can 00273 get artifacts of earlier talk that do not belong */ 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 }
|
|
Definition at line 285 of file codec_g723_1.c. References AST_FORMAT_G723_1, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), g723_encoder_pvt::buf, g723_encoder_pvt::cod, ast_frame::data, ast_frame::datalen, g723_encoder_pvt::f, ast_frame::frametype, g723_len(), LOG_WARNING, ast_frame::mallocd, ast_frame::offset, g723_encoder_pvt::outbuf, ast_frame::samples, ast_frame::src, ast_frame::subclass, and g723_encoder_pvt::tail. 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 /* We can't work on anything less than a frame in size */ 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 /* Encode a frame of data */ 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 /* Assume 8000 Hz */ 00316 tmp->f.samples += 240; 00317 cnt += g723_len(tmp->outbuf[cnt]); 00318 tmp->tail -= Frame; 00319 /* Move the data at the end of the buffer to the front */ 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 /* Save to a g723 sample output file... */ 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 }
|
|
Definition at line 158 of file codec_g723_1.c. References ast_update_use_count(), g723_encoder_pvt::cod, malloc, and g723_encoder_pvt::tail. 00159 { 00160 struct g723_encoder_pvt *tmp; 00161 tmp = malloc(sizeof(struct g723_encoder_pvt)); 00162 if (tmp) { 00163 Init_Coder(&tmp->cod); 00164 /* Init Comfort Noise Functions */ 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 }
|
|
Definition at line 128 of file codec_g723_1.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, slin_g723_ex, ast_frame::src, and ast_frame::subclass. 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 /* Assume 8000 Hz */ 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 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 392 of file codec_g723_1.c. References ast_register_translator(), ast_unregister_translator(), g723tolin, and lintog723. 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 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 379 of file codec_g723_1.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_unregister_translator(), g723tolin, and lintog723. 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 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 408 of file codec_g723_1.c. References STANDARD_USECOUNT. 00409 { 00410 int res; 00411 STANDARD_USECOUNT(res); 00412 return res; 00413 }
|
|
Definition at line 351 of file codec_g723_1.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 365 of file codec_g723_1.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 77 of file codec_g723_1.c. |
|
Definition at line 82 of file codec_g723_1.c. |
|
Definition at line 87 of file codec_g723_1.c. |
|
Definition at line 86 of file codec_g723_1.c. |
|
Definition at line 88 of file codec_g723_1.c. |
|
Definition at line 90 of file codec_g723_1.c. |