]> git.mxchange.org Git - flightgear.git/blob - 3rdparty/iaxclient/lib/codec_ulaw.c
VS2015 compatability fixes.
[flightgear.git] / 3rdparty / iaxclient / lib / codec_ulaw.c
1 /*
2  * iaxclient: a cross-platform IAX softphone library
3  *
4  * Copyrights:
5  * Copyright (C) 2003-2006, Horizon Wimba, Inc.
6  * Copyright (C) 2007, Wimba, Inc.
7  *
8  * Contributors:
9  * Steve Kann <stevek@stevek.com>
10  *
11  * This program is free software, distributed under the terms of
12  * the GNU Lesser (Library) General Public License.
13  */
14
15 #include "codec_ulaw.h"
16 #include "iaxclient_lib.h"
17
18 struct state {
19     plc_state_t plc;
20 };
21
22 static short ulaw_2lin [256];
23 static unsigned char lin_2ulaw [16384];
24 static int initialized=0;
25
26 /* this looks similar to asterisk, but comes from public domain code by craig reese
27    I've just followed asterisk's table sizes for lin_2u, and also too lazy to do binary arith to decide which
28    iterations to skip -- this way we get the same result.. */
29 static void initialize() {
30     int i;
31
32     /* ulaw_2lin */
33     for(i=0;i<256;i++) {
34           int b = ~i;
35           int exp_lut[8] = {0,132,396,924,1980,4092,8316,16764};
36           int sign, exponent, mantissa, sample;
37
38           sign = (b & 0x80);
39           exponent = (b >> 4) & 0x07;
40           mantissa = b & 0x0F;
41           sample = exp_lut[exponent] + (mantissa << (exponent + 3));
42           if (sign != 0) sample = -sample;
43           ulaw_2lin[i] = sample;
44     }
45
46     /* lin_2ulaw */
47     for(i=-32767;i<32768;i+=4) {
48         int sample = i;
49         int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
50                              4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
51                              5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
52                              5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
53                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
54                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
55                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
56                              6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
57                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
58                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
59                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
60                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
61                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
62                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
63                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
64                              7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
65         int sign, exponent, mantissa;
66         unsigned char ulawbyte;
67
68         /* Get the sample into sign-magnitude. */
69         sign = (sample >> 8) & 0x80;            /* set aside the sign */
70         if (sign != 0) sample = -sample;                /* get magnitude */
71         if (sample > 32635) sample = 32635;             /* clip the magnitude */
72
73         /* Convert from 16 bit linear to ulaw. */
74         sample = sample + 0x84;
75         exponent = exp_lut[(sample >> 7) & 0xFF];
76         mantissa = (sample >> (exponent + 3)) & 0x0F;
77         ulawbyte = ~(sign | (exponent << 4) | mantissa);
78         if (ulawbyte == 0) ulawbyte = 0x02;     /* optional CCITT trap */
79
80         lin_2ulaw[((unsigned short)i) >> 2] = ulawbyte;
81     }
82
83     initialized = 1;
84 }
85
86 static void destroy ( struct iaxc_audio_codec *c) {
87         if ( c->decstate )
88                 free(c->decstate);
89         free(c);
90 }
91
92
93 static int decode ( struct iaxc_audio_codec *c,
94     int *inlen, unsigned char *in, int *outlen, short *out ) {
95     struct state *state = (struct state *)c->decstate;
96     short *orig_out = out;
97     short sample;
98
99     if(*inlen == 0) {
100         int interp_len = 160;
101         if(*outlen < interp_len) interp_len = *outlen;
102         plc_fillin(&state->plc,out,interp_len);
103         *outlen -= interp_len;
104         return 0;
105     }
106
107     while ((*inlen > 0) && (*outlen > 0)) {
108         sample = ulaw_2lin[(unsigned char)*(in++)];
109         *(out++) = sample;
110         (*inlen)--; (*outlen)--;
111     }
112     plc_rx(&state->plc, orig_out, (int)(out - orig_out));
113
114     return 0;
115 }
116
117 static int encode ( struct iaxc_audio_codec *c,
118     int *inlen, short *in, int *outlen, unsigned char *out ) {
119
120     while ((*inlen > 0) && (*outlen > 0)) {
121         *(out++) = lin_2ulaw[((unsigned short)*(in++)) >> 2];
122         (*inlen)--; (*outlen)--;
123     }
124
125     return 0;
126 }
127
128
129 struct iaxc_audio_codec *codec_audio_ulaw_new() {
130
131   struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
132
133   if(!c) return c;
134
135   if(!initialized) initialize();
136
137   strcpy(c->name,"ulaw");
138   c->format = IAXC_FORMAT_ULAW;
139   c->encode = encode;
140   c->decode = decode;
141   c->destroy = destroy;
142
143   /* really, we can use less, but don't want to */
144   c->minimum_frame_size = 160;
145
146   /* decoder state, used for interpolation */
147   c->decstate = calloc(sizeof(struct state),1);
148   plc_init(&((struct state *)c->decstate)->plc);
149
150   return c;
151 }
152