summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libpcm/itut_g711.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libpcm/itut_g711.c')
-rw-r--r--lib/rbcodec/codecs/libpcm/itut_g711.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libpcm/itut_g711.c b/lib/rbcodec/codecs/libpcm/itut_g711.c
new file mode 100644
index 0000000000..88ff5f59e6
--- /dev/null
+++ b/lib/rbcodec/codecs/libpcm/itut_g711.c
@@ -0,0 +1,204 @@
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 "support_formats.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)
112{
113 fmt = format;
114
115 if (fmt->channels == 0)
116 {
117 DEBUGF("CODEC_ERROR: channels is 0\n");
118 return false;
119 }
120
121 if (fmt->bitspersample != 8)
122 {
123 DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample: %d\n",
124 fmt->bitspersample);
125 return false;
126 }
127
128 fmt->bytespersample = 1;
129
130 if (fmt->blockalign == 0)
131 fmt->blockalign = fmt->channels;
132
133 fmt->samplesperblock = fmt->blockalign / fmt->channels;
134
135 /* chunksize = about 1/50[sec] data */
136 fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock))
137 * fmt->blockalign;
138
139 return true;
140}
141
142static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
143 uint8_t *(*read_buffer)(size_t *realsize))
144{
145 static struct pcm_pos newpos;
146 uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
147 ((uint64_t)seek_val * ci->id3->frequency / 1000LL)
148 / fmt->samplesperblock :
149 seek_val / fmt->blockalign;
150
151 (void)read_buffer;
152 newpos.pos = newblock * fmt->blockalign;
153 newpos.samples = newblock * fmt->samplesperblock;
154 return &newpos;
155}
156
157static int decode_alaw(const uint8_t *inbuf, size_t inbufsize,
158 int32_t *outbuf, int *outbufsize)
159{
160 uint32_t i;
161
162 for (i = 0; i < inbufsize; i++)
163 outbuf[i] = alaw2linear16[inbuf[i]] << (PCM_OUTPUT_DEPTH - 16);
164
165 *outbufsize = (fmt->channels == 2) ? (inbufsize >> 1) : inbufsize;
166
167 return CODEC_OK;
168}
169
170static int decode_mulaw(const uint8_t *inbuf, size_t inbufsize,
171 int32_t *outbuf, int *outbufsize)
172{
173 uint32_t i;
174
175 for (i = 0; i < inbufsize; i++)
176 outbuf[i] = ulaw2linear16[inbuf[i]] << (PCM_OUTPUT_DEPTH - 16);
177
178 *outbufsize = (fmt->channels == 2) ? (inbufsize >> 1) : inbufsize;
179
180 return CODEC_OK;
181}
182
183static const struct pcm_codec alaw_codec = {
184 set_format,
185 get_seek_pos,
186 decode_alaw,
187 };
188
189static const struct pcm_codec mulaw_codec = {
190 set_format,
191 get_seek_pos,
192 decode_mulaw,
193 };
194
195const struct pcm_codec *get_itut_g711_alaw_codec(void)
196{
197 return &alaw_codec;
198}
199
200const struct pcm_codec *get_itut_g711_mulaw_codec(void)
201{
202 return &mulaw_codec;
203}
204