Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:53 2009

## Asterisk developer's documentation

# codec_a_mu.c

Go to the documentation of this file.

    00001 /*
    00002  * Asterisk -- An open source telephony toolkit.
    00003  *
    00004  * Copyright (C) 1999 - 2005, Digium, Inc.
    00005  *
    00006  * Mark Spencer <markster@digium.com>
    00007  *
    00008  * See http://www.asterisk.org for more information about
    00009  * the Asterisk project. Please do not directly contact
    00010  * any of the maintainers of this project for assistance;
    00011  * the project provides a web site, mailing lists and IRC
    00012  * channels for your use.
    00013  *
    00014  * This program is free software, distributed under the terms of
    00015  * the GNU General Public License Version 2. See the LICENSE file
    00016  * at the top of the source tree.
    00017  */
    00018
    00019 /*! \file
    00020  *
    00021  * \brief codec_a_mu.c - translate between alaw and ulaw directly
    00022  *
    00023  * \ingroup codecs
    00024  */
    00025
    00026 #include <fcntl.h>
    00027 #include <netinet/in.h>
    00028 #include <stdio.h>
    00029 #include <stdlib.h>
    00030 #include <string.h>
    00031 #include <unistd.h>
    00032
    00033 #include "asterisk.h"
    00034
    00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
    00036
    00037 #include "asterisk/lock.h"
    00038 #include "asterisk/logger.h"
    00039 #include "asterisk/module.h"
    00040 #include "asterisk/translate.h"
    00041 #include "asterisk/channel.h"
    00042 #include "asterisk/alaw.h"
    00043 #include "asterisk/ulaw.h"
    00044
    00045 #define BUFFER_SIZE   8096 /* size for the translation buffers */
    00046
    00047 AST_MUTEX_DEFINE_STATIC(localuser_lock);
    00048 static int localusecnt = 0;
    00049
    00050 static char *tdesc = "A-law and Mulaw direct Coder/Decoder";
    00051
    00052 static unsigned char mu2a[256];
    00053 static unsigned char a2mu[256];
    00054
    00055 /* Sample frame data (Mu data is okay) */
    00056
    00057 #include "ulaw_slin_ex.h"
    00058
    00059 /*
    00060  * Private workspace for translating signed linear signals to alaw.
    00061  */
    00062
    00063 struct alaw_encoder_pvt
    00064 {
    00065   struct ast_frame f;
    00066   char offset[AST_FRIENDLY_OFFSET];   /* Space to build offset */
    00067   unsigned char outbuf[BUFFER_SIZE];  /* Encoded alaw, two nibbles to a word */
    00068   int tail;
    00069 };
    00070
    00071 /*
    00072  * Private workspace for translating laws.
    00073  */
    00074
    00075 struct ulaw_encoder_pvt
    00076 {
    00077   struct ast_frame f;
    00078   char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */
    00079   unsigned char outbuf[BUFFER_SIZE];   /* Encoded ulaw values */
    00080   int tail;
    00081 };
    00082
    00083 static struct ast_translator_pvt *
    00084 alawtoulaw_new (void)
    00085 {
    00086   struct ulaw_encoder_pvt *tmp;
    00087   tmp = malloc (sizeof (struct ulaw_encoder_pvt));
    00088   if (tmp)
    00089     {
    00090      memset(tmp, 0, sizeof(*tmp));
    00091       tmp->tail = 0;
    00092       localusecnt++;
    00093       ast_update_use_count ();
    00094     }
    00095   return (struct ast_translator_pvt *) tmp;
    00096 }
    00097
    00098 static struct ast_translator_pvt *
    00099 ulawtoalaw_new (void)
    00100 {
    00101   struct alaw_encoder_pvt *tmp;
    00102   tmp = malloc (sizeof (struct alaw_encoder_pvt));
    00103   if (tmp)
    00104     {
    00105      memset(tmp, 0, sizeof(*tmp));
    00106       localusecnt++;
    00107       ast_update_use_count ();
    00108       tmp->tail = 0;
    00109     }
    00110   return (struct ast_translator_pvt *) tmp;
    00111 }
    00112
    00113 static int
    00114 alawtoulaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
    00115 {
    00116   struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
    00117   int x;
    00118   unsigned char *b;
    00119
    00120   if ((tmp->tail + f->datalen)> sizeof(tmp->outbuf)) {
    00121    ast_log(LOG_WARNING, "Out of buffer space\n");
    00122    return -1;
    00123   }
    00124
    00125   /* Reset ssindex and signal to frame's specified values */
    00126   b = f->data;
    00127   for (x=0;x<f->datalen;x++)
    00128    tmp->outbuf[tmp->tail + x] = a2mu[b[x]];
    00129
    00130   tmp->tail += f->datalen;
    00131   return 0;
    00132 }
    00133
    00134 static struct ast_frame *
    00135 alawtoulaw_frameout (struct ast_translator_pvt *pvt)
    00136 {
    00137   struct ulaw_encoder_pvt *tmp = (struct ulaw_encoder_pvt *) pvt;
    00138
    00139   if (!tmp->tail)
    00140     return NULL;
    00141
    00142   tmp->f.frametype = AST_FRAME_VOICE;
    00143   tmp->f.subclass = AST_FORMAT_ULAW;
    00144   tmp->f.datalen = tmp->tail;
    00145   tmp->f.samples = tmp->tail;
    00146   tmp->f.mallocd = 0;
    00147   tmp->f.offset = AST_FRIENDLY_OFFSET;
    00148   tmp->f.src = __PRETTY_FUNCTION__;
    00149   tmp->f.data = tmp->outbuf;
    00150   tmp->tail = 0;
    00151   return &tmp->f;
    00152 }
    00153
    00154 static int
    00155 ulawtoalaw_framein (struct ast_translator_pvt *pvt, struct ast_frame *f)
    00156 {
    00157   struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
    00158   int x;
    00159   unsigned char *s;
    00160   if (tmp->tail + f->datalen >= sizeof(tmp->outbuf))
    00161     {
    00162       ast_log (LOG_WARNING, "Out of buffer space\n");
    00163       return -1;
    00164     }
    00165   s = f->data;
    00166   for (x=0;x<f->datalen;x++)
    00167    tmp->outbuf[x+tmp->tail] = mu2a[s[x]];
    00168   tmp->tail += f->datalen;
    00169   return 0;
    00170 }
    00171
    00172 /*
    00173  * LinToalaw_FrameOut
    00174  *  Convert a buffer of raw 16-bit signed linear PCM to a buffer
    00175  *  of 4-bit alaw packed two to a byte (Big Endian).
    00176  *
    00177  * Results:
    00178  *  Foo
    00179  *
    00180  * Side effects:
    00181  *  Leftover inbuf data gets packed, tail gets updated.
    00182  */
    00183
    00184 static struct ast_frame *
    00185 ulawtoalaw_frameout (struct ast_translator_pvt *pvt)
    00186 {
    00187   struct alaw_encoder_pvt *tmp = (struct alaw_encoder_pvt *) pvt;
    00188
    00189   if (tmp->tail) {
    00190      tmp->f.frametype = AST_FRAME_VOICE;
    00191      tmp->f.subclass = AST_FORMAT_ALAW;
    00192      tmp->f.samples = tmp->tail;
    00193      tmp->f.mallocd = 0;
    00194      tmp->f.offset = AST_FRIENDLY_OFFSET;
    00195      tmp->f.src = __PRETTY_FUNCTION__;
    00196      tmp->f.data = tmp->outbuf;
    00197      tmp->f.datalen = tmp->tail;
    00198      tmp->tail = 0;
    00199      return &tmp->f;
    00200    } else return NULL;
    00201 }
    00202
    00203
    00204 /*
    00205  * alawToLin_Sample
    00206  */
    00207
    00208 static struct ast_frame *
    00209 alawtoulaw_sample (void)
    00210 {
    00211   static struct ast_frame f;
    00212   f.frametype = AST_FRAME_VOICE;
    00213   f.subclass = AST_FORMAT_ALAW;
    00214   f.datalen = sizeof (ulaw_slin_ex);
    00215   f.samples = sizeof(ulaw_slin_ex);
    00216   f.mallocd = 0;
    00217   f.offset = 0;
    00218   f.src = __PRETTY_FUNCTION__;
    00219   f.data = ulaw_slin_ex;
    00220   return &f;
    00221 }
    00222
    00223 static struct ast_frame *
    00224 ulawtoalaw_sample (void)
    00225 {
    00226   static struct ast_frame f;
    00227   f.frametype = AST_FRAME_VOICE;
    00228   f.subclass = AST_FORMAT_ULAW;
    00229   f.datalen = sizeof (ulaw_slin_ex);
    00230   f.samples = sizeof(ulaw_slin_ex);
    00231   f.mallocd = 0;
    00232   f.offset = 0;
    00233   f.src = __PRETTY_FUNCTION__;
    00234   f.data = ulaw_slin_ex;
    00235   return &f;
    00236 }
    00237
    00238
    00239 /*
    00240  * alaw_Destroy
    00241  *  Destroys a private workspace.
    00242  *
    00243  * Results:
    00244  *  It's gone!
    00245  *
    00246  * Side effects:
    00247  *  None.
    00248  */
    00249
    00250 static void
    00251 alaw_destroy (struct ast_translator_pvt *pvt)
    00252 {
    00253   free (pvt);
    00254   localusecnt--;
    00255   ast_update_use_count ();
    00256 }
    00257
    00258 /*
    00259  * The complete translator for alawToLin.
    00260  */
    00261
    00262 static struct ast_translator alawtoulaw = {
    00263   "alawtoulaw",
    00264   AST_FORMAT_ALAW,
    00265   AST_FORMAT_ULAW,
    00266   alawtoulaw_new,
    00267   alawtoulaw_framein,
    00268   alawtoulaw_frameout,
    00269   alaw_destroy,
    00270   /* NULL */
    00271   alawtoulaw_sample
    00272 };
    00273
    00274 /*
    00275  * The complete translator for LinToalaw.
    00276  */
    00277
    00278 static struct ast_translator ulawtoalaw = {
    00279   "ulawtoalaw",
    00280   AST_FORMAT_ULAW,
    00281   AST_FORMAT_ALAW,
    00282   ulawtoalaw_new,
    00283   ulawtoalaw_framein,
    00284   ulawtoalaw_frameout,
    00285   alaw_destroy,
    00286   /* NULL */
    00287   ulawtoalaw_sample
    00288 };
    00289
    00290 int
    00291 unload_module (void)
    00292 {
    00293   int res;
    00294   ast_mutex_lock (&localuser_lock);
    00295   res = ast_unregister_translator (&ulawtoalaw);
    00296   if (!res)
    00297     res = ast_unregister_translator (&alawtoulaw);
    00298   if (localusecnt)
    00299     res = -1;
    00300   ast_mutex_unlock (&localuser_lock);
    00301   return res;
    00302 }
    00303
    00304 int
    00305 load_module (void)
    00306 {
    00307   int res;
    00308   int x;
    00309   for (x=0;x<256;x++) {
    00310    mu2a[x] = AST_LIN2A(AST_MULAW(x));
    00311    a2mu[x] = AST_LIN2MU(AST_ALAW(x));
    00312   }
    00313   res = ast_register_translator (&alawtoulaw);
    00314   if (!res)
    00315     res = ast_register_translator (&ulawtoalaw);
    00316   else
    00317     ast_unregister_translator (&alawtoulaw);
    00318   return res;
    00319 }
    00320
    00321 /*
    00322  * Return a description of this module.
    00323  */
    00324
    00325 char *
    00326 description (void)
    00327 {
    00328   return tdesc;
    00329 }
    00330
    00331 int
    00332 usecount (void)
    00333 {
    00334   int res;
    00335   STANDARD_USECOUNT (res);
    00336   return res;
    00337 }
    00338
    00339 char *
    00340 key ()
    00341 {
    00342   return ASTERISK_GPL_KEY;
    00343 }