#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 "ilbc/iLBC_encode.h"
#include "ilbc/iLBC_decode.h"
#include "slin_ilbc_ex.h"
#include "ilbc_slin_ex.h"
Include dependency graph for codec_ilbc.c:
Go to the source code of this file.
Data Structures | |
struct | ast_translator_pvt |
Defines | |
#define | ilbc_coder_pvt ast_translator_pvt |
#define | ILBC_MS 30 |
#define | USE_ILBC_ENHANCER 0 |
Functions | |
AST_MUTEX_DEFINE_STATIC (localuser_lock) | |
char * | description (void) |
Provides a description of the module. | |
static void | ilbc_destroy_stuff (struct ast_translator_pvt *pvt) |
static int | ilbctolin_framein (struct ast_translator_pvt *tmp, struct ast_frame *f) |
static struct ast_frame * | ilbctolin_frameout (struct ast_translator_pvt *tmp) |
static struct ast_translator_pvt * | ilbctolin_new (void) |
static struct ast_frame * | ilbctolin_sample (void) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
static int | lintoilbc_framein (struct ast_translator_pvt *tmp, struct ast_frame *f) |
static struct ast_frame * | lintoilbc_frameout (struct ast_translator_pvt *tmp) |
static struct ast_translator_pvt * | lintoilbc_new (void) |
static struct ast_frame * | lintoilbc_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 | ilbctolin |
static struct ast_translator | lintoilbc |
static int | localusecnt = 0 |
static char * | tdesc = "iLBC/PCM16 (signed linear) Codec Translator" |
Definition in file codec_ilbc.c.
#define ilbc_coder_pvt ast_translator_pvt |
#define ILBC_MS 30 |
#define USE_ILBC_ENHANCER 0 |
AST_MUTEX_DEFINE_STATIC | ( | localuser_lock | ) |
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 303 of file codec_ilbc.c.
References tdesc.
00304 { 00305 return tdesc; 00306 }
static void ilbc_destroy_stuff | ( | struct ast_translator_pvt * | pvt | ) | [static] |
Definition at line 253 of file codec_ilbc.c.
References free, and localusecnt.
00254 { 00255 free(pvt); 00256 localusecnt--; 00257 }
static int ilbctolin_framein | ( | struct ast_translator_pvt * | tmp, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 155 of file codec_ilbc.c.
References ast_log(), ast_translator_pvt::buf, ast_frame::data, ast_frame::datalen, ast_translator_pvt::dec, LOG_WARNING, ast_frame::src, and ast_translator_pvt::tail.
00156 { 00157 /* Assuming there's space left, decode into the current buffer at 00158 the tail location. Read in as many frames as there are */ 00159 int x,i; 00160 float tmpf[240]; 00161 00162 if (f->datalen == 0) { /* native PLC */ 00163 if (tmp->tail + 240 < sizeof(tmp->buf)/2) { 00164 iLBC_decode(tmpf, NULL, &tmp->dec, 0); 00165 for (i=0;i<240;i++) 00166 tmp->buf[tmp->tail + i] = tmpf[i]; 00167 tmp->tail+=240; 00168 } else { 00169 ast_log(LOG_WARNING, "Out of buffer space\n"); 00170 return -1; 00171 } 00172 } 00173 00174 if (f->datalen % 50) { 00175 ast_log(LOG_WARNING, "Huh? An ilbc frame that isn't a multiple of 50 bytes long from %s (%d)?\n", f->src, f->datalen); 00176 return -1; 00177 } 00178 00179 for (x=0;x<f->datalen;x+=50) { 00180 if (tmp->tail + 240 < sizeof(tmp->buf)/2) { 00181 iLBC_decode(tmpf, f->data + x, &tmp->dec, 1); 00182 for (i=0;i<240;i++) 00183 tmp->buf[tmp->tail + i] = tmpf[i]; 00184 tmp->tail+=240; 00185 } else { 00186 ast_log(LOG_WARNING, "Out of buffer space\n"); 00187 return -1; 00188 } 00189 } 00190 return 0; 00191 }
static struct ast_frame* ilbctolin_frameout | ( | struct ast_translator_pvt * | tmp | ) | [static] |
Definition at line 134 of file codec_ilbc.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_translator_pvt::buf, ast_frame::data, ast_frame::datalen, ast_translator_pvt::f, ast_frame::frametype, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, ast_frame::subclass, and ast_translator_pvt::tail.
00135 { 00136 if (!tmp->tail) 00137 return NULL; 00138 /* Signed linear is no particular frame size, so just send whatever 00139 we have in the buffer in one lump sum */ 00140 tmp->f.frametype = AST_FRAME_VOICE; 00141 tmp->f.subclass = AST_FORMAT_SLINEAR; 00142 tmp->f.datalen = tmp->tail * 2; 00143 /* Assume 8000 Hz */ 00144 tmp->f.samples = tmp->tail; 00145 tmp->f.mallocd = 0; 00146 tmp->f.offset = AST_FRIENDLY_OFFSET; 00147 tmp->f.src = __PRETTY_FUNCTION__; 00148 tmp->f.data = tmp->buf; 00149 /* Reset tail pointer */ 00150 tmp->tail = 0; 00151 00152 return &tmp->f; 00153 }
static struct ast_translator_pvt* ilbctolin_new | ( | void | ) | [static] |
Definition at line 90 of file codec_ilbc.c.
References ilbc_coder_pvt, ILBC_MS, malloc, and USE_ILBC_ENHANCER.
00091 { 00092 struct ilbc_coder_pvt *tmp; 00093 tmp = malloc(sizeof(struct ilbc_coder_pvt)); 00094 if (tmp) { 00095 /* Shut valgrind up */ 00096 memset(&tmp->dec, 0, sizeof(tmp->dec)); 00097 initDecode(&tmp->dec, ILBC_MS, USE_ILBC_ENHANCER); 00098 tmp->tail = 0; 00099 localusecnt++; 00100 } 00101 return tmp; 00102 }
static struct ast_frame* ilbctolin_sample | ( | void | ) | [static] |
Definition at line 119 of file codec_ilbc.c.
References AST_FORMAT_ILBC, AST_FRAME_VOICE, ast_frame::data, ast_frame::datalen, ast_frame::frametype, ilbc_slin_ex, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.
00120 { 00121 static struct ast_frame f; 00122 f.frametype = AST_FRAME_VOICE; 00123 f.subclass = AST_FORMAT_ILBC; 00124 f.datalen = sizeof(ilbc_slin_ex); 00125 /* All frames are 30 ms long */ 00126 f.samples = 240; 00127 f.mallocd = 0; 00128 f.offset = 0; 00129 f.src = __PRETTY_FUNCTION__; 00130 f.data = ilbc_slin_ex; 00131 return &f; 00132 }
char* key | ( | void | ) |
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 315 of file codec_ilbc.c.
References ASTERISK_GPL_KEY.
00316 { 00317 return ASTERISK_GPL_KEY; 00318 }
static int lintoilbc_framein | ( | struct ast_translator_pvt * | tmp, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 193 of file codec_ilbc.c.
References ast_log(), ast_translator_pvt::buf, ast_frame::data, ast_frame::datalen, LOG_WARNING, and ast_translator_pvt::tail.
00194 { 00195 /* Just add the frames to our stream */ 00196 /* XXX We should look at how old the rest of our stream is, and if it 00197 is too old, then we should overwrite it entirely, otherwise we can 00198 get artifacts of earlier talk that do not belong */ 00199 if (tmp->tail + f->datalen/2 < sizeof(tmp->buf) / 2) { 00200 memcpy((tmp->buf + tmp->tail), f->data, f->datalen); 00201 tmp->tail += f->datalen/2; 00202 } else { 00203 ast_log(LOG_WARNING, "Out of buffer space\n"); 00204 return -1; 00205 } 00206 return 0; 00207 }
static struct ast_frame* lintoilbc_frameout | ( | struct ast_translator_pvt * | tmp | ) | [static] |
Definition at line 209 of file codec_ilbc.c.
References AST_FORMAT_ILBC, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_translator_pvt::buf, ast_frame::data, ast_frame::datalen, ast_translator_pvt::enc, ast_translator_pvt::f, ast_frame::frametype, LOG_WARNING, ast_frame::mallocd, ast_frame::offset, ast_translator_pvt::outbuf, ast_frame::samples, ast_frame::src, ast_frame::subclass, and ast_translator_pvt::tail.
00210 { 00211 int x=0,i; 00212 float tmpf[240]; 00213 /* We can't work on anything less than a frame in size */ 00214 if (tmp->tail < 240) 00215 return NULL; 00216 tmp->f.frametype = AST_FRAME_VOICE; 00217 tmp->f.subclass = AST_FORMAT_ILBC; 00218 tmp->f.mallocd = 0; 00219 tmp->f.offset = AST_FRIENDLY_OFFSET; 00220 tmp->f.src = __PRETTY_FUNCTION__; 00221 tmp->f.data = tmp->outbuf; 00222 while(tmp->tail >= 240) { 00223 if ((x+1) * 50 >= sizeof(tmp->outbuf)) { 00224 ast_log(LOG_WARNING, "Out of buffer space\n"); 00225 break; 00226 } 00227 for (i=0;i<240;i++) 00228 tmpf[i] = tmp->buf[i]; 00229 /* Encode a frame of data */ 00230 iLBC_encode(((unsigned char *)(tmp->outbuf)) + (x * 50), tmpf, &tmp->enc); 00231 /* Assume 8000 Hz -- 20 ms */ 00232 tmp->tail -= 240; 00233 /* Move the data at the end of the buffer to the front */ 00234 if (tmp->tail) 00235 memmove(tmp->buf, tmp->buf + 240, tmp->tail * 2); 00236 x++; 00237 } 00238 tmp->f.datalen = x * 50; 00239 tmp->f.samples = x * 240; 00240 #if 0 00241 { 00242 static int fd = -1; 00243 if (fd == -1) { 00244 fd = open("ilbc.out", O_CREAT|O_TRUNC|O_WRONLY, 0666); 00245 write(fd, tmp->f.data, tmp->f.datalen); 00246 close(fd); 00247 } 00248 } 00249 #endif 00250 return &tmp->f; 00251 }
static struct ast_translator_pvt* lintoilbc_new | ( | void | ) | [static] |
Definition at line 76 of file codec_ilbc.c.
References ilbc_coder_pvt, ILBC_MS, and malloc.
00077 { 00078 struct ilbc_coder_pvt *tmp; 00079 tmp = malloc(sizeof(struct ilbc_coder_pvt)); 00080 if (tmp) { 00081 /* Shut valgrind up */ 00082 memset(&tmp->enc, 0, sizeof(tmp->enc)); 00083 initEncode(&tmp->enc, ILBC_MS); 00084 tmp->tail = 0; 00085 localusecnt++; 00086 } 00087 return tmp; 00088 }
static struct ast_frame* lintoilbc_sample | ( | void | ) | [static] |
Definition at line 104 of file codec_ilbc.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_ilbc_ex, ast_frame::src, and ast_frame::subclass.
00105 { 00106 static struct ast_frame f; 00107 f.frametype = AST_FRAME_VOICE; 00108 f.subclass = AST_FORMAT_SLINEAR; 00109 f.datalen = sizeof(slin_ilbc_ex); 00110 /* Assume 8000 Hz */ 00111 f.samples = sizeof(slin_ilbc_ex)/2; 00112 f.mallocd = 0; 00113 f.offset = 0; 00114 f.src = __PRETTY_FUNCTION__; 00115 f.data = slin_ilbc_ex; 00116 return &f; 00117 }
int load_module | ( | void | ) |
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 292 of file codec_ilbc.c.
References ast_register_translator(), ast_unregister_translator(), ilbctolin, and lintoilbc.
00293 { 00294 int res; 00295 res=ast_register_translator(&ilbctolin); 00296 if (!res) 00297 res=ast_register_translator(&lintoilbc); 00298 else 00299 ast_unregister_translator(&ilbctolin); 00300 return res; 00301 }
int unload_module | ( | void | ) |
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 279 of file codec_ilbc.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_unregister_translator(), ilbctolin, lintoilbc, and localusecnt.
00280 { 00281 int res; 00282 ast_mutex_lock(&localuser_lock); 00283 res = ast_unregister_translator(&lintoilbc); 00284 if (!res) 00285 res = ast_unregister_translator(&ilbctolin); 00286 if (localusecnt) 00287 res = -1; 00288 ast_mutex_unlock(&localuser_lock); 00289 return res; 00290 }
int usecount | ( | void | ) |
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 308 of file codec_ilbc.c.
References STANDARD_USECOUNT.
00309 { 00310 int res; 00311 STANDARD_USECOUNT(res); 00312 return res; 00313 }
struct ast_translator ilbctolin [static] |
struct ast_translator lintoilbc [static] |
int localusecnt = 0 [static] |
Definition at line 57 of file codec_ilbc.c.
char* tdesc = "iLBC/PCM16 (signed linear) Codec Translator" [static] |
Definition at line 59 of file codec_ilbc.c.