Thu May 24 14:21:10 2007

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 }

Generated on Thu May 24 14:21:10 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.7