Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:43 2009

## Asterisk developer's documentation

# codec_lpc10.c File Reference

Translate between signed linear and LPC10 (Linear Predictor Code). More...

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

Include dependency graph for codec_lpc10.c:

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

## Detailed Description

Translate between signed linear and LPC10 (Linear Predictor Code).

Definition in file codec_lpc10.c.

## Define Documentation

#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

Definition at line 86 of file codec_lpc10.c.

Referenced by lpc10_dec_new(), and lpc10_enc_new().

## Function Documentation

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.

Returns:
  a short description of your 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;
     }

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

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

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.

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 404 of file codec_lpc10.c.

References ast_register_translator(), ast_unregister_translator(), 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, read]`

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

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

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

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, ast_variable::name, ast_variable::next, option_verbose, ast_variable::value, 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.

Returns:
  The return value is not used.

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

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

Definition at line 391 of file codec_lpc10.c.

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

    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.

Returns:
  The module's usecount.

Definition at line 421 of file codec_lpc10.c.

References STANDARD_USECOUNT.

    00422 {
    00423    int res;
    00424    STANDARD_USECOUNT(res);
    00425    return res;
    00426 }

## Variable Documentation

struct ast_translator lintolpc10`[static]`

Definition at line 355 of file codec_lpc10.c.

int localusecnt = 0`[static]`

Definition at line 63 of file codec_lpc10.c.

struct ast_translator lpc10tolin`[static]`

Definition at line 345 of file codec_lpc10.c.

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.