Mon Mar 20 08:25:57 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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"

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)
void build_bits (unsigned char *c, INT32 *bits)
char * description (void)
 Provides a description of the module.
void extract_bits (INT32 *bits, unsigned char *c)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int lintolpc10_framein (struct ast_translator_pvt *tmp, struct ast_frame *f)
ast_framelintolpc10_frameout (struct ast_translator_pvt *tmp)
ast_framelintolpc10_sample (void)
int load_module (void)
 Initialize the module.
ast_translator_pvtlpc10_dec_new (void)
void lpc10_destroy (struct ast_translator_pvt *pvt)
ast_translator_pvtlpc10_enc_new (void)
int lpc10tolin_framein (struct ast_translator_pvt *tmp, struct ast_frame *f)
ast_framelpc10tolin_frameout (struct ast_translator_pvt *tmp)
ast_framelpc10tolin_sample (void)
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

ast_translator lintolpc10
int localusecnt = 0
ast_translator lpc10tolin
char * tdesc = "LPC10 2.4kbps (signed linear) Voice Coder"
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   ) 
 

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 }

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.

00429 {
00430    return ASTERISK_GPL_KEY;
00431 }

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 }

struct ast_frame* lintolpc10_frameout struct ast_translator_pvt tmp  )  [static]
 

Definition at line 279 of file codec_lpc10.c.

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

struct ast_frame* lintolpc10_sample void   )  [static]
 

Definition at line 120 of file codec_lpc10.c.

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

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.

Returns:
int Always 0.

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 }

struct ast_translator_pvt* lpc10_dec_new void   )  [static]
 

Definition at line 104 of file codec_lpc10.c.

References free, localusecnt, ast_translator_pvt::longer, lpc10_coder_pvt, malloc, plc_init(), and ast_translator_pvt::tail.

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 }

void lpc10_destroy struct ast_translator_pvt pvt  )  [static]
 

Definition at line 337 of file codec_lpc10.c.

References ast_translator_pvt::enc, free, localusecnt, 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 }

struct ast_translator_pvt* lpc10_enc_new void   )  [static]
 

Definition at line 88 of file codec_lpc10.c.

References free, localusecnt, ast_translator_pvt::longer, lpc10_coder_pvt, malloc, and ast_translator_pvt::tail.

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 }

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 }

struct ast_frame* lpc10tolin_frameout struct ast_translator_pvt tmp  )  [static]
 

Definition at line 151 of file codec_lpc10.c.

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

struct ast_frame* lpc10tolin_sample void   )  [static]
 

Definition at line 135 of file codec_lpc10.c.

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

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 }

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

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.

Referenced by load_module(), and unload_module().

int localusecnt = 0 [static]
 

Definition at line 63 of file codec_lpc10.c.

Referenced by lpc10_dec_new(), lpc10_destroy(), and lpc10_enc_new().

struct ast_translator lpc10tolin [static]
 

Definition at line 345 of file codec_lpc10.c.

Referenced by load_module(), and unload_module().

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.

Referenced by parse_config().


Generated on Mon Mar 20 08:25:58 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1