#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/config.h"
#include "asterisk/options.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "lpc10/lpc10.h"
#include "slin_lpc10_ex.h"
#include "lpc10_slin_ex.h"
Go to the source code of this file.
Data Structures | |
struct | ast_translator_pvt |
Defines | |
#define | LPC10_BYTES_IN_COMPRESSED_FRAME (LPC10_BITS_IN_COMPRESSED_FRAME + 7)/8 |
#define | lpc10_coder_pvt ast_translator_pvt |
Functions | |
AST_MUTEX_DEFINE_STATIC (localuser_lock) | |
static void | build_bits (unsigned char *c, INT32 *bits) |
char * | description (void) |
Provides a description of the module. | |
static void | extract_bits (INT32 *bits, unsigned char *c) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
static int | lintolpc10_framein (struct ast_translator_pvt *tmp, struct ast_frame *f) |
static struct ast_frame * | lintolpc10_frameout (struct ast_translator_pvt *tmp) |
static struct ast_frame * | lintolpc10_sample (void) |
int | load_module (void) |
Initialize the module. | |
static struct ast_translator_pvt * | lpc10_dec_new (void) |
static void | lpc10_destroy (struct ast_translator_pvt *pvt) |
static struct ast_translator_pvt * | lpc10_enc_new (void) |
static int | lpc10tolin_framein (struct ast_translator_pvt *tmp, struct ast_frame *f) |
static struct ast_frame * | lpc10tolin_frameout (struct ast_translator_pvt *tmp) |
static struct ast_frame * | lpc10tolin_sample (void) |
static void | parse_config (void) |
int | reload (void) |
Reload stuff. | |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
static struct ast_translator | lintolpc10 |
static int | localusecnt = 0 |
static struct ast_translator | lpc10tolin |
static char * | tdesc = "LPC10 2.4kbps (signed linear) Voice Coder" |
static int | useplc = 0 |
Definition in file codec_lpc10.c.
#define LPC10_BYTES_IN_COMPRESSED_FRAME (LPC10_BITS_IN_COMPRESSED_FRAME + 7)/8 |
Definition at line 60 of file codec_lpc10.c.
Referenced by lintolpc10_frameout(), and lpc10tolin_framein().
#define lpc10_coder_pvt ast_translator_pvt |
AST_MUTEX_DEFINE_STATIC | ( | localuser_lock | ) |
static void build_bits | ( | unsigned char * | c, | |
INT32 * | bits | |||
) | [static] |
Definition at line 197 of file codec_lpc10.c.
Referenced by lintolpc10_frameout().
00198 { 00199 unsigned char mask=0x80; 00200 int x; 00201 *c = 0; 00202 for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) { 00203 if (bits[x]) 00204 *c |= mask; 00205 mask = mask >> 1; 00206 if ((x % 8)==7) { 00207 c++; 00208 *c = 0; 00209 mask = 0x80; 00210 } 00211 } 00212 }
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 416 of file codec_lpc10.c.
00417 { 00418 return tdesc; 00419 }
static void extract_bits | ( | INT32 * | bits, | |
unsigned char * | c | |||
) | [static] |
Definition at line 184 of file codec_lpc10.c.
Referenced by lpc10tolin_framein().
00185 { 00186 int x; 00187 for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) { 00188 if (*c & (0x80 >> (x & 7))) 00189 bits[x] = 1; 00190 else 00191 bits[x] = 0; 00192 if ((x & 7) == 7) 00193 c++; 00194 } 00195 }
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 428 of file codec_lpc10.c.
References ASTERISK_GPL_KEY.
00429 { 00430 return ASTERISK_GPL_KEY; 00431 }
static int lintolpc10_framein | ( | struct ast_translator_pvt * | tmp, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 263 of file codec_lpc10.c.
References ast_log(), ast_translator_pvt::buf, ast_frame::data, ast_frame::datalen, LOG_WARNING, and ast_translator_pvt::tail.
00264 { 00265 /* Just add the frames to our stream */ 00266 /* XXX We should look at how old the rest of our stream is, and if it 00267 is too old, then we should overwrite it entirely, otherwise we can 00268 get artifacts of earlier talk that do not belong */ 00269 if (tmp->tail + f->datalen < sizeof(tmp->buf) / 2) { 00270 memcpy((tmp->buf + tmp->tail), f->data, f->datalen); 00271 tmp->tail += f->datalen/2; 00272 } else { 00273 ast_log(LOG_WARNING, "Out of buffer space\n"); 00274 return -1; 00275 } 00276 return 0; 00277 }
static struct ast_frame* lintolpc10_frameout | ( | struct ast_translator_pvt * | tmp | ) | [static] |
Definition at line 279 of file codec_lpc10.c.
References AST_FORMAT_LPC10, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_translator_pvt::buf, build_bits(), ast_frame::data, ast_frame::datalen, ast_translator_pvt::enc, ast_translator_pvt::f, ast_frame::frametype, LOG_WARNING, ast_translator_pvt::longer, ast_translator_pvt::lpc10, LPC10_BYTES_IN_COMPRESSED_FRAME, ast_frame::mallocd, ast_frame::offset, ast_translator_pvt::outbuf, ast_frame::samples, ast_frame::src, ast_frame::subclass, and ast_translator_pvt::tail.
00280 { 00281 int x; 00282 int consumed = 0; 00283 float tmpbuf[LPC10_SAMPLES_PER_FRAME]; 00284 INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; 00285 /* We can't work on anything less than a frame in size */ 00286 if (tmp->tail < LPC10_SAMPLES_PER_FRAME) 00287 return NULL; 00288 /* Start with an empty frame */ 00289 tmp->f.samples = 0; 00290 tmp->f.datalen = 0; 00291 tmp->f.frametype = AST_FRAME_VOICE; 00292 tmp->f.subclass = AST_FORMAT_LPC10; 00293 while(tmp->tail >= LPC10_SAMPLES_PER_FRAME) { 00294 if (tmp->f.datalen + LPC10_BYTES_IN_COMPRESSED_FRAME > sizeof(tmp->outbuf)) { 00295 ast_log(LOG_WARNING, "Out of buffer space\n"); 00296 return NULL; 00297 } 00298 /* Encode a frame of data */ 00299 for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) { 00300 tmpbuf[x] = (float)tmp->buf[x+consumed] / 32768.0; 00301 } 00302 lpc10_encode(tmpbuf, bits, tmp->lpc10.enc); 00303 build_bits(((unsigned char *)tmp->outbuf) + tmp->f.datalen, bits); 00304 tmp->f.datalen += LPC10_BYTES_IN_COMPRESSED_FRAME; 00305 tmp->f.samples += LPC10_SAMPLES_PER_FRAME; 00306 /* Use one of the two left over bits to record if this is a 22 or 23 ms frame... 00307 important for IAX use */ 00308 tmp->longer = 1 - tmp->longer; 00309 #if 0 /* what the heck was this for? */ 00310 ((char *)(tmp->f.data))[consumed - 1] |= tmp->longer; 00311 #endif 00312 tmp->tail -= LPC10_SAMPLES_PER_FRAME; 00313 consumed += LPC10_SAMPLES_PER_FRAME; 00314 } 00315 tmp->f.mallocd = 0; 00316 tmp->f.offset = AST_FRIENDLY_OFFSET; 00317 tmp->f.src = __PRETTY_FUNCTION__; 00318 tmp->f.data = tmp->outbuf; 00319 /* Move the data at the end of the buffer to the front */ 00320 if (tmp->tail) 00321 memmove(tmp->buf, tmp->buf + consumed, tmp->tail * 2); 00322 #if 0 00323 /* Save a sample frame */ 00324 { static int samplefr = 0; 00325 if (samplefr == 0) { 00326 int fd; 00327 fd = open("lpc10.example", O_WRONLY | O_CREAT, 0644); 00328 write(fd, tmp->f.data, tmp->f.datalen); 00329 close(fd); 00330 } 00331 samplefr++; 00332 } 00333 #endif 00334 return &tmp->f; 00335 }
static struct ast_frame* lintolpc10_sample | ( | void | ) | [static] |
Definition at line 120 of file codec_lpc10.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_lpc10_ex, ast_frame::src, and ast_frame::subclass.
00121 { 00122 static struct ast_frame f; 00123 f.frametype = AST_FRAME_VOICE; 00124 f.subclass = AST_FORMAT_SLINEAR; 00125 f.datalen = sizeof(slin_lpc10_ex); 00126 /* Assume 8000 Hz */ 00127 f.samples = LPC10_SAMPLES_PER_FRAME; 00128 f.mallocd = 0; 00129 f.offset = 0; 00130 f.src = __PRETTY_FUNCTION__; 00131 f.data = slin_lpc10_ex; 00132 return &f; 00133 }
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 404 of file codec_lpc10.c.
References ast_register_translator(), ast_unregister_translator(), lintolpc10, lpc10tolin, and parse_config().
00405 { 00406 int res; 00407 parse_config(); 00408 res=ast_register_translator(&lpc10tolin); 00409 if (!res) 00410 res=ast_register_translator(&lintolpc10); 00411 else 00412 ast_unregister_translator(&lpc10tolin); 00413 return res; 00414 }
static struct ast_translator_pvt* lpc10_dec_new | ( | void | ) | [static] |
Definition at line 104 of file codec_lpc10.c.
References free, lpc10_coder_pvt, malloc, and plc_init().
00105 { 00106 struct lpc10_coder_pvt *tmp; 00107 tmp = malloc(sizeof(struct lpc10_coder_pvt)); 00108 if (tmp) { 00109 if (!(tmp->lpc10.dec = create_lpc10_decoder_state())) { 00110 free(tmp); 00111 tmp = NULL; 00112 } 00113 tmp->tail = 0; 00114 tmp->longer = 0; 00115 plc_init(&tmp->plc); 00116 localusecnt++; 00117 } 00118 return tmp; 00119 }
static void lpc10_destroy | ( | struct ast_translator_pvt * | pvt | ) | [static] |
Definition at line 337 of file codec_lpc10.c.
References ast_translator_pvt::enc, free, and ast_translator_pvt::lpc10.
00338 { 00339 /* Enc and DEC are both just allocated, so they can be freed */ 00340 free(pvt->lpc10.enc); 00341 free(pvt); 00342 localusecnt--; 00343 }
static struct ast_translator_pvt* lpc10_enc_new | ( | void | ) | [static] |
Definition at line 88 of file codec_lpc10.c.
References free, lpc10_coder_pvt, and malloc.
00089 { 00090 struct lpc10_coder_pvt *tmp; 00091 tmp = malloc(sizeof(struct lpc10_coder_pvt)); 00092 if (tmp) { 00093 if (!(tmp->lpc10.enc = create_lpc10_encoder_state())) { 00094 free(tmp); 00095 tmp = NULL; 00096 } 00097 tmp->tail = 0; 00098 tmp->longer = 0; 00099 localusecnt++; 00100 } 00101 return tmp; 00102 }
static int lpc10tolin_framein | ( | struct ast_translator_pvt * | tmp, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 214 of file codec_lpc10.c.
References ast_log(), ast_translator_pvt::buf, ast_frame::data, ast_frame::datalen, ast_translator_pvt::dec, extract_bits(), LOG_WARNING, ast_translator_pvt::lpc10, LPC10_BYTES_IN_COMPRESSED_FRAME, ast_translator_pvt::plc, plc_fillin(), plc_rx(), and ast_translator_pvt::tail.
00215 { 00216 /* Assuming there's space left, decode into the current buffer at 00217 the tail location */ 00218 int x; 00219 int len=0; 00220 float tmpbuf[LPC10_SAMPLES_PER_FRAME]; 00221 short *sd; 00222 INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; 00223 00224 if(f->datalen == 0) { /* perform PLC with nominal framesize of LPC10_SAMPLES_PER_FRAME */ 00225 if((tmp->tail + LPC10_SAMPLES_PER_FRAME) > sizeof(tmp->buf)/2) { 00226 ast_log(LOG_WARNING, "Out of buffer space\n"); 00227 return -1; 00228 } 00229 if(useplc) { 00230 plc_fillin(&tmp->plc, tmp->buf+tmp->tail, LPC10_SAMPLES_PER_FRAME); 00231 tmp->tail += LPC10_SAMPLES_PER_FRAME; 00232 } 00233 return 0; 00234 } 00235 00236 while(len + LPC10_BYTES_IN_COMPRESSED_FRAME <= f->datalen) { 00237 if (tmp->tail + LPC10_SAMPLES_PER_FRAME < sizeof(tmp->buf)/2) { 00238 sd = tmp->buf + tmp->tail; 00239 extract_bits(bits, f->data + len); 00240 if (lpc10_decode(bits, tmpbuf, tmp->lpc10.dec)) { 00241 ast_log(LOG_WARNING, "Invalid lpc10 data\n"); 00242 return -1; 00243 } 00244 for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) { 00245 /* Convert to a real between -1.0 and 1.0 */ 00246 sd[x] = 32768.0 * tmpbuf[x]; 00247 } 00248 00249 if(useplc) plc_rx(&tmp->plc, tmp->buf + tmp->tail, LPC10_SAMPLES_PER_FRAME); 00250 00251 tmp->tail+=LPC10_SAMPLES_PER_FRAME; 00252 } else { 00253 ast_log(LOG_WARNING, "Out of buffer space\n"); 00254 return -1; 00255 } 00256 len += LPC10_BYTES_IN_COMPRESSED_FRAME; 00257 } 00258 if (len != f->datalen) 00259 printf("Decoded %d, expected %d\n", len, f->datalen); 00260 return 0; 00261 }
static struct ast_frame* lpc10tolin_frameout | ( | struct ast_translator_pvt * | tmp | ) | [static] |
Definition at line 151 of file codec_lpc10.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.
00152 { 00153 if (!tmp->tail) 00154 return NULL; 00155 /* Signed linear is no particular frame size, so just send whatever 00156 we have in the buffer in one lump sum */ 00157 tmp->f.frametype = AST_FRAME_VOICE; 00158 tmp->f.subclass = AST_FORMAT_SLINEAR; 00159 tmp->f.datalen = tmp->tail * 2; 00160 /* Assume 8000 Hz */ 00161 tmp->f.samples = tmp->tail; 00162 tmp->f.mallocd = 0; 00163 tmp->f.offset = AST_FRIENDLY_OFFSET; 00164 tmp->f.src = __PRETTY_FUNCTION__; 00165 tmp->f.data = tmp->buf; 00166 /* Reset tail pointer */ 00167 tmp->tail = 0; 00168 00169 #if 0 00170 /* Save a sample frame */ 00171 { static int samplefr = 0; 00172 if (samplefr == 80) { 00173 int fd; 00174 fd = open("lpc10.example", O_WRONLY | O_CREAT, 0644); 00175 write(fd, tmp->f.data, tmp->f.datalen); 00176 close(fd); 00177 } 00178 samplefr++; 00179 } 00180 #endif 00181 return &tmp->f; 00182 }
static struct ast_frame* lpc10tolin_sample | ( | void | ) | [static] |
Definition at line 135 of file codec_lpc10.c.
References AST_FORMAT_LPC10, AST_FRAME_VOICE, ast_frame::data, ast_frame::datalen, ast_frame::frametype, lpc10_slin_ex, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.
00136 { 00137 static struct ast_frame f; 00138 f.frametype = AST_FRAME_VOICE; 00139 f.subclass = AST_FORMAT_LPC10; 00140 f.datalen = sizeof(lpc10_slin_ex); 00141 /* All frames are 22 ms long (maybe a little more -- why did he choose 00142 LPC10_SAMPLES_PER_FRAME sample frames anyway?? */ 00143 f.samples = LPC10_SAMPLES_PER_FRAME; 00144 f.mallocd = 0; 00145 f.offset = 0; 00146 f.src = __PRETTY_FUNCTION__; 00147 f.data = lpc10_slin_ex; 00148 return &f; 00149 }
static void parse_config | ( | void | ) | [static] |
Definition at line 365 of file codec_lpc10.c.
References ast_config_destroy(), ast_config_load(), ast_true(), ast_variable_browse(), ast_verbose(), cfg, option_verbose, var, and VERBOSE_PREFIX_3.
00366 { 00367 struct ast_config *cfg; 00368 struct ast_variable *var; 00369 if ((cfg = ast_config_load("codecs.conf"))) { 00370 if ((var = ast_variable_browse(cfg, "plc"))) { 00371 while (var) { 00372 if (!strcasecmp(var->name, "genericplc")) { 00373 useplc = ast_true(var->value) ? 1 : 0; 00374 if (option_verbose > 2) 00375 ast_verbose(VERBOSE_PREFIX_3 "codec_lpc10: %susing generic PLC\n", useplc ? "" : "not "); 00376 } 00377 var = var->next; 00378 } 00379 } 00380 ast_config_destroy(cfg); 00381 } 00382 }
int reload | ( | void | ) |
Reload stuff.
This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 384 of file codec_lpc10.c.
References parse_config().
00385 { 00386 parse_config(); 00387 return 0; 00388 }
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 391 of file codec_lpc10.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_unregister_translator(), lintolpc10, and lpc10tolin.
00392 { 00393 int res; 00394 ast_mutex_lock(&localuser_lock); 00395 res = ast_unregister_translator(&lintolpc10); 00396 if (!res) 00397 res = ast_unregister_translator(&lpc10tolin); 00398 if (localusecnt) 00399 res = -1; 00400 ast_mutex_unlock(&localuser_lock); 00401 return res; 00402 }
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 421 of file codec_lpc10.c.
References STANDARD_USECOUNT.
00422 { 00423 int res; 00424 STANDARD_USECOUNT(res); 00425 return res; 00426 }
struct ast_translator lintolpc10 [static] |
int localusecnt = 0 [static] |
Definition at line 63 of file codec_lpc10.c.
struct ast_translator lpc10tolin [static] |
char* tdesc = "LPC10 2.4kbps (signed linear) Voice Coder" [static] |
Definition at line 65 of file codec_lpc10.c.
int useplc = 0 [static] |
Definition at line 67 of file codec_lpc10.c.