codec_alaw.c

00001 /*
00002  * iaxclient: a cross-platform IAX softphone library
00003  *
00004  * Copyrights:
00005  * Copyright (C) 2004 Cyril VELTER
00006  *
00007  * Contributors:
00008  * Cyril VELTER <cyril.velter@metadys.com>
00009  *
00010  * This program is free software, distributed under the terms of
00011  * the GNU Lesser (Library) General Public License.
00012  */
00013 
00014 #include "codec_alaw.h"
00015 #include "iaxclient_lib.h"
00016 
00017 #if defined(_MSC_VER)
00018 #define INLINE __inline
00019 #else
00020 #define INLINE inline
00021 #endif
00022 
00023 struct state {
00024     plc_state_t plc;
00025 };
00026 
00027 static INLINE short int alawdecode (unsigned char alaw)
00028 {
00029         int value;
00030         int segment;
00031 
00032         /* Mask value */
00033         alaw ^= 0x55;
00034 
00035         /* Extract and scale value */
00036         value = (alaw & 0x0f) << 4;
00037 
00038         /* Extract segment number */
00039         segment = (alaw & 0x70) >> 4;
00040 
00041         /* Compute value */
00042         switch (segment) {
00043                 case 0:
00044                         break;
00045                 case 1:
00046                         value += 0x100;
00047                         break;
00048                 default:
00049                         value += 0x100;
00050                         value <<= segment - 1;
00051         }
00052 
00053         /* Extract sign */
00054         return (alaw & 0x80) ? value : -value;
00055 }
00056 
00057 static INLINE unsigned char alawencode (short int linear)
00058 {
00059         int mask = 0x55;
00060         int segment;
00061         unsigned char alaw;
00062 
00063         static int segments[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
00064 
00065         if (linear >= 0)
00066         {
00067           /* Sign (7th) bit = 1 */
00068           mask |= 0x80;
00069         }
00070         else
00071         {
00072           /* Sign (7th) bit = 0 */
00073           linear = -linear;
00074         }
00075 
00076         /* Find the segment */
00077         for (segment = 0;segment < 8;segment++)
00078                 if (linear <= segments[segment])
00079                         break;
00080 
00081         /* Combine the sign, segment, and quantization bits. */
00082 
00083         if (segment < 8)
00084         {
00085                 if (segment < 2)
00086                         alaw = (linear >> 4) & 0x0F;
00087                 else
00088                         alaw = (linear >> (segment + 3)) & 0x0F;
00089 
00090                 return ((alaw | (segment << 4)) ^ mask);
00091         }
00092         else
00093                 /* out of range, return maximum value. */
00094                 return (0x7F ^ mask);
00095 }
00096 
00097 static int decode ( struct iaxc_audio_codec *c,
00098     int *inlen, unsigned char *in, int *outlen, short *out ) {
00099     struct state *state = (struct state *)(c->decstate);
00100     short *orig_out = out;
00101     short sample;
00102 
00103 
00104     if(*inlen == 0) {
00105         int interp_len = 160;
00106         if(*outlen < interp_len) interp_len = *outlen;
00107         plc_fillin(&state->plc,out,interp_len);
00108         *outlen -= interp_len;
00109         return 0;
00110     }
00111 
00112 
00113     while ((*inlen > 0) && (*outlen > 0)) {
00114         sample = alawdecode((unsigned char)*(in++));
00115         *(out++) = sample;
00116         (*inlen)--; (*outlen)--;
00117     }
00118     plc_rx(&state->plc, orig_out, (int)(out - orig_out));
00119 
00120     return 0;
00121 }
00122 
00123 static int encode ( struct iaxc_audio_codec *c,
00124     int *inlen, short *in, int *outlen, unsigned char *out ) {
00125 
00126     while ((*inlen > 0) && (*outlen > 0)) {
00127         *(out++) = alawencode(*(in++));
00128         (*inlen)--; (*outlen)--;
00129     }
00130 
00131     return 0;
00132 }
00133 
00134 static void destroy ( struct iaxc_audio_codec *c) {
00135     free(c);
00136 }
00137 
00138 struct iaxc_audio_codec *codec_audio_alaw_new() {
00139 
00140   struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(1, sizeof(struct iaxc_audio_codec));
00141 
00142   if(!c) return c;
00143 
00144   strcpy(c->name,"alaw");
00145   c->format = IAXC_FORMAT_ALAW;
00146   c->encode = encode;
00147   c->decode = decode;
00148   c->destroy = destroy;
00149 
00150   /* really, we can use less, but don't want to */
00151   c->minimum_frame_size = 160;
00152 
00153   /* decoder state, used for interpolation */
00154   c->decstate = calloc(sizeof(struct state),1);
00155   plc_init(&((struct state *)c->decstate)->plc);
00156 
00157   return c;
00158 }
00159 

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