2 * iaxclient: a cross-platform IAX softphone library
5 * Copyright (C) 2004 Cyril VELTER
8 * Cyril VELTER <cyril.velter@metadys.com>
10 * This program is free software, distributed under the terms of
11 * the GNU Lesser (Library) General Public License.
14 #include "codec_alaw.h"
15 #include "iaxclient_lib.h"
18 #define INLINE __inline
27 static INLINE short int alawdecode (unsigned char alaw)
35 /* Extract and scale value */
36 value = (alaw & 0x0f) << 4;
38 /* Extract segment number */
39 segment = (alaw & 0x70) >> 4;
50 value <<= segment - 1;
54 return (alaw & 0x80) ? value : -value;
57 static INLINE unsigned char alawencode (short int linear)
63 static int segments[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
67 /* Sign (7th) bit = 1 */
72 /* Sign (7th) bit = 0 */
76 /* Find the segment */
77 for (segment = 0;segment < 8;segment++)
78 if (linear <= segments[segment])
81 /* Combine the sign, segment, and quantization bits. */
86 alaw = (linear >> 4) & 0x0F;
88 alaw = (linear >> (segment + 3)) & 0x0F;
90 return ((alaw | (segment << 4)) ^ mask);
93 /* out of range, return maximum value. */
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;
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;
113 while ((*inlen > 0) && (*outlen > 0)) {
114 sample = alawdecode((unsigned char)*(in++));
116 (*inlen)--; (*outlen)--;
118 plc_rx(&state->plc, orig_out, (int)(out - orig_out));
123 static int encode ( struct iaxc_audio_codec *c,
124 int *inlen, short *in, int *outlen, unsigned char *out ) {
126 while ((*inlen > 0) && (*outlen > 0)) {
127 *(out++) = alawencode(*(in++));
128 (*inlen)--; (*outlen)--;
134 static void destroy ( struct iaxc_audio_codec *c) {
138 struct iaxc_audio_codec *codec_audio_alaw_new() {
140 struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(1, sizeof(struct iaxc_audio_codec));
144 strcpy(c->name,"alaw");
145 c->format = IAXC_FORMAT_ALAW;
148 c->destroy = destroy;
150 /* really, we can use less, but don't want to */
151 c->minimum_frame_size = 160;
153 /* decoder state, used for interpolation */
154 c->decstate = calloc(sizeof(struct state),1);
155 plc_init(&((struct state *)c->decstate)->plc);