]> git.mxchange.org Git - flightgear.git/blob - 3rdparty/iaxclient/lib/codec_alaw.c
VS2015 compatability fixes.
[flightgear.git] / 3rdparty / iaxclient / lib / codec_alaw.c
1 /*
2  * iaxclient: a cross-platform IAX softphone library
3  *
4  * Copyrights:
5  * Copyright (C) 2004 Cyril VELTER
6  *
7  * Contributors:
8  * Cyril VELTER <cyril.velter@metadys.com>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU Lesser (Library) General Public License.
12  */
13
14 #include "codec_alaw.h"
15 #include "iaxclient_lib.h"
16
17 #if defined(_MSC_VER)
18 #define INLINE __inline
19 #else
20 #define INLINE inline
21 #endif
22
23 struct state {
24     plc_state_t plc;
25 };
26
27 static INLINE short int alawdecode (unsigned char alaw)
28 {
29         int value;
30         int segment;
31
32         /* Mask value */
33         alaw ^= 0x55;
34
35         /* Extract and scale value */
36         value = (alaw & 0x0f) << 4;
37
38         /* Extract segment number */
39         segment = (alaw & 0x70) >> 4;
40
41         /* Compute value */
42         switch (segment) {
43                 case 0:
44                         break;
45                 case 1:
46                         value += 0x100;
47                         break;
48                 default:
49                         value += 0x100;
50                         value <<= segment - 1;
51         }
52
53         /* Extract sign */
54         return (alaw & 0x80) ? value : -value;
55 }
56
57 static INLINE unsigned char alawencode (short int linear)
58 {
59         int mask = 0x55;
60         int segment;
61         unsigned char alaw;
62
63         static int segments[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
64
65         if (linear >= 0)
66         {
67           /* Sign (7th) bit = 1 */
68           mask |= 0x80;
69         }
70         else
71         {
72           /* Sign (7th) bit = 0 */
73           linear = -linear;
74         }
75
76         /* Find the segment */
77         for (segment = 0;segment < 8;segment++)
78                 if (linear <= segments[segment])
79                         break;
80
81         /* Combine the sign, segment, and quantization bits. */
82
83         if (segment < 8)
84         {
85                 if (segment < 2)
86                         alaw = (linear >> 4) & 0x0F;
87                 else
88                         alaw = (linear >> (segment + 3)) & 0x0F;
89
90                 return ((alaw | (segment << 4)) ^ mask);
91         }
92         else
93                 /* out of range, return maximum value. */
94                 return (0x7F ^ mask);
95 }
96
97 static int decode ( struct iaxc_audio_codec *c,
98     int *inlen, unsigned char *in, int *outlen, short *out ) {
99     struct state *state = (struct state *)(c->decstate);
100     short *orig_out = out;
101     short sample;
102
103
104     if(*inlen == 0) {
105         int interp_len = 160;
106         if(*outlen < interp_len) interp_len = *outlen;
107         plc_fillin(&state->plc,out,interp_len);
108         *outlen -= interp_len;
109         return 0;
110     }
111
112
113     while ((*inlen > 0) && (*outlen > 0)) {
114         sample = alawdecode((unsigned char)*(in++));
115         *(out++) = sample;
116         (*inlen)--; (*outlen)--;
117     }
118     plc_rx(&state->plc, orig_out, (int)(out - orig_out));
119
120     return 0;
121 }
122
123 static int encode ( struct iaxc_audio_codec *c,
124     int *inlen, short *in, int *outlen, unsigned char *out ) {
125
126     while ((*inlen > 0) && (*outlen > 0)) {
127         *(out++) = alawencode(*(in++));
128         (*inlen)--; (*outlen)--;
129     }
130
131     return 0;
132 }
133
134 static void destroy ( struct iaxc_audio_codec *c) {
135     free(c);
136 }
137
138 struct iaxc_audio_codec *codec_audio_alaw_new() {
139
140   struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(1, sizeof(struct iaxc_audio_codec));
141
142   if(!c) return c;
143
144   strcpy(c->name,"alaw");
145   c->format = IAXC_FORMAT_ALAW;
146   c->encode = encode;
147   c->decode = decode;
148   c->destroy = destroy;
149
150   /* really, we can use less, but don't want to */
151   c->minimum_frame_size = 160;
152
153   /* decoder state, used for interpolation */
154   c->decstate = calloc(sizeof(struct state),1);
155   plc_init(&((struct state *)c->decstate)->plc);
156
157   return c;
158 }
159