#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/translate.h"
#include "asterisk/channel.h"
#include "slin_adpcm_ex.h"
#include "adpcm_slin_ex.h"
Go to the source code of this file.
Data Structures | |
struct | adpcm_decoder_pvt |
struct | adpcm_encoder_pvt |
struct | adpcm_state |
Defines | |
#define | BUFFER_SIZE 8096 |
Functions | |
static int | adpcm (short csig, struct adpcm_state *state) |
static void | adpcm_destroy (struct ast_translator_pvt *pvt) |
static int | adpcmtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) |
static struct ast_frame * | adpcmtolin_frameout (struct ast_translator_pvt *pvt) |
static struct ast_translator_pvt * | adpcmtolin_new (void) |
static struct ast_frame * | adpcmtolin_sample (void) |
AST_MUTEX_DEFINE_STATIC (localuser_lock) | |
static short | decode (int encoded, struct adpcm_state *state) |
char * | description (void) |
Provides a description of the module. | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
static int | lintoadpcm_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) |
static struct ast_frame * | lintoadpcm_frameout (struct ast_translator_pvt *pvt) |
static struct ast_translator_pvt * | lintoadpcm_new (void) |
static struct ast_frame * | lintoadpcm_sample (void) |
int | load_module (void) |
Initialize the module. | |
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 | adpcmtolin |
static int | indsft [8] = { -1, -1, -1, -1, 2, 4, 6, 8 } |
static struct ast_translator | lintoadpcm |
static int | localusecnt = 0 |
static int | stpsz [49] |
static char * | tdesc = "Adaptive Differential PCM Coder/Decoder" |
static int | useplc = 0 |
Definition in file codec_adpcm.c.
#define BUFFER_SIZE 8096 |
Definition at line 52 of file codec_adpcm.c.
static int adpcm | ( | short | csig, | |
struct adpcm_state * | state | |||
) | [inline, static] |
Definition at line 178 of file codec_adpcm.c.
References decode(), adpcm_state::signal, and adpcm_state::ssindex.
Referenced by lintoadpcm_frameout().
00179 { 00180 int diff; 00181 int step; 00182 int encoded; 00183 00184 /* 00185 * Clip csig if too large or too small 00186 */ 00187 csig >>= 4; 00188 00189 step = stpsz[state->ssindex]; 00190 diff = csig - state->signal; 00191 00192 #ifdef NOT_BLI 00193 if (diff < 0) 00194 { 00195 encoded = (-diff << 2) / step; 00196 if (encoded > 7) 00197 encoded = 7; 00198 encoded |= 0x08; 00199 } 00200 else 00201 { 00202 encoded = (diff << 2) / step; 00203 if (encoded > 7) 00204 encoded = 7; 00205 } 00206 #else /* BLI code */ 00207 if (diff < 0) 00208 { 00209 encoded = 8; 00210 diff = -diff; 00211 } 00212 else 00213 encoded = 0; 00214 if (diff >= step) 00215 { 00216 encoded |= 4; 00217 diff -= step; 00218 } 00219 step >>= 1; 00220 if (diff >= step) 00221 { 00222 encoded |= 2; 00223 diff -= step; 00224 } 00225 step >>= 1; 00226 if (diff >= step) 00227 encoded |= 1; 00228 #endif /* NOT_BLI */ 00229 00230 /* feedback to state */ 00231 decode(encoded, state); 00232 00233 return encoded; 00234 }
static void adpcm_destroy | ( | struct ast_translator_pvt * | pvt | ) | [static] |
Definition at line 540 of file codec_adpcm.c.
References ast_update_use_count(), free, and localusecnt.
00541 { 00542 free (pvt); 00543 localusecnt--; 00544 ast_update_use_count (); 00545 }
static int adpcmtolin_framein | ( | struct ast_translator_pvt * | pvt, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 330 of file codec_adpcm.c.
References ast_log(), ast_frame::data, ast_frame::datalen, decode(), adpcm_decoder_pvt::f, LOG_WARNING, adpcm_decoder_pvt::outbuf, adpcm_decoder_pvt::plc, plc_fillin(), plc_rx(), adpcm_decoder_pvt::state, and adpcm_decoder_pvt::tail.
00331 { 00332 struct adpcm_decoder_pvt *tmp = (struct adpcm_decoder_pvt *) pvt; 00333 int x; 00334 unsigned char *b; 00335 00336 if(f->datalen == 0) { /* perform PLC with nominal framesize of 20ms/160 samples */ 00337 if((tmp->tail + 160) > sizeof(tmp->outbuf) / 2) { 00338 ast_log(LOG_WARNING, "Out of buffer space\n"); 00339 return -1; 00340 } 00341 if(useplc) { 00342 plc_fillin(&tmp->plc, tmp->outbuf+tmp->tail, 160); 00343 tmp->tail += 160; 00344 } 00345 return 0; 00346 } 00347 00348 if (f->datalen * 4 + tmp->tail * 2 > sizeof(tmp->outbuf)) { 00349 ast_log(LOG_WARNING, "Out of buffer space\n"); 00350 return -1; 00351 } 00352 00353 b = f->data; 00354 00355 for (x=0;x<f->datalen;x++) { 00356 tmp->outbuf[tmp->tail++] = decode((b[x] >> 4) & 0xf, &tmp->state); 00357 tmp->outbuf[tmp->tail++] = decode(b[x] & 0x0f, &tmp->state); 00358 } 00359 00360 if(useplc) plc_rx(&tmp->plc, tmp->outbuf+tmp->tail-f->datalen*2, f->datalen*2); 00361 00362 return 0; 00363 }
static struct ast_frame* adpcmtolin_frameout | ( | struct ast_translator_pvt * | pvt | ) | [static] |
Definition at line 378 of file codec_adpcm.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frame::data, ast_frame::datalen, adpcm_decoder_pvt::f, ast_frame::frametype, ast_frame::mallocd, ast_frame::offset, adpcm_decoder_pvt::outbuf, ast_frame::samples, ast_frame::src, ast_frame::subclass, and adpcm_decoder_pvt::tail.
00379 { 00380 struct adpcm_decoder_pvt *tmp = (struct adpcm_decoder_pvt *) pvt; 00381 00382 if (!tmp->tail) 00383 return NULL; 00384 00385 tmp->f.frametype = AST_FRAME_VOICE; 00386 tmp->f.subclass = AST_FORMAT_SLINEAR; 00387 tmp->f.datalen = tmp->tail *2; 00388 tmp->f.samples = tmp->tail; 00389 tmp->f.mallocd = 0; 00390 tmp->f.offset = AST_FRIENDLY_OFFSET; 00391 tmp->f.src = __PRETTY_FUNCTION__; 00392 tmp->f.data = tmp->outbuf; 00393 tmp->tail = 0; 00394 return &tmp->f; 00395 }
static struct ast_translator_pvt* adpcmtolin_new | ( | void | ) | [static] |
Definition at line 276 of file codec_adpcm.c.
References ast_update_use_count(), malloc, and plc_init().
00277 { 00278 struct adpcm_decoder_pvt *tmp; 00279 tmp = malloc (sizeof (struct adpcm_decoder_pvt)); 00280 if (tmp) 00281 { 00282 memset(tmp, 0, sizeof(*tmp)); 00283 tmp->tail = 0; 00284 plc_init(&tmp->plc); 00285 localusecnt++; 00286 ast_update_use_count (); 00287 } 00288 return (struct ast_translator_pvt *) tmp; 00289 }
static struct ast_frame* adpcmtolin_sample | ( | void | ) | [static] |
Definition at line 494 of file codec_adpcm.c.
References adpcm_slin_ex, AST_FORMAT_ADPCM, AST_FRAME_VOICE, ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.
00495 { 00496 static struct ast_frame f; 00497 f.frametype = AST_FRAME_VOICE; 00498 f.subclass = AST_FORMAT_ADPCM; 00499 f.datalen = sizeof (adpcm_slin_ex); 00500 f.samples = sizeof(adpcm_slin_ex) * 2; 00501 f.mallocd = 0; 00502 f.offset = 0; 00503 f.src = __PRETTY_FUNCTION__; 00504 f.data = adpcm_slin_ex; 00505 return &f; 00506 }
AST_MUTEX_DEFINE_STATIC | ( | localuser_lock | ) |
static short decode | ( | int | encoded, | |
struct adpcm_state * | state | |||
) | [inline, static] |
Definition at line 106 of file codec_adpcm.c.
References adpcm_state::next_flag, adpcm_state::signal, adpcm_state::ssindex, and adpcm_state::zero_count.
Referenced by adpcm(), and adpcmtolin_framein().
00107 { 00108 int diff; 00109 int step; 00110 int sign; 00111 00112 step = stpsz[state->ssindex]; 00113 00114 sign = encoded & 0x08; 00115 encoded &= 0x07; 00116 #ifdef NOT_BLI 00117 diff = (((encoded << 1) + 1) * step) >> 3; 00118 #else /* BLI code */ 00119 diff = step >> 3; 00120 if (encoded & 4) diff += step; 00121 if (encoded & 2) diff += step >> 1; 00122 if (encoded & 1) diff += step >> 2; 00123 if ((encoded >> 1) & step & 0x1) 00124 diff++; 00125 #endif 00126 if (sign) 00127 diff = -diff; 00128 00129 if (state->next_flag & 0x1) 00130 state->signal -= 8; 00131 else if (state->next_flag & 0x2) 00132 state->signal += 8; 00133 00134 state->signal += diff; 00135 00136 if (state->signal > 2047) 00137 state->signal = 2047; 00138 else if (state->signal < -2047) 00139 state->signal = -2047; 00140 00141 state->next_flag = 0; 00142 00143 #ifdef AUTO_RETURN 00144 if (encoded) 00145 state->zero_count = 0; 00146 else if (++(state->zero_count) == 24) 00147 { 00148 state->zero_count = 0; 00149 if (state->signal > 0) 00150 state->next_flag = 0x1; 00151 else if (state->signal < 0) 00152 state->next_flag = 0x2; 00153 } 00154 #endif 00155 00156 state->ssindex += indsft[encoded]; 00157 if (state->ssindex < 0) 00158 state->ssindex = 0; 00159 else if (state->ssindex > 48) 00160 state->ssindex = 48; 00161 00162 return state->signal << 4; 00163 }
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 638 of file codec_adpcm.c.
References tdesc.
00639 { 00640 return tdesc; 00641 }
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 652 of file codec_adpcm.c.
References ASTERISK_GPL_KEY.
00653 { 00654 return ASTERISK_GPL_KEY; 00655 }
static int lintoadpcm_framein | ( | struct ast_translator_pvt * | pvt, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 409 of file codec_adpcm.c.
References ast_log(), ast_frame::data, ast_frame::datalen, adpcm_encoder_pvt::f, adpcm_encoder_pvt::inbuf, LOG_WARNING, and adpcm_encoder_pvt::tail.
00410 { 00411 struct adpcm_encoder_pvt *tmp = (struct adpcm_encoder_pvt *) pvt; 00412 00413 if ((tmp->tail + f->datalen / 2) < (sizeof (tmp->inbuf) / 2)) 00414 { 00415 memcpy (&tmp->inbuf[tmp->tail], f->data, f->datalen); 00416 tmp->tail += f->datalen / 2; 00417 } 00418 else 00419 { 00420 ast_log (LOG_WARNING, "Out of buffer space\n"); 00421 return -1; 00422 } 00423 return 0; 00424 }
static struct ast_frame* lintoadpcm_frameout | ( | struct ast_translator_pvt * | pvt | ) | [static] |
Definition at line 439 of file codec_adpcm.c.
References adpcm(), AST_FORMAT_ADPCM, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_frame::data, ast_frame::datalen, adpcm_encoder_pvt::f, ast_frame::frametype, adpcm_encoder_pvt::inbuf, ast_frame::mallocd, ast_frame::offset, adpcm_encoder_pvt::outbuf, ast_frame::samples, ast_frame::src, adpcm_encoder_pvt::state, ast_frame::subclass, and adpcm_encoder_pvt::tail.
00440 { 00441 struct adpcm_encoder_pvt *tmp = (struct adpcm_encoder_pvt *) pvt; 00442 int i_max, i; 00443 00444 if (tmp->tail < 2) return NULL; 00445 00446 00447 i_max = tmp->tail & ~1; /* atomic size is 2 samples */ 00448 00449 /* What is this, state debugging? should be #ifdef'd then 00450 tmp->outbuf[0] = tmp->ssindex & 0xff; 00451 tmp->outbuf[1] = (tmp->signal >> 8) & 0xff; 00452 tmp->outbuf[2] = (tmp->signal & 0xff); 00453 tmp->outbuf[3] = tmp->zero_count; 00454 tmp->outbuf[4] = tmp->next_flag; 00455 */ 00456 for (i = 0; i < i_max; i+=2) 00457 { 00458 tmp->outbuf[i/2] = 00459 (adpcm(tmp->inbuf[i ], &tmp->state) << 4) | 00460 (adpcm(tmp->inbuf[i+1], &tmp->state) ); 00461 }; 00462 00463 00464 tmp->f.frametype = AST_FRAME_VOICE; 00465 tmp->f.subclass = AST_FORMAT_ADPCM; 00466 tmp->f.samples = i_max; 00467 tmp->f.mallocd = 0; 00468 tmp->f.offset = AST_FRIENDLY_OFFSET; 00469 tmp->f.src = __PRETTY_FUNCTION__; 00470 tmp->f.data = tmp->outbuf; 00471 tmp->f.datalen = i_max / 2; 00472 00473 /* 00474 * If there is a signal left over (there should be no more than 00475 * one) move it to the beginning of the input buffer. 00476 */ 00477 00478 if (tmp->tail == i_max) 00479 tmp->tail = 0; 00480 else 00481 { 00482 tmp->inbuf[0] = tmp->inbuf[tmp->tail]; 00483 tmp->tail = 1; 00484 } 00485 return &tmp->f; 00486 }
static struct ast_translator_pvt* lintoadpcm_new | ( | void | ) | [static] |
Definition at line 303 of file codec_adpcm.c.
References ast_update_use_count(), and malloc.
00304 { 00305 struct adpcm_encoder_pvt *tmp; 00306 tmp = malloc (sizeof (struct adpcm_encoder_pvt)); 00307 if (tmp) 00308 { 00309 memset(tmp, 0, sizeof(*tmp)); 00310 localusecnt++; 00311 ast_update_use_count (); 00312 tmp->tail = 0; 00313 } 00314 return (struct ast_translator_pvt *) tmp; 00315 }
static struct ast_frame* lintoadpcm_sample | ( | void | ) | [static] |
Definition at line 513 of file codec_adpcm.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_adpcm_ex, ast_frame::src, and ast_frame::subclass.
00514 { 00515 static struct ast_frame f; 00516 f.frametype = AST_FRAME_VOICE; 00517 f.subclass = AST_FORMAT_SLINEAR; 00518 f.datalen = sizeof (slin_adpcm_ex); 00519 /* Assume 8000 Hz */ 00520 f.samples = sizeof (slin_adpcm_ex) / 2; 00521 f.mallocd = 0; 00522 f.offset = 0; 00523 f.src = __PRETTY_FUNCTION__; 00524 f.data = slin_adpcm_ex; 00525 return &f; 00526 }
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 621 of file codec_adpcm.c.
References adpcmtolin, ast_register_translator(), ast_unregister_translator(), lintoadpcm, and parse_config().
00622 { 00623 int res; 00624 parse_config(); 00625 res = ast_register_translator (&adpcmtolin); 00626 if (!res) 00627 res = ast_register_translator (&lintoadpcm); 00628 else 00629 ast_unregister_translator (&adpcmtolin); 00630 return res; 00631 }
static void parse_config | ( | void | ) | [static] |
Definition at line 580 of file codec_adpcm.c.
References ast_config_destroy(), ast_config_load(), ast_true(), ast_variable_browse(), ast_verbose(), cfg, option_verbose, useplc, var, and VERBOSE_PREFIX_3.
Referenced by load_module(), and reload().
00581 { 00582 struct ast_config *cfg; 00583 struct ast_variable *var; 00584 if ((cfg = ast_config_load("codecs.conf"))) { 00585 if ((var = ast_variable_browse(cfg, "plc"))) { 00586 while (var) { 00587 if (!strcasecmp(var->name, "genericplc")) { 00588 useplc = ast_true(var->value) ? 1 : 0; 00589 if (option_verbose > 2) 00590 ast_verbose(VERBOSE_PREFIX_3 "codec_adpcm: %susing generic PLC\n", useplc ? "" : "not "); 00591 } 00592 var = var->next; 00593 } 00594 } 00595 ast_config_destroy(cfg); 00596 } 00597 }
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 600 of file codec_adpcm.c.
References parse_config().
00601 { 00602 parse_config(); 00603 return 0; 00604 }
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 607 of file codec_adpcm.c.
References adpcmtolin, ast_mutex_lock(), ast_mutex_unlock(), ast_unregister_translator(), lintoadpcm, and localusecnt.
00608 { 00609 int res; 00610 ast_mutex_lock (&localuser_lock); 00611 res = ast_unregister_translator (&lintoadpcm); 00612 if (!res) 00613 res = ast_unregister_translator (&adpcmtolin); 00614 if (localusecnt) 00615 res = -1; 00616 ast_mutex_unlock (&localuser_lock); 00617 return res; 00618 }
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 644 of file codec_adpcm.c.
References STANDARD_USECOUNT.
00645 { 00646 int res; 00647 STANDARD_USECOUNT (res); 00648 return res; 00649 }
struct ast_translator adpcmtolin [static] |
int indsft[8] = { -1, -1, -1, -1, 2, 4, 6, 8 } [static] |
Definition at line 70 of file codec_adpcm.c.
struct ast_translator lintoadpcm [static] |
int localusecnt = 0 [static] |
Definition at line 55 of file codec_adpcm.c.
int stpsz[49] [static] |
Definition at line 76 of file codec_adpcm.c.
char* tdesc = "Adaptive Differential PCM Coder/Decoder" [static] |
Definition at line 57 of file codec_adpcm.c.
int useplc = 0 [static] |