summaryrefslogtreecommitdiff
path: root/apps/codecs/libpcm/dvi_adpcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libpcm/dvi_adpcm.c')
-rw-r--r--apps/codecs/libpcm/dvi_adpcm.c444
1 files changed, 223 insertions, 221 deletions
diff --git a/apps/codecs/libpcm/dvi_adpcm.c b/apps/codecs/libpcm/dvi_adpcm.c
index 3df5e901be..97ba017451 100644
--- a/apps/codecs/libpcm/dvi_adpcm.c
+++ b/apps/codecs/libpcm/dvi_adpcm.c
@@ -21,280 +21,282 @@
21 ****************************************************************************/ 21 ****************************************************************************/
22#include "codeclib.h" 22#include "codeclib.h"
23#include "pcm_common.h" 23#include "pcm_common.h"
24#include "support_formats.h" 24#include "ima_adpcm_common.h"
25 25
26/* 26/*
27 * Intel DVI ADPCM 27 * Intel DVI ADPCM (IMA ADPCM)
28 *
29 * References
30 * [1] The IMA Digital Audio Focus and Technical Working Groups,
31 * Recommended Practices for Enhancing Digital Audio Compatibility
32 * in Multimedia Systems Revision 3.00, 1992
33 * [2] Microsoft Corporation, New Multimedia Data Types and Data Techniques,
34 * Revision:3.0, 1994
35 * [3] ffmpeg source code, libavcodec/adpcm.c
28 */ 36 */
29 37
30static const uint16_t dvi_adpcm_steptab[89] ICONST_ATTR = {
31 7, 8, 9, 10, 11, 12, 13, 14,
32 16, 17, 19, 21, 23, 25, 28, 31,
33 34, 37, 41, 45, 50, 55, 60, 66,
34 73, 80, 88, 97, 107, 118, 130, 143,
35 157, 173, 190, 209, 230, 253, 279, 307,
36 337, 371, 408, 449, 494, 544, 598, 658,
37 724, 796, 876, 963, 1060, 1166, 1282, 1411,
38 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
39 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
40 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
41 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
42 32767 };
43
44static const int dvi_adpcm_indextab4[8] ICONST_ATTR = {
45 -1, -1, -1, -1, 2, 4, 6, 8 };
46
47static const int dvi_adpcm_indextab3[4] ICONST_ATTR = { -1, -1, 1, 2 };
48
49static struct pcm_format *fmt; 38static struct pcm_format *fmt;
50 39
51static bool set_format(struct pcm_format *format, const unsigned char *fmtpos) 40static bool set_format(struct pcm_format *format)
52{ 41{
53 fmt = format; 42 fmt = format;
54 43
55 (void)fmtpos; 44 if (fmt->bitspersample < 2 || fmt->bitspersample > 5)
56
57 if (fmt->bitspersample != 4 && fmt->bitspersample != 3)
58 { 45 {
59 DEBUGF("CODEC_ERROR: dvi_adpcm must have 3 or 4 bitspersample\n"); 46 DEBUGF("CODEC_ERROR: dvi adpcm must be 2, 3, 4 or 5 bitspersample: %d\n",
47 fmt->bitspersample);
60 return false; 48 return false;
61 } 49 }
62 50
63 if (fmt->size < 2) { 51 fmt->chunksize = fmt->blockalign;
64 DEBUGF("CODEC_ERROR: dvi_adpcm is missing SamplesPerBlock value\n");
65 return false;
66 }
67
68 /* chunksize is computed so that one chunk is about 1/50s.
69 * this make 4096 for 44.1kHz 16bits stereo.
70 * It also has to be a multiple of blockalign */
71 fmt->chunksize = (1 + fmt->avgbytespersec / (50*fmt->blockalign))*fmt->blockalign;
72
73 /* check that the output buffer is big enough (convert to samplespersec,
74 then round to the blockalign multiple below) */
75 if ((((uint64_t)fmt->chunksize * ci->id3->frequency * fmt->channels * fmt->bitspersample)>>3)
76 /(uint64_t)fmt->avgbytespersec >= PCM_CHUNK_SIZE)
77 fmt->chunksize = ((uint64_t)PCM_CHUNK_SIZE * fmt->avgbytespersec
78 /((uint64_t)ci->id3->frequency * fmt->channels * 2
79 * fmt->blockalign)) * fmt->blockalign;
80 52
53 init_ima_adpcm_decoder(fmt->bitspersample, NULL);
81 return true; 54 return true;
82} 55}
83 56
84static uint32_t get_seek_pos(long seek_time) 57static struct pcm_pos *get_seek_pos(long seek_time,
58 uint8_t *(*read_buffer)(size_t *realsize))
85{ 59{
86 uint32_t newpos; 60 static struct pcm_pos newpos;
61 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
62 / (1000LL * fmt->samplesperblock);
87 63
88 /* use avgbytespersec to round to the closest blockalign multiple, 64 (void)read_buffer;
89 add firstblockposn. 64-bit casts to avoid overflows. */ 65 newpos.pos = newblock * fmt->blockalign;
90 newpos = (((uint64_t)fmt->avgbytespersec*(seek_time - 1)) 66 newpos.samples = newblock * fmt->samplesperblock;
91 / (1000LL*fmt->blockalign))*fmt->blockalign; 67 return &newpos;
92 return newpos;
93} 68}
94 69
95static int decode_dvi_adpcm(const uint8_t *inbuf, size_t inbufsize, 70static inline void decode_2bit(const uint8_t **inbuf,
96 int32_t *outbuf, size_t *outbufcount) 71 int32_t **outbuf, int *outbufcount)
97{ 72{
98 size_t nsamples = 0; 73 int ch;
99 int sample[2];
100 int samplecode[32][2];
101 int i; 74 int i;
102 int stepindex[2]; 75 int32_t *pcmbuf;
103 int c; 76 int samples;
104 int diff;
105 int step;
106 int codem;
107 int code;
108 77
109 if (fmt->bitspersample != 4 && fmt->bitspersample != 3) { 78 samples = fmt->blockalign / (4 * fmt->channels) - 1;
110 DEBUGF("decode_dvi_adpcm: wrong bitspersample\n"); 79 *outbufcount += (samples << 4);
111 return CODEC_ERROR; 80 while (samples-- > 0)
81 {
82 for (ch = 0; ch < fmt->channels; ch++)
83 {
84 pcmbuf = *outbuf + ch;
85 for (i = 0; i < 4; i++)
86 {
87 *pcmbuf = create_pcmdata(ch, **inbuf ) << 13;
88 pcmbuf += fmt->channels;
89 *pcmbuf = create_pcmdata(ch, **inbuf >> 2) << 13;
90 pcmbuf += fmt->channels;
91 *pcmbuf = create_pcmdata(ch, **inbuf >> 4) << 13;
92 pcmbuf += fmt->channels;
93 *pcmbuf = create_pcmdata(ch, **inbuf >> 6) << 13;
94 pcmbuf += fmt->channels;
95 (*inbuf)++;
96 }
97 }
98 *outbuf += 16 * fmt->channels;
112 } 99 }
100}
113 101
114 /* decode block header */ 102static inline void decode_3bit(const uint8_t **inbuf,
115 for (c = 0; c < fmt->channels && inbufsize >= 4; c++) { 103 int32_t **outbuf, int *outbufcount)
116 /* decode + push first sample */ 104{
117 sample[c] = (short)(inbuf[0]|(inbuf[1]<<8));/* need cast for sign-extend */ 105 const uint8_t *adpcmbuf;
118 outbuf[c] = sample[c] << 13; 106 uint32_t adpcms;
119 nsamples++; 107 int ch;
120 stepindex[c] = inbuf[2]; 108 int i;
121 /* check for step table index overflow */ 109 int32_t *pcmbuf;
122 if (stepindex[c] > 88) { 110 int samples;
123 DEBUGF("decode_dvi_adpcm: stepindex[%d]=%d>88\n",c,stepindex[c]);
124 return CODEC_ERROR;
125 }
126 111
127 inbuf += 4; 112 samples = (fmt->blockalign - 4 * fmt->channels) / (12 * fmt->channels);
128 inbufsize -= 4; 113 *outbufcount += (samples << 5);
129 } 114 while (samples--)
130 if (fmt->bitspersample == 4) { 115 {
131 while (inbufsize >= (size_t)(fmt->channels*4) && 116 for (ch = 0; ch < fmt->channels; ch++)
132 (nsamples + (fmt->channels*8) <= *outbufcount))
133 { 117 {
134 for (c = 0; c < fmt->channels; c++) 118 adpcmbuf = *inbuf + ch * 4;
119 pcmbuf = *outbuf + ch;
120 adpcms = *adpcmbuf++;
121 adpcms |= (*adpcmbuf++) << 8;
122 adpcms |= (*adpcmbuf++) << 16;
123 for (i = 0; i < 8; i++)
135 { 124 {
136 samplecode[0][c] = inbuf[0]&0xf; 125 *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << 13;
137 samplecode[1][c] = inbuf[0]>>4; 126 pcmbuf += fmt->channels;
138 samplecode[2][c] = inbuf[1]&0xf;
139 samplecode[3][c] = inbuf[1]>>4;
140 samplecode[4][c] = inbuf[2]&0xf;
141 samplecode[5][c] = inbuf[2]>>4;
142 samplecode[6][c] = inbuf[3]&0xf;
143 samplecode[7][c] = inbuf[3]>>4;
144 inbuf += 4;
145 inbufsize -= 4;
146 } 127 }
128 adpcms = *adpcmbuf++;
129 adpcmbuf += (fmt->channels - 1) * 4;
130 adpcms |= (*adpcmbuf++) << 8;
131 adpcms |= (*adpcmbuf++) << 16;
147 for (i = 0; i < 8; i++) 132 for (i = 0; i < 8; i++)
148 { 133 {
149 for (c = 0; c < fmt->channels; c++) 134 *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << 13;
150 { 135 pcmbuf += fmt->channels;
151 step = dvi_adpcm_steptab[stepindex[c]];
152 codem = samplecode[i][c];
153 code = codem & 0x07;
154
155 /* adjust the step table index */
156 stepindex[c] += dvi_adpcm_indextab4[code];
157 /* check for step table index overflow and underflow */
158 if (stepindex[c] > 88)
159 stepindex[c] = 88;
160 else if (stepindex[c] < 0)
161 stepindex[c] = 0;
162 /* calculate the difference */
163#ifdef STRICT_IMA
164 diff = 0;
165 if (code & 4)
166 diff += step;
167 step = step >> 1;
168 if (code & 2)
169 diff += step;
170 step = step >> 1;
171 if (code & 1)
172 diff += step;
173 step = step >> 1;
174 diff += step;
175#else
176 diff = ((code + code + 1) * step) >> 3; /* faster */
177#endif
178 /* check the sign bit */
179 /* check for overflow and underflow errors */
180 if (code != codem)
181 {
182 sample[c] -= diff;
183 if (sample[c] < -32768)
184 sample[c] = -32768;
185 }
186 else
187 {
188 sample[c] += diff;
189 if (sample[c] > 32767)
190 sample[c] = 32767;
191 }
192 /* output the new sample */
193 outbuf[nsamples] = sample[c] << 13;
194 nsamples++;
195 }
196 } 136 }
197 } 137 adpcms = *adpcmbuf++;
198 } else { /* bitspersample == 3 */ 138 adpcms |= (*adpcmbuf++) << 8;
199 while (inbufsize >= (uint32_t)(fmt->channels*12) && 139 adpcmbuf += (fmt->channels - 1) * 4;
200 (nsamples + 32*fmt->channels) <= *outbufcount) { 140 adpcms |= (*adpcmbuf++) << 16;
201 for (c = 0; c < fmt->channels; c++) { 141 for (i = 0; i < 8; i++)
202 uint16_t bitstream = 0; 142 {
203 int bitsread = 0; 143 *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << 13;
204 for (i = 0; i < 32 && inbufsize > 0; i++) { 144 pcmbuf += fmt->channels;
205 if (bitsread < 3) {
206 /* read 8 more bits */
207 bitstream |= inbuf[0]<<bitsread;
208 bitsread += 8;
209 inbufsize--;
210 inbuf++;
211 }
212 samplecode[i][c] = bitstream & 7;
213 bitstream = bitstream>>3;
214 bitsread -= 3;
215 }
216 if (bitsread != 0) {
217 /* 32*3 = 3 words, so we should end with bitsread==0 */
218 DEBUGF("decode_dvi_adpcm: error in implementation\n");
219 return CODEC_ERROR;
220 }
221 } 145 }
222 146 adpcms = *adpcmbuf++;
223 for (i = 0; i < 32; i++) { 147 adpcms |= (*adpcmbuf++) << 8;
224 for (c = 0; c < fmt->channels; c++) { 148 adpcms |= (*adpcmbuf++) << 16;
225 step = dvi_adpcm_steptab[stepindex[c]]; 149 for (i = 0; i < 8; i++)
226 codem = samplecode[i][c]; 150 {
227 code = codem & 0x03; 151 *pcmbuf = create_pcmdata(ch, adpcms >> (3 * i)) << 13;
228 152 pcmbuf += fmt->channels;
229 /* adjust the step table index */
230 stepindex[c] += dvi_adpcm_indextab3[code];
231 /* check for step table index overflow and underflow */
232 if (stepindex[c] > 88)
233 stepindex[c] = 88;
234 else if (stepindex[c] < 0)
235 stepindex[c] = 0;
236 /* calculate the difference */
237#ifdef STRICT_IMA
238 diff = 0;
239 if (code & 2)
240 diff += step;
241 step = step >> 1;
242 if (code & 1)
243 diff += step;
244 step = step >> 1;
245 diff += step;
246#else
247 diff = ((code + code + 1) * step) >> 3; /* faster */
248#endif
249 /* check the sign bit */
250 /* check for overflow and underflow errors */
251 if (code != codem) {
252 sample[c] -= diff;
253 if (sample[c] < -32768)
254 sample[c] = -32768;
255 }
256 else {
257 sample[c] += diff;
258 if (sample[c] > 32767)
259 sample[c] = 32767;
260 }
261 /* output the new sample */
262 outbuf[nsamples] = sample[c] << 13;
263 nsamples++;
264 }
265 } 153 }
266 } 154 }
155 *outbuf += 32 * fmt->channels;
156 *inbuf += 12 * fmt->channels;
267 } 157 }
158}
268 159
269 if (nsamples > *outbufcount) { 160static inline void decode_4bit(const uint8_t **inbuf,
270 DEBUGF("decode_dvi_adpcm: output buffer overflow!\n"); 161 int32_t **outbuf, int *outbufcount)
271 return CODEC_ERROR; 162{
163 int ch;
164 int i;
165 int32_t *pcmbuf;
166 int samples;
167
168 samples = fmt->blockalign / (4 * fmt->channels) - 1;
169 *outbufcount += (samples << 3);
170 while (samples-- > 0)
171 {
172 for (ch = 0; ch < fmt->channels; ch++)
173 {
174 pcmbuf = *outbuf + ch;
175 for (i = 0; i < 4; i++)
176 {
177 *pcmbuf = create_pcmdata_size4(ch, **inbuf ) << 13;
178 pcmbuf += fmt->channels;
179 *pcmbuf = create_pcmdata_size4(ch, **inbuf >> 4) << 13;
180 pcmbuf += fmt->channels;
181 (*inbuf)++;
182 }
183 }
184 *outbuf += 8 * fmt->channels;
272 } 185 }
273 *outbufcount = nsamples; 186}
274 if (inbufsize != 0) { 187
275 DEBUGF("decode_dvi_adpcm: n=%d unprocessed bytes\n", (int)inbufsize); 188static inline void decode_5bit(const uint8_t **inbuf,
189 int32_t **outbuf, int *outbufcount)
190{
191 const uint8_t *adpcmbuf;
192 uint64_t adpcms;
193 int ch;
194 int i;
195 int32_t *pcmbuf;
196 int samples;
197
198 samples = (fmt->blockalign - 4 * fmt->channels) / (20 * fmt->channels);
199 *outbufcount += (samples << 5);
200 while (samples--)
201 {
202 for (ch = 0; ch < fmt->channels; ch++)
203 {
204 adpcmbuf = *inbuf + ch * 4;
205 pcmbuf = *outbuf + ch;
206 adpcms = *adpcmbuf++;
207 adpcms |= (*adpcmbuf++) << 8;
208 adpcms |= (*adpcmbuf++) << 16;
209 adpcms |= (uint64_t)(*adpcmbuf++) << 24;
210 adpcmbuf += (fmt->channels - 1) * 4;
211 adpcms |= (uint64_t)(*adpcmbuf++) << 32;
212 for (i = 0; i < 8; i++)
213 {
214 *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << 13;
215 pcmbuf += fmt->channels;
216 }
217 adpcms = *adpcmbuf++;
218 adpcms |= (*adpcmbuf++) << 8;
219 adpcms |= (*adpcmbuf++) << 16;
220 adpcmbuf += (fmt->channels - 1) * 4;
221 adpcms |= (uint64_t)(*adpcmbuf++) << 24;
222 adpcms |= (uint64_t)(*adpcmbuf++) << 32;
223 for (i = 0; i < 8; i++)
224 {
225 *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << 13;
226 pcmbuf += fmt->channels;
227 }
228 adpcms = *adpcmbuf++;
229 adpcms |= (*adpcmbuf++) << 8;
230 adpcmbuf += (fmt->channels - 1) * 4;
231 adpcms |= (*adpcmbuf++) << 16;
232 adpcms |= (uint64_t)(*adpcmbuf++) << 24;
233 adpcms |= (uint64_t)(*adpcmbuf++) << 32;
234 for (i = 0; i < 8; i++)
235 {
236 *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << 13;
237 pcmbuf += fmt->channels;
238 }
239 adpcms = *adpcmbuf++;
240 adpcmbuf += (fmt->channels - 1) * 4;
241 adpcms |= (*adpcmbuf++) << 8;
242 adpcms |= (*adpcmbuf++) << 16;
243 adpcms |= (uint64_t)(*adpcmbuf++) << 24;
244 adpcms |= (uint64_t)(*adpcmbuf++) << 32;
245 for (i = 0; i < 8; i++)
246 {
247 *pcmbuf = create_pcmdata(ch, adpcms >> (5 * i)) << 13;
248 pcmbuf += fmt->channels;
249 }
250 }
251 *outbuf += 32 * fmt->channels;
252 *inbuf += 20 * fmt->channels;
276 } 253 }
277 return CODEC_OK;
278} 254}
279 255
280static int decode(const uint8_t *inbuf, size_t inbufsize, 256static int decode(const uint8_t *inbuf, size_t inbufsize,
281 int32_t *outbuf, int *outbufsize) 257 int32_t *outbuf, int *outbufcount)
282{ 258{
259 int ch;
283 unsigned int i; 260 unsigned int i;
261 int32_t init_pcmdata[2];
262 int8_t init_index[2];
284 unsigned int nblocks = fmt->chunksize / fmt->blockalign; 263 unsigned int nblocks = fmt->chunksize / fmt->blockalign;
285 264
286 (void)inbufsize; 265 (void)inbufsize;
287 266
267 *outbufcount = 0;
288 for (i = 0; i < nblocks; i++) 268 for (i = 0; i < nblocks; i++)
289 { 269 {
290 size_t decodedsize = fmt->samplesperblock * fmt->channels; 270 for (ch = 0; ch < fmt->channels; ch++)
291 if (decode_dvi_adpcm(inbuf + i * fmt->blockalign, fmt->blockalign, 271 {
292 outbuf + i * fmt->samplesperblock * fmt->channels, 272 init_pcmdata[ch] = inbuf[0] | (inbuf[1] << 8);
293 &decodedsize) != CODEC_OK) { 273 if (init_pcmdata[ch] > 32767)
294 return CODEC_ERROR; 274 init_pcmdata[ch] -= 65536;
275
276 init_index[ch] = inbuf[2];
277 if (init_index[ch] > 88 || init_index[ch] < 0)
278 {
279 DEBUGF("CODEC_ERROR: dvi adpcm illegal step index=%d > 88\n",
280 init_index[ch]);
281 return CODEC_ERROR;
282 }
283 inbuf += 4;
284
285 *outbuf++ = init_pcmdata[ch] << 13;
295 } 286 }
287
288 *outbufcount += 1;
289 set_decode_parameters(fmt->channels, init_pcmdata, init_index);
290
291 if (fmt->bitspersample == 4)
292 decode_4bit(&inbuf, &outbuf, outbufcount);
293 else if (fmt->bitspersample == 3)
294 decode_3bit(&inbuf, &outbuf, outbufcount);
295 else if (fmt->bitspersample == 5)
296 decode_5bit(&inbuf, &outbuf, outbufcount);
297 else /* fmt->bitspersample == 2 */
298 decode_2bit(&inbuf, &outbuf, outbufcount);
296 } 299 }
297 *outbufsize = nblocks * fmt->samplesperblock;
298 return CODEC_OK; 300 return CODEC_OK;
299} 301}
300 302