diff options
Diffstat (limited to 'codecs/codec_adpcm.c')
-rw-r--r-- | codecs/codec_adpcm.c | 504 |
1 files changed, 237 insertions, 267 deletions
diff --git a/codecs/codec_adpcm.c b/codecs/codec_adpcm.c index 187c42442..e62755074 100644 --- a/codecs/codec_adpcm.c +++ b/codecs/codec_adpcm.c @@ -102,8 +102,7 @@ struct adpcm_state { * Sets the index to the step size table for the next encode. */ -static inline short -decode(int encoded, struct adpcm_state* state) +static inline short decode(int encoded, struct adpcm_state *state) { int diff; int step; @@ -117,9 +116,12 @@ decode(int encoded, struct adpcm_state* state) diff = (((encoded << 1) + 1) * step) >> 3; #else /* BLI code */ diff = step >> 3; - if (encoded & 4) diff += step; - if (encoded & 2) diff += step >> 1; - if (encoded & 1) diff += step >> 2; + if (encoded & 4) + diff += step; + if (encoded & 2) + diff += step >> 1; + if (encoded & 1) + diff += step >> 2; if ((encoded >> 1) & step & 0x1) diff++; #endif @@ -143,8 +145,7 @@ decode(int encoded, struct adpcm_state* state) #ifdef AUTO_RETURN if (encoded) state->zero_count = 0; - else if (++(state->zero_count) == 24) - { + else if (++(state->zero_count) == 24) { state->zero_count = 0; if (state->signal > 0) state->next_flag = 0x1; @@ -174,51 +175,43 @@ decode(int encoded, struct adpcm_state* state) * signal gets updated with each pass. */ -static inline int -adpcm(short csig, struct adpcm_state* state) +static inline int adpcm(short csig, struct adpcm_state *state) { int diff; int step; int encoded; /* - * Clip csig if too large or too small - */ + * Clip csig if too large or too small + */ csig >>= 4; step = stpsz[state->ssindex]; diff = csig - state->signal; #ifdef NOT_BLI - if (diff < 0) - { + if (diff < 0) { encoded = (-diff << 2) / step; if (encoded > 7) encoded = 7; encoded |= 0x08; - } - else - { + } else { encoded = (diff << 2) / step; if (encoded > 7) encoded = 7; } #else /* BLI code */ - if (diff < 0) - { + if (diff < 0) { encoded = 8; diff = -diff; - } - else + } else encoded = 0; - if (diff >= step) - { + if (diff >= step) { encoded |= 4; diff -= step; } step >>= 1; - if (diff >= step) - { + if (diff >= step) { encoded |= 2; diff -= step; } @@ -239,12 +232,12 @@ adpcm(short csig, struct adpcm_state* state) struct adpcm_encoder_pvt { - struct ast_frame f; - char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */ - short inbuf[BUFFER_SIZE]; /* Unencoded signed linear values */ - unsigned char outbuf[BUFFER_SIZE]; /* Encoded ADPCM, two nibbles to a word */ - struct adpcm_state state; - int tail; + struct ast_frame f; + char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */ + short inbuf[BUFFER_SIZE]; /* Unencoded signed linear values */ + unsigned char outbuf[BUFFER_SIZE]; /* Encoded ADPCM, two nibbles to a word */ + struct adpcm_state state; + int tail; }; /* @@ -253,12 +246,12 @@ struct adpcm_encoder_pvt struct adpcm_decoder_pvt { - struct ast_frame f; - char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */ - short outbuf[BUFFER_SIZE]; /* Decoded signed linear values */ - struct adpcm_state state; - int tail; - plc_state_t plc; + struct ast_frame f; + char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */ + short outbuf[BUFFER_SIZE]; /* Decoded signed linear values */ + struct adpcm_state state; + int tail; + plc_state_t plc; }; /* @@ -272,20 +265,18 @@ struct adpcm_decoder_pvt * None. */ -static struct ast_translator_pvt * -adpcmtolin_new (void) +static struct ast_translator_pvt *adpcmtolin_new(void) { - struct adpcm_decoder_pvt *tmp; - tmp = malloc (sizeof (struct adpcm_decoder_pvt)); - if (tmp) - { - memset(tmp, 0, sizeof(*tmp)); - tmp->tail = 0; - plc_init(&tmp->plc); - localusecnt++; - ast_update_use_count (); - } - return (struct ast_translator_pvt *) tmp; + struct adpcm_decoder_pvt *tmp; + tmp = malloc(sizeof(struct adpcm_decoder_pvt)); + if (tmp) { + memset(tmp, 0, sizeof(*tmp)); + tmp->tail = 0; + plc_init(&tmp->plc); + localusecnt++; + ast_update_use_count(); + } + return (struct ast_translator_pvt *)tmp; } /* @@ -299,19 +290,17 @@ adpcmtolin_new (void) * None. */ -static struct ast_translator_pvt * -lintoadpcm_new (void) +static struct ast_translator_pvt *lintoadpcm_new(void) { - struct adpcm_encoder_pvt *tmp; - tmp = malloc (sizeof (struct adpcm_encoder_pvt)); - if (tmp) - { - memset(tmp, 0, sizeof(*tmp)); - localusecnt++; - ast_update_use_count (); - tmp->tail = 0; - } - return (struct ast_translator_pvt *) tmp; + struct adpcm_encoder_pvt *tmp; + tmp = malloc(sizeof(struct adpcm_encoder_pvt)); + if (tmp) { + memset(tmp, 0, sizeof(*tmp)); + localusecnt++; + ast_update_use_count(); + tmp->tail = 0; + } + return (struct ast_translator_pvt *)tmp; } /* @@ -326,40 +315,40 @@ lintoadpcm_new (void) * tmp->tail is the number of packed values in the buffer. */ -static int -adpcmtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) +static int adpcmtolin_framein(struct ast_translator_pvt *pvt, struct ast_frame *f) { - struct adpcm_decoder_pvt *tmp = (struct adpcm_decoder_pvt *) pvt; - int x; - unsigned char *b; - - if(f->datalen == 0) { /* perform PLC with nominal framesize of 20ms/160 samples */ - if((tmp->tail + 160) > sizeof(tmp->outbuf) / 2) { - ast_log(LOG_WARNING, "Out of buffer space\n"); - return -1; - } - if(useplc) { - plc_fillin(&tmp->plc, tmp->outbuf+tmp->tail, 160); - tmp->tail += 160; + struct adpcm_decoder_pvt *tmp = (struct adpcm_decoder_pvt *)pvt; + int x; + unsigned char *b; + + if(f->datalen == 0) { /* perform PLC with nominal framesize of 20ms/160 samples */ + if((tmp->tail + 160) > sizeof(tmp->outbuf) / 2) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + if(useplc) { + plc_fillin(&tmp->plc, tmp->outbuf+tmp->tail, 160); + tmp->tail += 160; + } + return 0; } - return 0; - } - if (f->datalen * 4 + tmp->tail * 2 > sizeof(tmp->outbuf)) { - ast_log(LOG_WARNING, "Out of buffer space\n"); - return -1; - } + if (f->datalen * 4 + tmp->tail * 2 > sizeof(tmp->outbuf)) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } - b = f->data; + b = f->data; - for (x=0;x<f->datalen;x++) { - tmp->outbuf[tmp->tail++] = decode((b[x] >> 4) & 0xf, &tmp->state); - tmp->outbuf[tmp->tail++] = decode(b[x] & 0x0f, &tmp->state); - } + for (x=0;x<f->datalen;x++) { + tmp->outbuf[tmp->tail++] = decode((b[x] >> 4) & 0xf, &tmp->state); + tmp->outbuf[tmp->tail++] = decode(b[x] & 0x0f, &tmp->state); + } - if(useplc) plc_rx(&tmp->plc, tmp->outbuf+tmp->tail-f->datalen*2, f->datalen*2); + if(useplc) + plc_rx(&tmp->plc, tmp->outbuf+tmp->tail-f->datalen*2, f->datalen*2); - return 0; + return 0; } /* @@ -374,24 +363,23 @@ adpcmtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) * None. */ -static struct ast_frame * -adpcmtolin_frameout (struct ast_translator_pvt *pvt) +static struct ast_frame *adpcmtolin_frameout(struct ast_translator_pvt *pvt) { - struct adpcm_decoder_pvt *tmp = (struct adpcm_decoder_pvt *) pvt; - - if (!tmp->tail) - return NULL; - - tmp->f.frametype = AST_FRAME_VOICE; - tmp->f.subclass = AST_FORMAT_SLINEAR; - tmp->f.datalen = tmp->tail *2; - tmp->f.samples = tmp->tail; - tmp->f.mallocd = 0; - tmp->f.offset = AST_FRIENDLY_OFFSET; - tmp->f.src = __PRETTY_FUNCTION__; - tmp->f.data = tmp->outbuf; - tmp->tail = 0; - return &tmp->f; + struct adpcm_decoder_pvt *tmp = (struct adpcm_decoder_pvt *)pvt; + + if (!tmp->tail) + return NULL; + + tmp->f.frametype = AST_FRAME_VOICE; + tmp->f.subclass = AST_FORMAT_SLINEAR; + tmp->f.datalen = tmp->tail * 2; + tmp->f.samples = tmp->tail; + tmp->f.mallocd = 0; + tmp->f.offset = AST_FRIENDLY_OFFSET; + tmp->f.src = __PRETTY_FUNCTION__; + tmp->f.data = tmp->outbuf; + tmp->tail = 0; + return &tmp->f; } /* @@ -405,22 +393,18 @@ adpcmtolin_frameout (struct ast_translator_pvt *pvt) * tmp->tail is number of signal values in the input buffer. */ -static int -lintoadpcm_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) +static int lintoadpcm_framein(struct ast_translator_pvt *pvt, struct ast_frame *f) { - struct adpcm_encoder_pvt *tmp = (struct adpcm_encoder_pvt *) pvt; - - if ((tmp->tail + f->datalen / 2) < (sizeof (tmp->inbuf) / 2)) - { - memcpy (&tmp->inbuf[tmp->tail], f->data, f->datalen); - tmp->tail += f->datalen / 2; - } - else - { - ast_log (LOG_WARNING, "Out of buffer space\n"); - return -1; - } - return 0; + struct adpcm_encoder_pvt *tmp = (struct adpcm_encoder_pvt *)pvt; + + if ((tmp->tail + f->datalen / 2) < (sizeof(tmp->inbuf) / 2)) { + memcpy(&tmp->inbuf[tmp->tail], f->data, f->datalen); + tmp->tail += f->datalen / 2; + } else { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + return 0; } /* @@ -435,54 +419,50 @@ lintoadpcm_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) * Leftover inbuf data gets packed, tail gets updated. */ -static struct ast_frame * -lintoadpcm_frameout (struct ast_translator_pvt *pvt) +static struct ast_frame *lintoadpcm_frameout(struct ast_translator_pvt *pvt) { - struct adpcm_encoder_pvt *tmp = (struct adpcm_encoder_pvt *) pvt; - int i_max, i; + struct adpcm_encoder_pvt *tmp = (struct adpcm_encoder_pvt *)pvt; + int i_max, i; - if (tmp->tail < 2) return NULL; - - - i_max = tmp->tail & ~1; /* atomic size is 2 samples */ - - /* What is this, state debugging? should be #ifdef'd then - tmp->outbuf[0] = tmp->ssindex & 0xff; - tmp->outbuf[1] = (tmp->signal >> 8) & 0xff; - tmp->outbuf[2] = (tmp->signal & 0xff); - tmp->outbuf[3] = tmp->zero_count; - tmp->outbuf[4] = tmp->next_flag; - */ - for (i = 0; i < i_max; i+=2) - { - tmp->outbuf[i/2] = - (adpcm(tmp->inbuf[i ], &tmp->state) << 4) | - (adpcm(tmp->inbuf[i+1], &tmp->state) ); - }; - - - tmp->f.frametype = AST_FRAME_VOICE; - tmp->f.subclass = AST_FORMAT_ADPCM; - tmp->f.samples = i_max; - tmp->f.mallocd = 0; - tmp->f.offset = AST_FRIENDLY_OFFSET; - tmp->f.src = __PRETTY_FUNCTION__; - tmp->f.data = tmp->outbuf; - tmp->f.datalen = i_max / 2; - - /* - * If there is a signal left over (there should be no more than - * one) move it to the beginning of the input buffer. - */ - - if (tmp->tail == i_max) - tmp->tail = 0; - else - { - tmp->inbuf[0] = tmp->inbuf[tmp->tail]; - tmp->tail = 1; - } - return &tmp->f; + if (tmp->tail < 2) + return NULL; + + i_max = tmp->tail & ~1; /* atomic size is 2 samples */ + + /* What is this, state debugging? should be #ifdef'd then + tmp->outbuf[0] = tmp->ssindex & 0xff; + tmp->outbuf[1] = (tmp->signal >> 8) & 0xff; + tmp->outbuf[2] = (tmp->signal & 0xff); + tmp->outbuf[3] = tmp->zero_count; + tmp->outbuf[4] = tmp->next_flag; + */ + for (i = 0; i < i_max; i+=2) { + tmp->outbuf[i/2] = + (adpcm(tmp->inbuf[i ], &tmp->state) << 4) | + (adpcm(tmp->inbuf[i+1], &tmp->state) ); + }; + + tmp->f.frametype = AST_FRAME_VOICE; + tmp->f.subclass = AST_FORMAT_ADPCM; + tmp->f.samples = i_max; + tmp->f.mallocd = 0; + tmp->f.offset = AST_FRIENDLY_OFFSET; + tmp->f.src = __PRETTY_FUNCTION__; + tmp->f.data = tmp->outbuf; + tmp->f.datalen = i_max / 2; + + /* + * If there is a signal left over (there should be no more than + * one) move it to the beginning of the input buffer. + */ + + if (tmp->tail == i_max) + tmp->tail = 0; + else { + tmp->inbuf[0] = tmp->inbuf[tmp->tail]; + tmp->tail = 1; + } + return &tmp->f; } @@ -490,39 +470,37 @@ lintoadpcm_frameout (struct ast_translator_pvt *pvt) * AdpcmToLin_Sample */ -static struct ast_frame * -adpcmtolin_sample (void) +static struct ast_frame *adpcmtolin_sample(void) { - static struct ast_frame f; - f.frametype = AST_FRAME_VOICE; - f.subclass = AST_FORMAT_ADPCM; - f.datalen = sizeof (adpcm_slin_ex); - f.samples = sizeof(adpcm_slin_ex) * 2; - f.mallocd = 0; - f.offset = 0; - f.src = __PRETTY_FUNCTION__; - f.data = adpcm_slin_ex; - return &f; + static struct ast_frame f; + f.frametype = AST_FRAME_VOICE; + f.subclass = AST_FORMAT_ADPCM; + f.datalen = sizeof(adpcm_slin_ex); + f.samples = sizeof(adpcm_slin_ex) * 2; + f.mallocd = 0; + f.offset = 0; + f.src = __PRETTY_FUNCTION__; + f.data = adpcm_slin_ex; + return &f; } /* * LinToAdpcm_Sample */ -static struct ast_frame * -lintoadpcm_sample (void) +static struct ast_frame *lintoadpcm_sample(void) { - static struct ast_frame f; - f.frametype = AST_FRAME_VOICE; - f.subclass = AST_FORMAT_SLINEAR; - f.datalen = sizeof (slin_adpcm_ex); - /* Assume 8000 Hz */ - f.samples = sizeof (slin_adpcm_ex) / 2; - f.mallocd = 0; - f.offset = 0; - f.src = __PRETTY_FUNCTION__; - f.data = slin_adpcm_ex; - return &f; + static struct ast_frame f; + f.frametype = AST_FRAME_VOICE; + f.subclass = AST_FORMAT_SLINEAR; + f.datalen = sizeof(slin_adpcm_ex); + /* Assume 8000 Hz */ + f.samples = sizeof(slin_adpcm_ex) / 2; + f.mallocd = 0; + f.offset = 0; + f.src = __PRETTY_FUNCTION__; + f.data = slin_adpcm_ex; + return &f; } /* @@ -536,12 +514,11 @@ lintoadpcm_sample (void) * None. */ -static void -adpcm_destroy (struct ast_translator_pvt *pvt) +static void adpcm_destroy(struct ast_translator_pvt *pvt) { - free (pvt); - localusecnt--; - ast_update_use_count (); + free(pvt); + localusecnt--; + ast_update_use_count(); } /* @@ -549,15 +526,15 @@ adpcm_destroy (struct ast_translator_pvt *pvt) */ static struct ast_translator adpcmtolin = { - "adpcmtolin", - AST_FORMAT_ADPCM, - AST_FORMAT_SLINEAR, - adpcmtolin_new, - adpcmtolin_framein, - adpcmtolin_frameout, - adpcm_destroy, - /* NULL */ - adpcmtolin_sample + "adpcmtolin", + AST_FORMAT_ADPCM, + AST_FORMAT_SLINEAR, + adpcmtolin_new, + adpcmtolin_framein, + adpcmtolin_frameout, + adpcm_destroy, + /* NULL */ + adpcmtolin_sample }; /* @@ -565,91 +542,84 @@ static struct ast_translator adpcmtolin = { */ static struct ast_translator lintoadpcm = { - "lintoadpcm", - AST_FORMAT_SLINEAR, - AST_FORMAT_ADPCM, - lintoadpcm_new, - lintoadpcm_framein, - lintoadpcm_frameout, - adpcm_destroy, - /* NULL */ - lintoadpcm_sample + "lintoadpcm", + AST_FORMAT_SLINEAR, + AST_FORMAT_ADPCM, + lintoadpcm_new, + lintoadpcm_framein, + lintoadpcm_frameout, + adpcm_destroy, + /* NULL */ + lintoadpcm_sample }; -static void -parse_config(void) +static void parse_config(void) { - struct ast_config *cfg; - struct ast_variable *var; - if ((cfg = ast_config_load("codecs.conf"))) { - if ((var = ast_variable_browse(cfg, "plc"))) { - while (var) { - if (!strcasecmp(var->name, "genericplc")) { - useplc = ast_true(var->value) ? 1 : 0; - if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "codec_adpcm: %susing generic PLC\n", useplc ? "" : "not "); - } - var = var->next; - } - } - ast_config_destroy(cfg); - } + struct ast_config *cfg; + struct ast_variable *var; + if ((cfg = ast_config_load("codecs.conf"))) { + if ((var = ast_variable_browse(cfg, "plc"))) { + while (var) { + if (!strcasecmp(var->name, "genericplc")) { + useplc = ast_true(var->value) ? 1 : 0; + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "codec_adpcm: %susing generic PLC\n", useplc ? "" : "not "); + } + var = var->next; + } + } + ast_config_destroy(cfg); + } } -int -reload(void) +int reload(void) { - parse_config(); - return 0; + parse_config(); + return 0; } -int -unload_module (void) +int unload_module(void) { - int res; - ast_mutex_lock (&localuser_lock); - res = ast_unregister_translator (&lintoadpcm); - if (!res) - res = ast_unregister_translator (&adpcmtolin); - if (localusecnt) - res = -1; - ast_mutex_unlock (&localuser_lock); - return res; + int res; + ast_mutex_lock(&localuser_lock); + res = ast_unregister_translator(&lintoadpcm); + if (!res) + res = ast_unregister_translator(&adpcmtolin); + if (localusecnt) + res = -1; + ast_mutex_unlock(&localuser_lock); + return res; } -int -load_module (void) +int load_module(void) { - int res; - parse_config(); - res = ast_register_translator (&adpcmtolin); - if (!res) - res = ast_register_translator (&lintoadpcm); - else - ast_unregister_translator (&adpcmtolin); - return res; + int res; + parse_config(); + res = ast_register_translator(&adpcmtolin); + if (!res) + res = ast_register_translator(&lintoadpcm); + else + ast_unregister_translator(&adpcmtolin); + return res; } /* * Return a description of this module. */ -char * -description (void) +char *description(void) { - return tdesc; + return tdesc; } -int -usecount (void) +int usecount(void) { - int res; - STANDARD_USECOUNT (res); - return res; + int res; + STANDARD_USECOUNT(res); + return res; } -char * -key () +char *key() { - return ASTERISK_GPL_KEY; + return ASTERISK_GPL_KEY; } |