00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00027
00028
00029 static void initialize() {
00030 int i;
00031
00032
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
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
00069 sign = (sample >> 8) & 0x80;
00070 if (sign != 0) sample = -sample;
00071 if (sample > 32635) sample = 32635;
00072
00073
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;
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
00142 c->minimum_frame_size = 160;
00143
00144
00145 c->decstate = calloc(sizeof(struct state),1);
00146 plc_init(&((struct state *)c->decstate)->plc);
00147
00148 return c;
00149 }
00150