diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libpcm/itut_g711.c | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libpcm/itut_g711.c')
-rw-r--r-- | lib/rbcodec/codecs/libpcm/itut_g711.c | 204 |
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 | |||
29 | static 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 | |||
69 | static 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 | |||
109 | static struct pcm_format *fmt; | ||
110 | |||
111 | static 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 | |||
142 | static 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 | |||
157 | static 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 | |||
170 | static 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 | |||
183 | static const struct pcm_codec alaw_codec = { | ||
184 | set_format, | ||
185 | get_seek_pos, | ||
186 | decode_alaw, | ||
187 | }; | ||
188 | |||
189 | static const struct pcm_codec mulaw_codec = { | ||
190 | set_format, | ||
191 | get_seek_pos, | ||
192 | decode_mulaw, | ||
193 | }; | ||
194 | |||
195 | const struct pcm_codec *get_itut_g711_alaw_codec(void) | ||
196 | { | ||
197 | return &alaw_codec; | ||
198 | } | ||
199 | |||
200 | const struct pcm_codec *get_itut_g711_mulaw_codec(void) | ||
201 | { | ||
202 | return &mulaw_codec; | ||
203 | } | ||
204 | |||