codec_ulaw.c

00001 /*
00002  * iaxclient: a cross-platform IAX softphone library
00003  *
00004  * Copyrights:
00005  * Copyright (C) 2003-2006, Horizon Wimba, Inc.
00006  * Copyright (C) 2007, Wimba, Inc.
00007  *
00008  * Contributors:
00009  * Steve Kann <stevek@stevek.com>
00010  *
00011  * This program is free software, distributed under the terms of
00012  * the GNU Lesser (Library) General Public License.
00013  */
00014 
00015 #include "codec_ulaw.h"
00016 #include "iaxclient_lib.h"
00017 
00018 struct state {
00019     plc_state_t plc;
00020 };
00021 
00022 static short ulaw_2lin [256];
00023 static unsigned char lin_2ulaw [16384];
00024 static int initialized=0;
00025 
00026 /* this looks similar to asterisk, but comes from public domain code by craig reese
00027    I've just followed asterisk's table sizes for lin_2u, and also too lazy to do binary arith to decide which
00028    iterations to skip -- this way we get the same result.. */
00029 static void initialize() {
00030     int i;
00031 
00032     /* ulaw_2lin */
00033     for(i=0;i<256;i++) {
00034           int b = ~i;
00035           int exp_lut[8] = {0,132,396,924,1980,4092,8316,16764};
00036           int sign, exponent, mantissa, sample;
00037 
00038           sign = (b & 0x80);
00039           exponent = (b >> 4) & 0x07;
00040           mantissa = b & 0x0F;
00041           sample = exp_lut[exponent] + (mantissa << (exponent + 3));
00042           if (sign != 0) sample = -sample;
00043           ulaw_2lin[i] = sample;
00044     }
00045 
00046     /* lin_2ulaw */
00047     for(i=-32767;i<32768;i+=4) {
00048         int sample = i;
00049         int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
00050                              4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
00051                              5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00052                              5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00053                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00054                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00055                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00056                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00057                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00058                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00059                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00060                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00061                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00062                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00063                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00064                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
00065         int sign, exponent, mantissa;
00066         unsigned char ulawbyte;
00067 
00068         /* Get the sample into sign-magnitude. */
00069         sign = (sample >> 8) & 0x80;            /* set aside the sign */
00070         if (sign != 0) sample = -sample;                /* get magnitude */
00071         if (sample > 32635) sample = 32635;             /* clip the magnitude */
00072 
00073         /* Convert from 16 bit linear to ulaw. */
00074         sample = sample + 0x84;
00075         exponent = exp_lut[(sample >> 7) & 0xFF];
00076         mantissa = (sample >> (exponent + 3)) & 0x0F;
00077         ulawbyte = ~(sign | (exponent << 4) | mantissa);
00078         if (ulawbyte == 0) ulawbyte = 0x02;     /* optional CCITT trap */
00079 
00080         lin_2ulaw[((unsigned short)i) >> 2] = ulawbyte;
00081     }
00082 
00083     initialized = 1;
00084 }
00085 
00086 static void destroy ( struct iaxc_audio_codec *c) {
00087     free(c);
00088 }
00089 
00090 
00091 static int decode ( struct iaxc_audio_codec *c,
00092     int *inlen, unsigned char *in, int *outlen, short *out ) {
00093     struct state *state = (struct state *)c->decstate;
00094     short *orig_out = out;
00095     short sample;
00096 
00097     if(*inlen == 0) {
00098         int interp_len = 160;
00099         if(*outlen < interp_len) interp_len = *outlen;
00100         plc_fillin(&state->plc,out,interp_len);
00101         *outlen -= interp_len;
00102         return 0;
00103     }
00104 
00105     while ((*inlen > 0) && (*outlen > 0)) {
00106         sample = ulaw_2lin[(unsigned char)*(in++)];
00107         *(out++) = sample;
00108         (*inlen)--; (*outlen)--;
00109     }
00110     plc_rx(&state->plc, orig_out, (int)(out - orig_out));
00111 
00112     return 0;
00113 }
00114 
00115 static int encode ( struct iaxc_audio_codec *c,
00116     int *inlen, short *in, int *outlen, unsigned char *out ) {
00117 
00118     while ((*inlen > 0) && (*outlen > 0)) {
00119         *(out++) = lin_2ulaw[((unsigned short)*(in++)) >> 2];
00120         (*inlen)--; (*outlen)--;
00121     }
00122 
00123     return 0;
00124 }
00125 
00126 
00127 struct iaxc_audio_codec *codec_audio_ulaw_new() {
00128 
00129   struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
00130 
00131   if(!c) return c;
00132 
00133   if(!initialized) initialize();
00134 
00135   strcpy(c->name,"ulaw");
00136   c->format = IAXC_FORMAT_ULAW;
00137   c->encode = encode;
00138   c->decode = decode;
00139   c->destroy = destroy;
00140 
00141   /* really, we can use less, but don't want to */
00142   c->minimum_frame_size = 160;
00143 
00144   /* decoder state, used for interpolation */
00145   c->decstate = calloc(sizeof(struct state),1);
00146   plc_init(&((struct state *)c->decstate)->plc);
00147 
00148   return c;
00149 }
00150 

Generated on Mon Sep 24 15:43:29 2007 for IAXClient by  doxygen 1.5.3