Wed Oct 28 15:48:42 2009

Asterisk developer's documentation


codec_adpcm.c File Reference

codec_adpcm.c - translate between signed linear and Dialogic ADPCM More...

#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"

Include dependency graph for codec_adpcm.c:

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_frameadpcmtolin_frameout (struct ast_translator_pvt *pvt)
static struct ast_translator_pvtadpcmtolin_new (void)
static struct ast_frameadpcmtolin_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_framelintoadpcm_frameout (struct ast_translator_pvt *pvt)
static struct ast_translator_pvtlintoadpcm_new (void)
static struct ast_framelintoadpcm_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


Detailed Description

codec_adpcm.c - translate between signed linear and Dialogic ADPCM

Definition in file codec_adpcm.c.


Define Documentation

#define BUFFER_SIZE   8096

Definition at line 52 of file codec_adpcm.c.


Function Documentation

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(), and free.

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(), 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, read]

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, read]

Definition at line 276 of file codec_adpcm.c.

References ast_update_use_count(), malloc, adpcm_decoder_pvt::plc, plc_init(), and adpcm_decoder_pvt::tail.

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, read]

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.

Returns:
a short description of your module

Definition at line 638 of file codec_adpcm.c.

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;
 }

Returns:
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::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, read]

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, read]

Definition at line 303 of file codec_adpcm.c.

References ast_update_use_count(), malloc, and adpcm_encoder_pvt::tail.

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, read]

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.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.
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.

Returns:
int Always 0.
TE STUFF END

Definition at line 621 of file codec_adpcm.c.

References ast_register_translator(), ast_unregister_translator(), 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, ast_variable::name, ast_variable::next, option_verbose, ast_variable::value, 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.

Returns:
The return value is not used.

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).

Returns:
Zero on success, or non-zero on error.

Definition at line 607 of file codec_adpcm.c.

References ast_mutex_lock(), ast_mutex_unlock(), and ast_unregister_translator().

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.

Returns:
The module's usecount.

Definition at line 644 of file codec_adpcm.c.

References STANDARD_USECOUNT.

00645 {
00646   int res;
00647   STANDARD_USECOUNT (res);
00648   return res;
00649 }


Variable Documentation

struct ast_translator adpcmtolin [static]

Definition at line 551 of file codec_adpcm.c.

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]

Definition at line 567 of file codec_adpcm.c.

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]

Definition at line 59 of file codec_adpcm.c.


Generated on Wed Oct 28 15:48:42 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6