summaryrefslogtreecommitdiff
path: root/apps/codecs/libpcm/itut_g711.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libpcm/itut_g711.c')
-rw-r--r--apps/codecs/libpcm/itut_g711.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/apps/codecs/libpcm/itut_g711.c b/apps/codecs/libpcm/itut_g711.c
new file mode 100644
index 0000000000..1f235943ad
--- /dev/null
+++ b/apps/codecs/libpcm/itut_g711.c
@@ -0,0 +1,203 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 * Copyright (C) 2009 Yoshihisa Uchida
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "codeclib.h"
23#include "pcm_common.h"
24
25/*
26 * ITU-T G.711 A-law mu-law
27 */
28
29static const int16_t alaw2linear16[256] ICONST_ATTR = {
30 -5504, -5248, -6016, -5760, -4480, -4224, -4992,
31 -4736, -7552, -7296, -8064, -7808, -6528, -6272,
32 -7040, -6784, -2752, -2624, -3008, -2880, -2240,
33 -2112, -2496, -2368, -3776, -3648, -4032, -3904,
34 -3264, -3136, -3520, -3392, -22016, -20992, -24064,
35 -23040, -17920, -16896, -19968, -18944, -30208, -29184,
36 -32256, -31232, -26112, -25088, -28160, -27136, -11008,
37 -10496, -12032, -11520, -8960, -8448, -9984, -9472,
38 -15104, -14592, -16128, -15616, -13056, -12544, -14080,
39 -13568, -344, -328, -376, -360, -280, -264,
40 -312, -296, -472, -456, -504, -488, -408,
41 -392, -440, -424, -88, -72, -120, -104,
42 -24, -8, -56, -40, -216, -200, -248,
43 -232, -152, -136, -184, -168, -1376, -1312,
44 -1504, -1440, -1120, -1056, -1248, -1184, -1888,
45 -1824, -2016, -1952, -1632, -1568, -1760, -1696,
46 -688, -656, -752, -720, -560, -528, -624,
47 -592, -944, -912, -1008, -976, -816, -784,
48 -880, -848, 5504, 5248, 6016, 5760, 4480,
49 4224, 4992, 4736, 7552, 7296, 8064, 7808,
50 6528, 6272, 7040, 6784, 2752, 2624, 3008,
51 2880, 2240, 2112, 2496, 2368, 3776, 3648,
52 4032, 3904, 3264, 3136, 3520, 3392, 22016,
53 20992, 24064, 23040, 17920, 16896, 19968, 18944,
54 30208, 29184, 32256, 31232, 26112, 25088, 28160,
55 27136, 11008, 10496, 12032, 11520, 8960, 8448,
56 9984, 9472, 15104, 14592, 16128, 15616, 13056,
57 12544, 14080, 13568, 344, 328, 376, 360,
58 280, 264, 312, 296, 472, 456, 504,
59 488, 408, 392, 440, 424, 88, 72,
60 120, 104, 24, 8, 56, 40, 216,
61 200, 248, 232, 152, 136, 184, 168,
62 1376, 1312, 1504, 1440, 1120, 1056, 1248,
63 1184, 1888, 1824, 2016, 1952, 1632, 1568,
64 1760, 1696, 688, 656, 752, 720, 560,
65 528, 624, 592, 944, 912, 1008, 976,
66 816, 784, 880, 848
67};
68
69static const int16_t ulaw2linear16[256] ICONST_ATTR = {
70 -32124, -31100, -30076, -29052, -28028, -27004, -25980,
71 -24956, -23932, -22908, -21884, -20860, -19836, -18812,
72 -17788, -16764, -15996, -15484, -14972, -14460, -13948,
73 -13436, -12924, -12412, -11900, -11388, -10876, -10364,
74 -9852, -9340, -8828, -8316, -7932, -7676, -7420,
75 -7164, -6908, -6652, -6396, -6140, -5884, -5628,
76 -5372, -5116, -4860, -4604, -4348, -4092, -3900,
77 -3772, -3644, -3516, -3388, -3260, -3132, -3004,
78 -2876, -2748, -2620, -2492, -2364, -2236, -2108,
79 -1980, -1884, -1820, -1756, -1692, -1628, -1564,
80 -1500, -1436, -1372, -1308, -1244, -1180, -1116,
81 -1052, -988, -924, -876, -844, -812, -780,
82 -748, -716, -684, -652, -620, -588, -556,
83 -524, -492, -460, -428, -396, -372, -356,
84 -340, -324, -308, -292, -276, -260, -244,
85 -228, -212, -196, -180, -164, -148, -132,
86 -120, -112, -104, -96, -88, -80, -72,
87 -64, -56, -48, -40, -32, -24, -16,
88 -8, 0, 32124, 31100, 30076, 29052, 28028,
89 27004, 25980, 24956, 23932, 22908, 21884, 20860,
90 19836, 18812, 17788, 16764, 15996, 15484, 14972,
91 14460, 13948, 13436, 12924, 12412, 11900, 11388,
92 10876, 10364, 9852, 9340, 8828, 8316, 7932,
93 7676, 7420, 7164, 6908, 6652, 6396, 6140,
94 5884, 5628, 5372, 5116, 4860, 4604, 4348,
95 4092, 3900, 3772, 3644, 3516, 3388, 3260,
96 3132, 3004, 2876, 2748, 2620, 2492, 2364,
97 2236, 2108, 1980, 1884, 1820, 1756, 1692,
98 1628, 1564, 1500, 1436, 1372, 1308, 1244,
99 1180, 1116, 1052, 988, 924, 876, 844,
100 812, 780, 748, 716, 684, 652, 620,
101 588, 556, 524, 492, 460, 428, 396,
102 372, 356, 340, 324, 308, 292, 276,
103 260, 244, 228, 212, 196, 180, 164,
104 148, 132, 120, 112, 104, 96, 88,
105 80, 72, 64, 56, 48, 40, 32,
106 24, 16, 8, 0
107};
108
109static struct pcm_format *fmt;
110
111static bool set_format(struct pcm_format *format, const unsigned char *fmtpos)
112{
113 fmt = format;
114
115 (void)fmtpos;
116
117 if (fmt->bitspersample != 8)
118 {
119 DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample\n");
120 return false;
121 }
122
123 if (fmt->totalsamples == 0)
124 {
125 fmt->bytespersample = fmt->channels;
126 fmt->totalsamples = fmt->numbytes/fmt->bytespersample;
127 }
128
129 /* chunksize is computed so that one chunk is about 1/50s.
130 * this make 4096 for 44.1kHz 16bits stereo.
131 * It also has to be a multiple of blockalign */
132 fmt->chunksize = (1 + fmt->avgbytespersec / (50*fmt->blockalign))*fmt->blockalign;
133
134 /* check that the output buffer is big enough (convert to samplespersec,
135 then round to the blockalign multiple below) */
136 if ((((uint64_t)fmt->chunksize * ci->id3->frequency * fmt->channels * fmt->bitspersample)>>3)
137 /(uint64_t)fmt->avgbytespersec >= PCM_CHUNK_SIZE)
138 fmt->chunksize = ((uint64_t)PCM_CHUNK_SIZE * fmt->avgbytespersec
139 /((uint64_t)ci->id3->frequency * fmt->channels * 2
140 * fmt->blockalign)) * fmt->blockalign;
141
142 return true;
143}
144
145static uint32_t get_seek_pos(long seek_time)
146{
147 uint32_t newpos;
148
149 /* use avgbytespersec to round to the closest blockalign multiple,
150 add firstblockposn. 64-bit casts to avoid overflows. */
151 newpos = (((uint64_t)fmt->avgbytespersec*(seek_time - 1))
152 / (1000LL*fmt->blockalign))*fmt->blockalign;
153 return newpos;
154}
155
156static int decode_alaw(const uint8_t *inbuf, size_t inbufsize,
157 int32_t *outbuf, int *outbufsize)
158{
159 uint32_t i;
160
161 for (i = 0; i < inbufsize; i++)
162 outbuf[i] = alaw2linear16[inbuf[i]] << 13;
163
164 *outbufsize = (fmt->channels == 2) ? (inbufsize >> 1) : inbufsize;
165
166 return CODEC_OK;
167}
168
169static int decode_mulaw(const uint8_t *inbuf, size_t inbufsize,
170 int32_t *outbuf, int *outbufsize)
171{
172 uint32_t i;
173
174 for (i = 0; i < inbufsize; i++)
175 outbuf[i] = ulaw2linear16[inbuf[i]] << 13;
176
177 *outbufsize = (fmt->channels == 2) ? (inbufsize >> 1) : inbufsize;
178
179 return CODEC_OK;
180}
181
182static const struct pcm_codec alaw_codec = {
183 set_format,
184 get_seek_pos,
185 decode_alaw,
186 };
187
188static const struct pcm_codec mulaw_codec = {
189 set_format,
190 get_seek_pos,
191 decode_mulaw,
192 };
193
194const struct pcm_codec *get_itut_g711_alaw_codec(void)
195{
196 return &alaw_codec;
197}
198
199const struct pcm_codec *get_itut_g711_mulaw_codec(void)
200{
201 return &mulaw_codec;
202}
203