summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshihisa Uchida <uchida@rockbox.org>2010-02-20 02:04:56 +0000
committerYoshihisa Uchida <uchida@rockbox.org>2010-02-20 02:04:56 +0000
commit3716abba9274f544dd31cdf4e6c83a845bf2a801 (patch)
tree07bca7cdd3e40bb176e938fcb5ea8eb2f7c3e9cb
parent93caf52db5e0afe826278c148936bdfa563724f1 (diff)
downloadrockbox-3716abba9274f544dd31cdf4e6c83a845bf2a801.tar.gz
rockbox-3716abba9274f544dd31cdf4e6c83a845bf2a801.zip
commit FS#10424 and FS#10425
- wav(RIFF) supports Microsoft ADPCM, Dialogic OKI ADPCM, YAMAHA ADPCM, Adobe SWF ADPCM. - AIFF supports QuickTime IMA ADPCM. - DVI ADPCM(IMA ADPCM) reworks. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24782 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/aiff.c58
-rw-r--r--apps/codecs/libpcm/SOURCES7
-rw-r--r--apps/codecs/libpcm/adpcm_seek.c101
-rw-r--r--apps/codecs/libpcm/adpcm_seek.h39
-rw-r--r--apps/codecs/libpcm/dialogic_oki_adpcm.c183
-rw-r--r--apps/codecs/libpcm/dvi_adpcm.c444
-rw-r--r--apps/codecs/libpcm/ieee_float.c29
-rw-r--r--apps/codecs/libpcm/ima_adpcm_common.c171
-rw-r--r--apps/codecs/libpcm/ima_adpcm_common.h32
-rw-r--r--apps/codecs/libpcm/itut_g711.c44
-rw-r--r--apps/codecs/libpcm/linear_pcm.c39
-rw-r--r--apps/codecs/libpcm/ms_adpcm.c166
-rw-r--r--apps/codecs/libpcm/pcm_common.h77
-rw-r--r--apps/codecs/libpcm/qt_ima_adpcm.c136
-rw-r--r--apps/codecs/libpcm/support_formats.h21
-rw-r--r--apps/codecs/libpcm/swf_adpcm.c233
-rw-r--r--apps/codecs/libpcm/yamaha_adpcm.c245
-rw-r--r--apps/codecs/wav.c122
-rw-r--r--apps/metadata/aiff.c23
-rw-r--r--apps/metadata/wave.c138
20 files changed, 1968 insertions, 340 deletions
diff --git a/apps/codecs/aiff.c b/apps/codecs/aiff.c
index 2e10d1e416..4b870386c1 100644
--- a/apps/codecs/aiff.c
+++ b/apps/codecs/aiff.c
@@ -36,6 +36,7 @@ enum {
36 AIFC_FORMAT_MULAW = FOURCC('u', 'l', 'a', 'w'), /* AIFC uLaw compressed */ 36 AIFC_FORMAT_MULAW = FOURCC('u', 'l', 'a', 'w'), /* AIFC uLaw compressed */
37 AIFC_FORMAT_IEEE_FLOAT32 = FOURCC('f', 'l', '3', '2'), /* AIFC IEEE float 32 bit */ 37 AIFC_FORMAT_IEEE_FLOAT32 = FOURCC('f', 'l', '3', '2'), /* AIFC IEEE float 32 bit */
38 AIFC_FORMAT_IEEE_FLOAT64 = FOURCC('f', 'l', '6', '4'), /* AIFC IEEE float 64 bit */ 38 AIFC_FORMAT_IEEE_FLOAT64 = FOURCC('f', 'l', '6', '4'), /* AIFC IEEE float 64 bit */
39 AIFC_FORMAT_QT_IMA_ADPCM = FOURCC('i', 'm', 'a', '4'), /* AIFC QuickTime IMA ADPCM */
39}; 40};
40 41
41static const struct pcm_entry pcm_codecs[] = { 42static const struct pcm_entry pcm_codecs[] = {
@@ -44,9 +45,10 @@ static const struct pcm_entry pcm_codecs[] = {
44 { AIFC_FORMAT_MULAW, get_itut_g711_mulaw_codec }, 45 { AIFC_FORMAT_MULAW, get_itut_g711_mulaw_codec },
45 { AIFC_FORMAT_IEEE_FLOAT32, get_ieee_float_codec }, 46 { AIFC_FORMAT_IEEE_FLOAT32, get_ieee_float_codec },
46 { AIFC_FORMAT_IEEE_FLOAT64, get_ieee_float_codec }, 47 { AIFC_FORMAT_IEEE_FLOAT64, get_ieee_float_codec },
48 { AIFC_FORMAT_QT_IMA_ADPCM, get_qt_ima_adpcm_codec },
47}; 49};
48 50
49#define NUM_FORMATS 5 51#define NUM_FORMATS 6
50 52
51static int32_t samples[PCM_CHUNK_SIZE] IBSS_ATTR; 53static int32_t samples[PCM_CHUNK_SIZE] IBSS_ATTR;
52 54
@@ -70,7 +72,7 @@ enum codec_status codec_main(void)
70{ 72{
71 int status = CODEC_OK; 73 int status = CODEC_OK;
72 struct pcm_format format; 74 struct pcm_format format;
73 uint32_t bytesdone, decodedbytes; 75 uint32_t bytesdone, decodedsamples;
74 uint32_t num_sample_frames = 0; 76 uint32_t num_sample_frames = 0;
75 uint32_t i = CODEC_OK; 77 uint32_t i = CODEC_OK;
76 size_t n; 78 size_t n;
@@ -128,7 +130,7 @@ next_track:
128 format.is_signed = true; 130 format.is_signed = true;
129 format.is_little_endian = false; 131 format.is_little_endian = false;
130 132
131 decodedbytes = 0; 133 decodedsamples = 0;
132 codec = 0; 134 codec = 0;
133 135
134 /* read until 'SSND' chunk, which typically is last */ 136 /* read until 'SSND' chunk, which typically is last */
@@ -168,8 +170,11 @@ next_track:
168 * aiff's sample_size is uncompressed sound data size. 170 * aiff's sample_size is uncompressed sound data size.
169 * But format.bitspersample is compressed sound data size. 171 * But format.bitspersample is compressed sound data size.
170 */ 172 */
171 if (format.formattag == AIFC_FORMAT_ALAW || format.formattag == AIFC_FORMAT_MULAW) 173 if (format.formattag == AIFC_FORMAT_ALAW ||
174 format.formattag == AIFC_FORMAT_MULAW)
172 format.bitspersample = 8; 175 format.bitspersample = 8;
176 else if (format.formattag == AIFC_FORMAT_QT_IMA_ADPCM)
177 format.bitspersample = 4;
173 } 178 }
174 else 179 else
175 format.formattag = AIFC_FORMAT_PCM; 180 format.formattag = AIFC_FORMAT_PCM;
@@ -184,9 +189,9 @@ next_track:
184 /* offset2snd */ 189 /* offset2snd */
185 offset2snd = (buf[8]<<24)|(buf[9]<<16)|(buf[10]<<8)|buf[11]; 190 offset2snd = (buf[8]<<24)|(buf[9]<<16)|(buf[10]<<8)|buf[11];
186 /* block_size */ 191 /* block_size */
187 format.blockalign = (buf[12]<<24)|(buf[13]<<16)|(buf[14]<<8)|buf[15]; 192 format.blockalign = ((buf[12]<<24)|(buf[13]<<16)|(buf[14]<<8)|buf[15]) >> 3;
188 if (format.blockalign == 0) 193 if (format.blockalign == 0)
189 format.blockalign = format.channels*format.bitspersample; 194 format.blockalign = format.channels * format.bitspersample >> 3;
190 format.numbytes = i - 8 - offset2snd; 195 format.numbytes = i - 8 - offset2snd;
191 i = 8 + offset2snd; /* advance to the beginning of data */ 196 i = 8 + offset2snd; /* advance to the beginning of data */
192 } else if (is_aifc && (memcmp(buf, "FVER", 4)==0)) { 197 } else if (is_aifc && (memcmp(buf, "FVER", 4)==0)) {
@@ -228,7 +233,7 @@ next_track:
228 goto done; 233 goto done;
229 } 234 }
230 235
231 if (!codec->set_format(&format, 0)) 236 if (!codec->set_format(&format))
232 { 237 {
233 i = CODEC_ERROR; 238 i = CODEC_ERROR;
234 goto done; 239 goto done;
@@ -246,6 +251,30 @@ next_track:
246 goto done; 251 goto done;
247 } 252 }
248 253
254 if (format.samplesperblock == 0)
255 {
256 DEBUGF("CODEC_ERROR: samplesperblock is 0\n");
257 i = CODEC_ERROR;
258 goto done;
259 }
260 if (format.blockalign == 0)
261 {
262 DEBUGF("CODEC_ERROR: blockalign is 0\n");
263 i = CODEC_ERROR;
264 goto done;
265 }
266
267 /* check chunksize */
268 if ((format.chunksize / format.blockalign) * format.samplesperblock * format.channels
269 > PCM_CHUNK_SIZE)
270 format.chunksize = (PCM_CHUNK_SIZE / format.blockalign) * format.blockalign;
271 if (format.chunksize == 0)
272 {
273 DEBUGF("CODEC_ERROR: chunksize is 0\n");
274 i = CODEC_ERROR;
275 goto done;
276 }
277
249 firstblockposn = 1024 - n; 278 firstblockposn = 1024 - n;
250 ci->advance_buffer(firstblockposn); 279 ci->advance_buffer(firstblockposn);
251 280
@@ -260,11 +289,14 @@ next_track:
260 break; 289 break;
261 290
262 if (ci->seek_time) { 291 if (ci->seek_time) {
263 uint32_t newpos = codec->get_seek_pos(ci->seek_time); 292 /* 2nd args(read_buffer) is unnecessary in the format which AIFF supports. */
264 if (newpos > format.numbytes) 293 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, NULL);
294
295 decodedsamples = newpos->samples;
296 if (newpos->pos > format.numbytes)
265 break; 297 break;
266 if (ci->seek_buffer(firstblockposn + newpos)) 298 if (ci->seek_buffer(firstblockposn + newpos->pos))
267 bytesdone = newpos; 299 bytesdone = newpos->pos;
268 ci->seek_complete(); 300 ci->seek_complete();
269 } 301 }
270 aifbuf = (uint8_t *)ci->request_buffer(&n, format.chunksize); 302 aifbuf = (uint8_t *)ci->request_buffer(&n, format.chunksize);
@@ -288,11 +320,11 @@ next_track:
288 320
289 ci->advance_buffer(n); 321 ci->advance_buffer(n);
290 bytesdone += n; 322 bytesdone += n;
291 decodedbytes += bufcount; 323 decodedsamples += bufcount;
292 if (bytesdone >= format.numbytes) 324 if (bytesdone >= format.numbytes)
293 endofstream = 1; 325 endofstream = 1;
294 326
295 ci->set_elapsed(decodedbytes*1000LL/ci->id3->frequency); 327 ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
296 } 328 }
297 i = CODEC_OK; 329 i = CODEC_OK;
298 330
diff --git a/apps/codecs/libpcm/SOURCES b/apps/codecs/libpcm/SOURCES
index 89be3452b1..356c9cdbb7 100644
--- a/apps/codecs/libpcm/SOURCES
+++ b/apps/codecs/libpcm/SOURCES
@@ -2,3 +2,10 @@ linear_pcm.c
2itut_g711.c 2itut_g711.c
3dvi_adpcm.c 3dvi_adpcm.c
4ieee_float.c 4ieee_float.c
5adpcm_seek.c
6dialogic_oki_adpcm.c
7ms_adpcm.c
8yamaha_adpcm.c
9ima_adpcm_common.c
10qt_ima_adpcm.c
11swf_adpcm.c
diff --git a/apps/codecs/libpcm/adpcm_seek.c b/apps/codecs/libpcm/adpcm_seek.c
new file mode 100644
index 0000000000..ce49d5fcd3
--- /dev/null
+++ b/apps/codecs/libpcm/adpcm_seek.c
@@ -0,0 +1,101 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "adpcm_seek.h"
22#include "codeclib.h"
23
24/*
25 * The helper functions in order to seek for the adpcm codec
26 * which does not include the header each the data block.
27 */
28
29#define MAX_STORE_COUNT 1000
30
31static struct adpcm_data seek_table[MAX_STORE_COUNT];
32static int seek_count;
33static int cur_count;
34static int max_ratio;
35static int cur_ratio;
36
37void init_seek_table(uint32_t max_count)
38{
39 int i = 0;
40
41 for ( ; i < MAX_STORE_COUNT; i++)
42 {
43 seek_table[i].is_valid = false;
44 }
45 seek_count = max_count / MAX_STORE_COUNT + 1;
46 max_ratio = max_count / seek_count + 1;
47 cur_count = 0;
48 cur_ratio = -1;
49}
50
51void add_adpcm_data(struct adpcm_data *data)
52{
53 if (--cur_count <= 0)
54 {
55 cur_count = seek_count;
56 if (++cur_ratio >= max_ratio)
57 cur_ratio = max_ratio - 1;
58
59 if (!seek_table[cur_ratio].is_valid)
60 {
61 seek_table[cur_ratio].pcmdata[0] = data->pcmdata[0];
62 seek_table[cur_ratio].pcmdata[1] = data->pcmdata[1];
63 seek_table[cur_ratio].step[0] = data->step[0];
64 seek_table[cur_ratio].step[1] = data->step[1];
65 seek_table[cur_ratio].is_valid = true;
66 }
67 }
68}
69
70uint32_t seek(uint32_t count, struct adpcm_data *seek_data,
71 uint8_t *(*read_buffer)(size_t *realsize),
72 int (*decode)(const uint8_t *inbuf, size_t inbufsize))
73{
74 int new_ratio = count / seek_count;
75
76 if (new_ratio >= max_ratio)
77 new_ratio = max_ratio - 1;
78
79 if (!seek_table[new_ratio].is_valid)
80 {
81 uint8_t *buffer;
82 size_t n;
83
84 do
85 {
86 buffer = read_buffer(&n);
87 if (n == 0)
88 break;
89 decode(buffer, n);
90 } while (cur_ratio < new_ratio);
91 }
92
93 seek_data->pcmdata[0] = seek_table[new_ratio].pcmdata[0];
94 seek_data->pcmdata[1] = seek_table[new_ratio].pcmdata[1];
95 seek_data->step[0] = seek_table[new_ratio].step[0];
96 seek_data->step[1] = seek_table[new_ratio].step[1];
97
98 cur_ratio = new_ratio;
99 cur_count = seek_count;
100 return cur_ratio * seek_count;
101}
diff --git a/apps/codecs/libpcm/adpcm_seek.h b/apps/codecs/libpcm/adpcm_seek.h
new file mode 100644
index 0000000000..66ec390097
--- /dev/null
+++ b/apps/codecs/libpcm/adpcm_seek.h
@@ -0,0 +1,39 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef CODEC_LIBPCM_ADPCM_SEEK_H
22#define CODEC_LIBPCM_ADPCM_SEEK_H
23
24#include <sys/types.h>
25#include <stdbool.h>
26#include <inttypes.h>
27
28struct adpcm_data {
29 int16_t pcmdata[2];
30 uint16_t step[2];
31 bool is_valid;
32};
33
34void init_seek_table(uint32_t max_count);
35void add_adpcm_data(struct adpcm_data *data);
36uint32_t seek(uint32_t seek_time, struct adpcm_data *seek_data,
37 uint8_t *(*read_buffer)(size_t *realsize),
38 int (*decode)(const uint8_t *inbuf, size_t inbufsize));
39#endif
diff --git a/apps/codecs/libpcm/dialogic_oki_adpcm.c b/apps/codecs/libpcm/dialogic_oki_adpcm.c
new file mode 100644
index 0000000000..e12930057b
--- /dev/null
+++ b/apps/codecs/libpcm/dialogic_oki_adpcm.c
@@ -0,0 +1,183 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "codeclib.h"
22#include "pcm_common.h"
23#include "adpcm_seek.h"
24
25/*
26 * Dialogic OKI ADPCM
27 *
28 * References
29 * [1] Dialogic Corporation, Dialogic ADPCM Algorithm, 1988
30 * [2] MultimediaWiki, Dialogic IMA ADPCM, URL:http://wiki.multimedia.cx/index.php?title=Dialogic_IMA_ADPCM
31 * [3] sox source code, src/adpcms.c
32 * [4] Tetsuya Isaki, NetBSD:/sys/dev/audio.c, http://www.tri-tree.gr.jp/~isaki/NetBSD/src/sys/dev/ic/msm6258.c.html
33 */
34
35static const uint16_t step_table[] ICONST_ATTR = {
36 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55,
37 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209,
38 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
39 876, 963, 1060, 1166, 1282, 1411, 1552,
40};
41
42static const int index_table[] ICONST_ATTR = {
43 -1, -1, -1, -1, 2, 4, 6, 8
44};
45
46static struct adpcm_data cur_data;
47
48static struct pcm_format *fmt;
49
50static bool set_format(struct pcm_format *format)
51{
52 uint32_t max_chunk_count;
53
54 fmt = format;
55
56 if (fmt->bitspersample != 4)
57 {
58 DEBUGF("CODEC_ERROR: dialogic oki adpcm must be 4 bitspersample: %d\n",
59 fmt->bitspersample);
60 return false;
61 }
62
63 if (fmt->channels != 1)
64 {
65 DEBUGF("CODEC_ERROR: dialogic oki adpcm must be monaural\n");
66 return false;
67 }
68
69 /* blockalign = 2 samples */
70 fmt->blockalign = 1;
71 fmt->samplesperblock = 2;
72
73 /* chunksize = about 1/32[sec] data */
74 fmt->chunksize = ci->id3->frequency >> 6;
75
76 max_chunk_count = (uint64_t)ci->id3->length * ci->id3->frequency
77 / (2000LL * fmt->chunksize);
78
79 /* initialize seek table */
80 init_seek_table(max_chunk_count);
81 /* add first data */
82 add_adpcm_data(&cur_data);
83
84 return true;
85}
86
87static int16_t create_pcmdata(uint8_t nibble)
88{
89 int16_t delta;
90 int16_t index = cur_data.step[0];
91 int16_t step = step_table[index];
92
93 delta = (step >> 3);
94 if (nibble & 4) delta += step;
95 if (nibble & 2) delta += (step >> 1);
96 if (nibble & 1) delta += (step >> 2);
97
98 if (nibble & 0x08)
99 cur_data.pcmdata[0] -= delta;
100 else
101 cur_data.pcmdata[0] += delta;
102
103 CLIP(cur_data.pcmdata[0], -2048, 2047);
104
105 index += index_table[nibble & 0x07];
106 CLIP(index, 0, 48);
107 cur_data.step[0] = index;
108
109 return cur_data.pcmdata[0];
110}
111
112static int decode(const uint8_t *inbuf, size_t inbufsize,
113 int32_t *outbuf, int *outbufcount)
114{
115 size_t nsamples = 0;
116
117 while (inbufsize)
118 {
119 *outbuf++ = create_pcmdata(*inbuf >> 4) << 17;
120 *outbuf++ = create_pcmdata(*inbuf ) << 17;
121 nsamples += 2;
122
123 inbuf++;
124 inbufsize--;
125 }
126
127 *outbufcount = nsamples;
128 add_adpcm_data(&cur_data);
129
130 return CODEC_OK;
131}
132
133static int decode_for_seek(const uint8_t *inbuf, size_t inbufsize)
134{
135 while (inbufsize)
136 {
137 create_pcmdata(*inbuf >> 4);
138 create_pcmdata(*inbuf );
139
140 inbuf++;
141 inbufsize--;
142 }
143
144 add_adpcm_data(&cur_data);
145
146 return CODEC_OK;
147}
148
149static struct pcm_pos *get_seek_pos(long seek_time,
150 uint8_t *(*read_buffer)(size_t *realsize))
151{
152 static struct pcm_pos newpos;
153 uint32_t seek_count = 0;
154 uint32_t new_count;
155
156 if (seek_time > 0)
157 seek_count = (uint64_t)seek_time * ci->id3->frequency
158 / (2000LL * fmt->chunksize);
159
160 new_count = seek(seek_count, &cur_data, read_buffer, &decode_for_seek);
161 newpos.pos = new_count * fmt->chunksize;
162 newpos.samples = (newpos.pos / fmt->blockalign) * fmt->samplesperblock;
163 return &newpos;
164}
165
166static const struct pcm_codec codec = {
167 set_format,
168 get_seek_pos,
169 decode,
170 };
171
172const struct pcm_codec *get_dialogic_oki_adpcm_codec(void)
173{
174 /*
175 * initialize first pcm data, step index
176 * because the dialogic oki adpcm is always monaural,
177 * pcmdata[1], step[1] do not use.
178 */
179 cur_data.pcmdata[0] = 0;
180 cur_data.step[0] = 0;
181
182 return &codec;
183}
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
diff --git a/apps/codecs/libpcm/ieee_float.c b/apps/codecs/libpcm/ieee_float.c
index c0e91a46cb..0530993f31 100644
--- a/apps/codecs/libpcm/ieee_float.c
+++ b/apps/codecs/libpcm/ieee_float.c
@@ -28,33 +28,38 @@
28 28
29static struct pcm_format *fmt; 29static struct pcm_format *fmt;
30 30
31static bool set_format(struct pcm_format *format, const unsigned char *fmtpos) 31static bool set_format(struct pcm_format *format)
32{ 32{
33 fmt = format; 33 fmt = format;
34 34
35 (void)fmtpos;
36
37 if (fmt->bitspersample != 32 && fmt->bitspersample != 64) 35 if (fmt->bitspersample != 32 && fmt->bitspersample != 64)
38 { 36 {
39 DEBUGF("CODEC_ERROR: ieee float must be 32 or 64 bitspersample %d\n", fmt->bitspersample); 37 DEBUGF("CODEC_ERROR: ieee float must be 32 or 64 bitspersample: %d\n",
38 fmt->bitspersample);
40 return false; 39 return false;
41 } 40 }
42 41
43 fmt->bytespersample = fmt->bitspersample >> 3; 42 fmt->bytespersample = fmt->bitspersample >> 3;
44 fmt->blockalign = fmt->bytespersample; 43 fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels);
45 44
46 /* chunksize is computed so that one chunk is about 1/50s. */ 45 /* chunksize = about 1/50[sec] data */
47 fmt->chunksize = (ci->id3->frequency * fmt->channels / 50) * fmt->blockalign; 46 fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock))
47 * fmt->blockalign;
48 48
49 return true; 49 return true;
50} 50}
51 51
52static uint32_t get_seek_pos(long seek_time) 52static struct pcm_pos *get_seek_pos(long seek_time,
53 uint8_t *(*read_buffer)(size_t *realsize))
53{ 54{
54 uint32_t newpos; 55 static struct pcm_pos newpos;
55 56 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
56 newpos = ((uint64_t)(seek_time * ci->id3->frequency * fmt->channels / 1000LL))*fmt->blockalign; 57 / (1000LL * fmt->samplesperblock);
57 return newpos; 58
59 (void)read_buffer;
60 newpos.pos = newblock * fmt->blockalign;
61 newpos.samples = newblock * fmt->samplesperblock;
62 return &newpos;
58} 63}
59 64
60static int decode(const uint8_t *inbuf, size_t inbufsize, 65static int decode(const uint8_t *inbuf, size_t inbufsize,
diff --git a/apps/codecs/libpcm/ima_adpcm_common.c b/apps/codecs/libpcm/ima_adpcm_common.c
new file mode 100644
index 0000000000..ff5051f166
--- /dev/null
+++ b/apps/codecs/libpcm/ima_adpcm_common.c
@@ -0,0 +1,171 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "codeclib.h"
22#include "pcm_common.h"
23#include "ima_adpcm_common.h"
24
25/*
26 * Functions for IMA ADPCM and IMA ADPCM series format
27 *
28 * References
29 * [1] The IMA Digital Audio Focus and Technical Working Groups,
30 * Recommended Practices for Enhancing Digital Audio Compatibility
31 * in Multimedia Systems Revision 3.00, 1992
32 * [2] Microsoft Corporation, New Multimedia Data Types and Data Techniques,
33 * Revision:3.0, 1994
34 * [3] ffmpeg source code, libavcodec/adpcm.c
35 */
36
37/* step table */
38static const uint16_t step_table[89] ICONST_ATTR = {
39 7, 8, 9, 10, 11, 12, 13, 14,
40 16, 17, 19, 21, 23, 25, 28, 31,
41 34, 37, 41, 45, 50, 55, 60, 66,
42 73, 80, 88, 97, 107, 118, 130, 143,
43 157, 173, 190, 209, 230, 253, 279, 307,
44 337, 371, 408, 449, 494, 544, 598, 658,
45 724, 796, 876, 963, 1060, 1166, 1282, 1411,
46 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
47 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
48 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
49 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
50 32767
51};
52
53/* step index tables */
54static const int index_tables[4][16] ICONST_ATTR = {
55 /* adpcm data size is 2 */
56 { -1, 2 },
57 /* adpcm data size is 3 */
58 { -1, -1, 1, 2 },
59 /* adpcm data size is 4 */
60 { -1, -1, -1, -1, 2, 4, 6, 8 },
61 /* adpcm data size is 5 */
62 { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 },
63};
64
65static int32_t pcmdata[2];
66static int8_t index[2];
67
68static int adpcm_data_size;
69static uint8_t step_mask;
70static uint8_t step_sign_mask;
71static int8_t step_shift;
72static const int *use_index_table;
73
74/*
75 * Before first decoding, this function must be executed.
76 *
77 * params
78 * bit: adpcm data size (2 <= bit <= 5).
79 * index_table: step index table
80 * if index_table is null, then step index table
81 * is used index_tables[bit-2].
82 */
83void init_ima_adpcm_decoder(int bit, const int *index_table)
84{
85 adpcm_data_size = bit;
86 step_sign_mask = 1 << (adpcm_data_size - 1);
87 step_mask = step_sign_mask - 1;
88 step_shift = adpcm_data_size - 2;
89 if (index_table)
90 use_index_table = index_table;
91 else
92 use_index_table = index_tables[adpcm_data_size - 2];
93}
94
95/*
96 * When starting decoding for each block, this function must be executed.
97 *
98 * params
99 * channels: channel count
100 * init_pcmdata: array of init pcmdata
101 * init_index: array of init step indexes
102 */
103void set_decode_parameters(int channels, int32_t *init_pcmdata, int8_t *init_index)
104{
105 int ch;
106
107 for (ch = 0; ch < channels; ch++)
108 {
109 pcmdata[ch] = init_pcmdata[ch];
110 index[ch] = init_index[ch];
111 }
112}
113
114/*
115 * convert ADPCM to PCM for any adpcm data size.
116 *
117 * If adpcm_data_size is 4, then you use create_pcmdata_size4()
118 * in place of this functon.
119 */
120int16_t create_pcmdata(int ch, uint8_t nibble)
121{
122 int check_bit = 1 << step_shift;
123 int32_t delta = 0;
124 int16_t step = step_table[index[ch]];
125
126 do {
127 if (nibble & check_bit)
128 delta += step;
129 step >>= 1;
130 check_bit >>= 1;
131 } while (check_bit);
132 delta += step;
133
134 if (nibble & step_sign_mask)
135 pcmdata[ch] -= delta;
136 else
137 pcmdata[ch] += delta;
138
139 index[ch] += use_index_table[nibble & step_mask];
140 CLIP(index[ch], 0, 88);
141
142 CLIP(pcmdata[ch], -32768, 32767);
143
144 return (int16_t)pcmdata[ch];
145}
146
147/*
148 * convert ADPCM to PCM when adpcm data size is 4.
149 */
150int16_t create_pcmdata_size4(int ch, uint8_t nibble)
151{
152 int32_t delta;
153 int16_t step = step_table[index[ch]];
154
155 delta = (step >> 3);
156 if (nibble & 4) delta += step;
157 if (nibble & 2) delta += (step >> 1);
158 if (nibble & 1) delta += (step >> 2);
159
160 if (nibble & 0x08)
161 pcmdata[ch] -= delta;
162 else
163 pcmdata[ch] += delta;
164
165 index[ch] += use_index_table[nibble & 0x07];
166 CLIP(index[ch], 0, 88);
167
168 CLIP(pcmdata[ch], -32768, 32767);
169
170 return (int16_t)pcmdata[ch];
171}
diff --git a/apps/codecs/libpcm/ima_adpcm_common.h b/apps/codecs/libpcm/ima_adpcm_common.h
new file mode 100644
index 0000000000..65cfefcfa3
--- /dev/null
+++ b/apps/codecs/libpcm/ima_adpcm_common.h
@@ -0,0 +1,32 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef CODEC_LIBPCM_IMA_ADPCM_COMMON_H
22#define CODEC_LIBPCM_IMA_ADPCM_COMMON_H
23
24#include <sys/types.h>
25#include <stdbool.h>
26#include <inttypes.h>
27
28void init_ima_adpcm_decoder(int bit, const int *index_table);
29void set_decode_parameters(int channels, int32_t *init_pcmdata, int8_t *init_index);
30int16_t create_pcmdata(int ch, uint8_t nibble);
31int16_t create_pcmdata_size4(int ch, uint8_t nibble);
32#endif
diff --git a/apps/codecs/libpcm/itut_g711.c b/apps/codecs/libpcm/itut_g711.c
index 520ca46a7a..9a38031882 100644
--- a/apps/codecs/libpcm/itut_g711.c
+++ b/apps/codecs/libpcm/itut_g711.c
@@ -109,49 +109,43 @@ static const int16_t ulaw2linear16[256] ICONST_ATTR = {
109 109
110static struct pcm_format *fmt; 110static struct pcm_format *fmt;
111 111
112static bool set_format(struct pcm_format *format, const unsigned char *fmtpos) 112static bool set_format(struct pcm_format *format)
113{ 113{
114 fmt = format; 114 fmt = format;
115 115
116 (void)fmtpos;
117
118 if (fmt->bitspersample != 8) 116 if (fmt->bitspersample != 8)
119 { 117 {
120 DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample\n"); 118 DEBUGF("CODEC_ERROR: alaw and mulaw must have 8 bitspersample: %d\n",
119 fmt->bitspersample);
121 return false; 120 return false;
122 } 121 }
123 122
124 if (fmt->totalsamples == 0) 123 if (fmt->totalsamples == 0)
125 { 124 {
126 fmt->bytespersample = fmt->channels; 125 fmt->bytespersample = 1;
127 fmt->totalsamples = fmt->numbytes/fmt->bytespersample; 126 fmt->totalsamples = fmt->numbytes / (fmt->bytespersample * fmt->channels);
128 } 127 }
129 128
130 /* chunksize is computed so that one chunk is about 1/50s. 129 fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels);
131 * this make 4096 for 44.1kHz 16bits stereo.
132 * It also has to be a multiple of blockalign */
133 fmt->chunksize = (1 + fmt->avgbytespersec / (50*fmt->blockalign))*fmt->blockalign;
134 130
135 /* check that the output buffer is big enough (convert to samplespersec, 131 /* chunksize = about 1/50[sec] data */
136 then round to the blockalign multiple below) */ 132 fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock))
137 if ((((uint64_t)fmt->chunksize * ci->id3->frequency * fmt->channels * fmt->bitspersample)>>3) 133 * fmt->blockalign;
138 /(uint64_t)fmt->avgbytespersec >= PCM_CHUNK_SIZE)
139 fmt->chunksize = ((uint64_t)PCM_CHUNK_SIZE * fmt->avgbytespersec
140 /((uint64_t)ci->id3->frequency * fmt->channels * 2
141 * fmt->blockalign)) * fmt->blockalign;
142 134
143 return true; 135 return true;
144} 136}
145 137
146static uint32_t get_seek_pos(long seek_time) 138static struct pcm_pos *get_seek_pos(long seek_time,
139 uint8_t *(*read_buffer)(size_t *realsize))
147{ 140{
148 uint32_t newpos; 141 static struct pcm_pos newpos;
149 142 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
150 /* use avgbytespersec to round to the closest blockalign multiple, 143 / (1000LL * fmt->samplesperblock);
151 add firstblockposn. 64-bit casts to avoid overflows. */ 144
152 newpos = (((uint64_t)fmt->avgbytespersec*(seek_time - 1)) 145 (void)read_buffer;
153 / (1000LL*fmt->blockalign))*fmt->blockalign; 146 newpos.pos = newblock * fmt->blockalign;
154 return newpos; 147 newpos.samples = newblock * fmt->samplesperblock;
148 return &newpos;
155} 149}
156 150
157static int decode_alaw(const uint8_t *inbuf, size_t inbufsize, 151static int decode_alaw(const uint8_t *inbuf, size_t inbufsize,
diff --git a/apps/codecs/libpcm/linear_pcm.c b/apps/codecs/libpcm/linear_pcm.c
index 4db27ca2b3..5360d79901 100644
--- a/apps/codecs/libpcm/linear_pcm.c
+++ b/apps/codecs/libpcm/linear_pcm.c
@@ -29,12 +29,10 @@
29 29
30static struct pcm_format *fmt; 30static struct pcm_format *fmt;
31 31
32static bool set_format(struct pcm_format *format, const unsigned char *fmtpos) 32static bool set_format(struct pcm_format *format)
33{ 33{
34 fmt = format; 34 fmt = format;
35 35
36 (void)fmtpos;
37
38 if (fmt->bitspersample > 32) 36 if (fmt->bitspersample > 32)
39 { 37 {
40 DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample " 38 DEBUGF("CODEC_ERROR: pcm with more than 32 bitspersample "
@@ -42,33 +40,34 @@ static bool set_format(struct pcm_format *format, const unsigned char *fmtpos)
42 return false; 40 return false;
43 } 41 }
44 42
43 fmt->bytespersample = fmt->bitspersample >> 3;
44
45 if (fmt->totalsamples == 0) 45 if (fmt->totalsamples == 0)
46 {
47 fmt->bytespersample = (((fmt->bitspersample - 1)/8 + 1)*fmt->channels);
48 fmt->totalsamples = fmt->numbytes/fmt->bytespersample; 46 fmt->totalsamples = fmt->numbytes/fmt->bytespersample;
49 }
50 47
51 /* chunksize is computed so that one chunk is about 1/50s. 48 fmt->samplesperblock = fmt->blockalign / (fmt->bytespersample * fmt->channels);
52 * this make 4096 for 44.1kHz 16bits stereo. 49
53 * It also has to be a multiple of blockalign */ 50 /* chunksize = about 1/50[sec] data */
54 fmt->chunksize = (1 + fmt->avgbytespersec / (50*fmt->blockalign))*fmt->blockalign; 51 fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock))
52 * fmt->blockalign;
55 53
56 return true; 54 return true;
57} 55}
58 56
59static 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))
60{ 59{
61 uint32_t newpos; 60 static struct pcm_pos newpos;
62 61 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
63 /* use avgbytespersec to round to the closest blockalign multiple, 62 / (1000LL * fmt->samplesperblock);
64 add firstblockposn. 64-bit casts to avoid overflows. */ 63
65 newpos = (((uint64_t)fmt->avgbytespersec*(seek_time - 1)) 64 (void)read_buffer;
66 / (1000LL*fmt->blockalign))*fmt->blockalign; 65 newpos.pos = newblock * fmt->blockalign;
67 return newpos; 66 newpos.samples = newblock * fmt->samplesperblock;
67 return &newpos;
68} 68}
69 69
70static int decode(const uint8_t *inbuf, size_t inbufsize, 70static int decode(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf, int *outbufsize)
71 int32_t *outbuf, int *outbufsize)
72{ 71{
73 uint32_t i; 72 uint32_t i;
74 73
diff --git a/apps/codecs/libpcm/ms_adpcm.c b/apps/codecs/libpcm/ms_adpcm.c
new file mode 100644
index 0000000000..899ecc2045
--- /dev/null
+++ b/apps/codecs/libpcm/ms_adpcm.c
@@ -0,0 +1,166 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "codeclib.h"
22#include "pcm_common.h"
23
24/*
25 * Microsoft ADPCM
26 *
27 * References
28 * [1] Microsoft, New Multimedia Data Types and Data Techniques Revision 3.0, 1994
29 * [2] MulitimediaWiki, Microsoft ADPCM, 2006
30 * (http://wiki.multimedia.cx/index.php?title=Microsoft_ADPCM)
31 * [3] ffmpeg source code, libavcodec/adpcm.c
32 */
33
34#define ADPCM_NUM_COEFF 7
35
36static int16_t dec_coeff[2][2];
37static uint16_t delta[2];
38static int16_t sample[2][2];
39
40static struct pcm_format *fmt;
41
42static const int16_t adaptation_table[] ICONST_ATTR = {
43 230, 230, 230, 230, 307, 409, 512, 614,
44 768, 614, 512, 409, 307, 230, 230, 230
45};
46
47static bool set_format(struct pcm_format *format)
48{
49 fmt = format;
50
51 if (fmt->bitspersample != 4)
52 {
53 DEBUGF("CODEC_ERROR: microsoft adpcm must be 4 bitspersample: %d\n",
54 fmt->bitspersample);
55 return false;
56 }
57
58 fmt->chunksize = fmt->blockalign;
59
60 return true;
61}
62
63static struct pcm_pos *get_seek_pos(long seek_time,
64 uint8_t *(*read_buffer)(size_t *realsize))
65{
66 static struct pcm_pos newpos;
67 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
68 / (1000LL * fmt->samplesperblock);
69
70 (void)read_buffer;
71 newpos.pos = newblock * fmt->blockalign;
72 newpos.samples = newblock * fmt->samplesperblock;
73 return &newpos;
74}
75
76static int16_t create_pcmdata(int ch, uint8_t nibble)
77{
78 int32_t pcmdata;
79
80 pcmdata = (sample[ch][0] * dec_coeff[ch][0] +
81 sample[ch][1] * dec_coeff[ch][1]) / 256;
82 pcmdata += (delta[ch] * (nibble - ((nibble & 0x8) << 1)));
83
84 CLIP(pcmdata, -32768, 32767);
85
86 sample[ch][1] = sample[ch][0];
87 sample[ch][0] = pcmdata;
88
89 delta[ch] = (adaptation_table[nibble] * delta[ch]) >> 8;
90 if (delta[ch] < 16)
91 delta[ch] = 16;
92
93 return (int16_t)pcmdata;
94}
95
96static int decode(const uint8_t *inbuf, size_t inbufsize,
97 int32_t *outbuf, int *outbufcount)
98{
99 int ch;
100 size_t nsamples = 0;
101 int size = fmt->samplesperblock;
102
103 /* read block header */
104 for (ch = 0; ch < fmt->channels; ch++)
105 {
106 if (*inbuf >= ADPCM_NUM_COEFF)
107 {
108 DEBUGF("CODEC_ERROR: microsoft adpcm illegal initial coeff=%d > 7\n",
109 *inbuf);
110 return CODEC_ERROR;
111 }
112 dec_coeff[ch][0] = fmt->coeffs[*inbuf][0];
113 dec_coeff[ch][1] = fmt->coeffs[*inbuf][1];
114 inbuf++;
115 }
116
117 for (ch = 0; ch < fmt->channels; ch++)
118 {
119 delta[ch] = inbuf[0] | (SE(inbuf[1]) << 8);
120 inbuf += 2;
121 }
122
123 for (ch = 0; ch < fmt->channels; ch++)
124 {
125 sample[ch][0] = inbuf[0] | (SE(inbuf[1]) << 8);
126 inbuf += 2;
127 }
128
129 for (ch = 0; ch < fmt->channels; ch++)
130 {
131 sample[ch][1] = inbuf[0] | (SE(inbuf[1]) << 8);
132 inbuf += 2;
133 }
134
135 inbufsize -= 7 * fmt->channels;
136 ch = fmt->channels - 1;
137
138 while (size-- > 0)
139 {
140 *outbuf++ = create_pcmdata(0, *inbuf >> 4 ) << 13;
141 *outbuf++ = create_pcmdata(ch, *inbuf & 0xf) << 13;
142 nsamples += 2;
143
144 inbuf++;
145 inbufsize--;
146 if (inbufsize <= 0)
147 break;
148 }
149
150 if (fmt->channels == 2)
151 nsamples >>= 1;
152 *outbufcount = nsamples;
153
154 return CODEC_OK;
155}
156
157static const struct pcm_codec codec = {
158 set_format,
159 get_seek_pos,
160 decode,
161 };
162
163const struct pcm_codec *get_ms_adpcm_codec(void)
164{
165 return &codec;
166}
diff --git a/apps/codecs/libpcm/pcm_common.h b/apps/codecs/libpcm/pcm_common.h
index 757d0ad5d9..d490a85e9f 100644
--- a/apps/codecs/libpcm/pcm_common.h
+++ b/apps/codecs/libpcm/pcm_common.h
@@ -18,8 +18,8 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#ifndef CODEC_LIBPCMS_PCM_COMMON_H 21#ifndef CODEC_LIBPCM_PCM_COMMON_H
22#define CODEC_LIBPCMS_PCM_COMMON_H 22#define CODEC_LIBPCM_PCM_COMMON_H
23 23
24#include <sys/types.h> 24#include <sys/types.h>
25#include <stdbool.h> 25#include <stdbool.h>
@@ -38,6 +38,19 @@
38/* Macro that shift to -0x80. (0 .. 127 to -128 .. -1, 128 .. 255 to 0 .. 127) */ 38/* Macro that shift to -0x80. (0 .. 127 to -128 .. -1, 128 .. 255 to 0 .. 127) */
39#define SFT(x) ((int32_t)x-0x80) 39#define SFT(x) ((int32_t)x-0x80)
40 40
41/* Macro that clipping data */
42#define CLIP(data, min, max) \
43if ((data) > (max)) data = max; \
44else if ((data) < (min)) data = min;
45
46/* nums of msadpcm coeffs
47 * In many case, nNumCoef is 7.
48 * Depending upon the encoder, as for this value there is a possibility
49 * of increasing more.
50 * If you found the file where this value exceeds 7, please report.
51 */
52#define MSADPCM_NUM_COEFF 7
53
41struct pcm_format { 54struct pcm_format {
42 /* 55 /*
43 * RIFF: wFormatTag (in 'fmt ' chunk) 56 * RIFF: wFormatTag (in 'fmt ' chunk)
@@ -103,13 +116,67 @@ struct pcm_format {
103 * true: signed, false: unsigned 116 * true: signed, false: unsigned
104 */ 117 */
105 bool is_signed; 118 bool is_signed;
119
120 /* the following values are format speciffic parameters */
121
122 /* microsoft adpcm: aCoeff */
123 int16_t coeffs[MSADPCM_NUM_COEFF][2];
124};
125
126struct pcm_pos {
127 uint32_t pos;
128 uint32_t samples;
106}; 129};
107 130
108struct pcm_codec { 131struct pcm_codec {
109 bool (*set_format)(struct pcm_format *format, const unsigned char *fmtpos); 132 /*
110 uint32_t (*get_seek_pos)(long seek_time); 133 * sets the format speciffic RIFF/AIFF header information and checks the pcm_format.
134 *
135 * [In/Out] format
136 * the structure which supplies RIFF/AIFF header information.
137 *
138 * return
139 * true: RIFF/AIFF header check OK
140 * false: RIFF/AIFF header check NG
141 */
142 bool (*set_format)(struct pcm_format *format);
143
144 /*
145 * get seek position
146 *
147 * [In] seek_time
148 * seek time [ms]
149 *
150 * [In] read_buffer
151 * the function which reads the data from the file (chunksize bytes read).
152 *
153 * return
154 * position after the seeking.
155 */
156 struct pcm_pos *(*get_seek_pos)(long seek_time,
157 uint8_t *(*read_buffer)(size_t *realsize));
158
159 /*
160 * decode wave data.
161 *
162 * [In] inbuf
163 * the start pointer of wave data buffer.
164 *
165 * [In] inbufsize
166 * wave data buffer size (bytes).
167 *
168 * [Out] outbuf
169 * the start pointer of the buffer which supplies decoded pcm data.
170 *
171 * [Out] outbufcount
172 * decoded pcm data count.
173 *
174 * return
175 * CODEC_OK: decode succeed.
176 * CODEC_ERROR: decode failure.
177 */
111 int (*decode)(const uint8_t *inbuf, size_t inbufsize, 178 int (*decode)(const uint8_t *inbuf, size_t inbufsize,
112 int32_t *outbuf, int *outbufsize); 179 int32_t *outbuf, int *outbufcount);
113}; 180};
114 181
115struct pcm_entry { 182struct pcm_entry {
diff --git a/apps/codecs/libpcm/qt_ima_adpcm.c b/apps/codecs/libpcm/qt_ima_adpcm.c
new file mode 100644
index 0000000000..a34e0e86cd
--- /dev/null
+++ b/apps/codecs/libpcm/qt_ima_adpcm.c
@@ -0,0 +1,136 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "codeclib.h"
22#include "pcm_common.h"
23#include "ima_adpcm_common.h"
24
25/*
26 * Apple QuickTime IMA ADPCM
27 *
28 * References
29 * [1] Multimedia Wiki, Apple QuickTime IMA ADPCM
30 * URL:http://wiki.multimedia.cx/index.php?title=Apple_QuickTime_IMA_ADPCM
31 * [2] Apple Inc., Technical Note TN1081 Understanding the Differences Between
32 * Apple and Windows IMA-ADPCM Compressed Sound Files, 1996
33 * [3] ffmpeg source code, libavcodec/adpcm.c
34 */
35
36static struct pcm_format *fmt;
37
38static bool set_format(struct pcm_format *format)
39{
40 fmt = format;
41
42 if (fmt->bitspersample != 4)
43 {
44 DEBUGF("CODEC_ERROR: quicktime ima adpcm must be 4 bitspersample: %d\n",
45 fmt->bitspersample);
46 return false;
47 }
48
49 fmt->blockalign = 34 * fmt->channels;
50 fmt->samplesperblock = 64;
51
52 /* chunksize = about 1/50[s] data */
53 fmt->chunksize = (ci->id3->frequency / (50 * fmt->samplesperblock))
54 * fmt->blockalign;
55
56 init_ima_adpcm_decoder(4, NULL);
57 return true;
58}
59
60static struct pcm_pos *get_seek_pos(long seek_time,
61 uint8_t *(*read_buffer)(size_t *realsize))
62{
63 static struct pcm_pos newpos;
64 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
65 / (1000LL * fmt->samplesperblock);
66
67 (void)read_buffer;
68 newpos.pos = newblock * fmt->blockalign;
69 newpos.samples = newblock * fmt->samplesperblock;
70 return &newpos;
71}
72
73static int decode(const uint8_t *inbuf, size_t inbufsize,
74 int32_t *outbuf, int *outbufcount)
75{
76 int ch;
77 size_t nsamples = 0;
78 int block_size;
79 int32_t *pcmbuf;
80 int32_t init_pcmdata;
81 int8_t init_index;
82
83 while (inbufsize > 0)
84 {
85 for (ch = 0; ch < fmt->channels; ch++)
86 {
87 /* read block header */
88 init_pcmdata = (inbuf[0] << 8)|(inbuf[1] & 0x80);
89 if (init_pcmdata > 32767)
90 init_pcmdata -= 65536;
91
92 init_index = inbuf[1] & 0x7f;
93 if (init_index > 88)
94 {
95 DEBUGF("CODEC_ERROR: quicktime ima adpcm illegal step index=%d > 88\n",
96 init_index);
97 return CODEC_ERROR;
98 }
99
100 inbuf += 2;
101 inbufsize -= 2;
102
103 set_decode_parameters(1, &init_pcmdata, &init_index);
104
105 /* read block data */
106 pcmbuf = outbuf + ch;
107 for (block_size = 32; block_size > 0 && inbufsize > 0; block_size--, inbufsize--)
108 {
109 *pcmbuf = create_pcmdata_size4(ch, *inbuf ) << 13;
110 pcmbuf += fmt->channels;
111 *pcmbuf = create_pcmdata_size4(ch, *inbuf >> 4) << 13;
112 pcmbuf += fmt->channels;
113 nsamples += 2;
114 inbuf++;
115 }
116 }
117 outbuf += 64 * fmt->channels;
118 }
119
120 if (fmt->channels == 2)
121 nsamples >>= 1;
122 *outbufcount = nsamples;
123
124 return CODEC_OK;
125}
126
127static const struct pcm_codec codec = {
128 set_format,
129 get_seek_pos,
130 decode,
131 };
132
133const struct pcm_codec *get_qt_ima_adpcm_codec(void)
134{
135 return &codec;
136}
diff --git a/apps/codecs/libpcm/support_formats.h b/apps/codecs/libpcm/support_formats.h
index 0a6ea339f4..b1e089e464 100644
--- a/apps/codecs/libpcm/support_formats.h
+++ b/apps/codecs/libpcm/support_formats.h
@@ -18,8 +18,8 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#ifndef CODEC_LIBPCMS_SUPPORT_FORMATS_H 21#ifndef CODEC_LIBPCM_SUPPORT_FORMATS_H
22#define CODEC_LIBPCMS_SUPPORT_FORMATS_H 22#define CODEC_LIBPCM_SUPPORT_FORMATS_H
23 23
24#include "pcm_common.h" 24#include "pcm_common.h"
25 25
@@ -32,9 +32,24 @@ const struct pcm_codec *get_itut_g711_alaw_codec(void);
32/* ITU-T G.711 mu-law */ 32/* ITU-T G.711 mu-law */
33const struct pcm_codec *get_itut_g711_mulaw_codec(void); 33const struct pcm_codec *get_itut_g711_mulaw_codec(void);
34 34
35/* Intel DVI ADPCM */ 35/* Intel DVI ADPCM (IMA ADPCM) */
36const struct pcm_codec *get_dvi_adpcm_codec(void); 36const struct pcm_codec *get_dvi_adpcm_codec(void);
37 37
38/* IEEE float */ 38/* IEEE float */
39const struct pcm_codec *get_ieee_float_codec(void); 39const struct pcm_codec *get_ieee_float_codec(void);
40
41/* Microsoft ADPCM */
42const struct pcm_codec *get_ms_adpcm_codec(void);
43
44/* Dialogic OKI ADPCM */
45const struct pcm_codec *get_dialogic_oki_adpcm_codec(void);
46
47/* YAMAHA ADPCM */
48const struct pcm_codec *get_yamaha_adpcm_codec(void);
49
50/* Apple QuickTime IMA ADPCM */
51const struct pcm_codec *get_qt_ima_adpcm_codec(void);
52
53/* Adobe SWF ADPCM */
54const struct pcm_codec *get_swf_adpcm_codec(void);
40#endif 55#endif
diff --git a/apps/codecs/libpcm/swf_adpcm.c b/apps/codecs/libpcm/swf_adpcm.c
new file mode 100644
index 0000000000..456e1cdd4c
--- /dev/null
+++ b/apps/codecs/libpcm/swf_adpcm.c
@@ -0,0 +1,233 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "codeclib.h"
22#include "pcm_common.h"
23#include "ima_adpcm_common.h"
24
25/*
26 * Adobe SWF ADPCM
27 *
28 * References
29 * [1] Adobe, SWF File Format Specification Version 10, 2008
30 * [2] Jack Jansen, adpcm.c in adpcm.zip
31 * [3] ffmpeg source code, libavcodec/adpcm.c
32 */
33
34/* step index table when bitspersample is 3.
35 * (when bitspersample is 2, 4, 5, step index table uses the table
36 * which is defined ima_adpcm_common.c.)
37 */
38static const int index_table[4] ICONST_ATTR = {
39 -1, -1, 2, 4,
40};
41
42static int validity_bits = 8;
43static bool first_block = true;
44static int blockbits = 0;
45static int lastbytebits = 0;
46static bool after_seek = false;
47
48static struct pcm_format *fmt;
49
50static bool set_format(struct pcm_format *format)
51{
52 fmt = format;
53
54 if (fmt->bitspersample < 2 || fmt->bitspersample > 5)
55 {
56 DEBUGF("CODEC_ERROR: swf adpcm must be 2, 3, 4 or 5 bitspersample: %d\n",
57 fmt->bitspersample);
58 return false;
59 }
60
61 if (fmt->samplesperblock == 0)
62 fmt->samplesperblock = (((fmt->blockalign << 3) - 2) / fmt->channels - 22)
63 / fmt->bitspersample + 1;
64
65 blockbits = ((fmt->samplesperblock - 1) * fmt->bitspersample + 22) * fmt->channels;
66
67 /*
68 * chunksize = about 93 [ms] data (frequency:44.1kHz, 4096 [sample/block])
69 * chunksize changes depending upon the position of block.
70 */
71 fmt->chunksize = (blockbits + 9) >> 3;
72
73 /* initialize for ima adpcm common functions */
74 if (fmt->bitspersample == 3)
75 init_ima_adpcm_decoder(fmt->bitspersample, index_table);
76 else
77 init_ima_adpcm_decoder(fmt->bitspersample, NULL);
78
79 return true;
80}
81
82static struct pcm_pos *get_seek_pos(long seek_time,
83 uint8_t *(*read_buffer)(size_t *realsize))
84{
85 static struct pcm_pos newpos;
86 uint32_t chunkbits = blockbits;
87 uint32_t seekbits = (((uint64_t)seek_time * ci->id3->frequency)
88 / (1000LL * fmt->samplesperblock)) * blockbits + 2;
89
90 (void)read_buffer;
91
92 newpos.pos = seekbits >> 3;
93 newpos.samples = (((uint64_t)seek_time * ci->id3->frequency)
94 / (1000LL * fmt->samplesperblock))
95 * fmt->samplesperblock;
96
97 if (newpos.pos == 0)
98 {
99 first_block = true;
100 lastbytebits = 0;
101 }
102 else
103 {
104 first_block = false;
105 lastbytebits = seekbits & 0x07;
106 if (lastbytebits != 0)
107 chunkbits -= (8 - lastbytebits);
108 }
109
110 /* calculates next read bytes */
111 fmt->chunksize = (chunkbits >> 3) + (((chunkbits & 0x07) > 0)?1:0)
112 + ((lastbytebits > 0)?1:0);
113
114 after_seek = true;
115 return &newpos;
116}
117
118static uint8_t get_data(const uint8_t **buf, int bit)
119{
120 uint8_t res = 0;
121 uint8_t mask = (1 << bit) - 1;
122
123 if (validity_bits >= bit)
124 {
125 validity_bits -= bit;
126 return (**buf >> validity_bits) & mask;
127 }
128
129 if (validity_bits > 0)
130 res = **buf << (bit - validity_bits);
131
132 validity_bits += 8 - bit;
133 res = (res | (*(++(*buf)) >> validity_bits)) & mask;
134 return res;
135}
136
137static int decode(const uint8_t *inbuf, size_t inbufsize,
138 int32_t *outbuf, int *outbufcount)
139{
140 int ch;
141 int adpcm_code_size;
142 int count = fmt->samplesperblock;
143 int32_t init_pcmdata[2];
144 int8_t init_index[2];
145 static uint8_t lastbyte = 0;
146
147 (void)inbufsize;
148
149 validity_bits = 8;
150
151 /* read block header */
152 ch = fmt->channels - 1;
153 if (first_block)
154 {
155 adpcm_code_size = get_data(&inbuf, 2) + 2;
156 if (fmt->bitspersample != adpcm_code_size)
157 {
158 DEBUGF("CODEC_ERROR: swf adpcm different adpcm code size=%d != %d\n",
159 adpcm_code_size, fmt->bitspersample);
160 return CODEC_ERROR;
161 }
162 init_pcmdata[0] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8);
163
164 lastbytebits = 0;
165 first_block = false;
166 }
167 else
168 {
169 if (after_seek && lastbytebits > 0)
170 {
171 lastbyte = *inbuf++;
172 after_seek = false;
173 }
174 if (lastbytebits > 0)
175 init_pcmdata[0] = ((lastbyte << (8 + lastbytebits)) |
176 (get_data(&inbuf, 8) << lastbytebits) |
177 get_data(&inbuf, lastbytebits)) & 65535;
178 else
179 init_pcmdata[0] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8);
180 }
181 after_seek = false;
182
183 init_index[0] = get_data(&inbuf, 6);
184 if (init_pcmdata[0] > 32767)
185 init_pcmdata[0] -= 65536;
186
187 if (ch > 0)
188 {
189 init_pcmdata[1] = (get_data(&inbuf, 8) << 8) | get_data(&inbuf, 8);
190 init_index[1] = get_data(&inbuf, 6);
191 if (init_pcmdata[1] > 32767)
192 init_pcmdata[1] -= 65536;
193 }
194
195 *outbuf++ = init_pcmdata[0] << 13;
196 if (ch > 0)
197 *outbuf++ = init_pcmdata[1] << 13;
198
199 set_decode_parameters(fmt->channels, init_pcmdata, init_index);
200
201 /* read block data */
202 while (--count > 0)
203 {
204 *outbuf++ = create_pcmdata(0, get_data(&inbuf, fmt->bitspersample)) << 13;
205 if (ch > 0)
206 *outbuf++ = create_pcmdata(ch, get_data(&inbuf, fmt->bitspersample)) << 13;
207 }
208
209 *outbufcount = fmt->samplesperblock;
210
211 lastbyte = *inbuf;
212 lastbytebits = (8 - validity_bits) & 0x07;
213
214 /* calculates next read bytes */
215 fmt->chunksize = (blockbits - validity_bits + 7) >> 3;
216
217 return CODEC_OK;
218}
219
220static const struct pcm_codec codec = {
221 set_format,
222 get_seek_pos,
223 decode,
224 };
225
226const struct pcm_codec *get_swf_adpcm_codec(void)
227{
228 first_block = true;
229 lastbytebits = 0;
230 after_seek = false;
231
232 return &codec;
233}
diff --git a/apps/codecs/libpcm/yamaha_adpcm.c b/apps/codecs/libpcm/yamaha_adpcm.c
new file mode 100644
index 0000000000..6b3daa8f83
--- /dev/null
+++ b/apps/codecs/libpcm/yamaha_adpcm.c
@@ -0,0 +1,245 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "codeclib.h"
22#include "pcm_common.h"
23#include "adpcm_seek.h"
24
25/*
26 * YAMAHA ADPCM
27 *
28 * References
29 * [1] YAMAHA, YAMAHA ADPCM ACM Driver Version 1.0.0.0, 2005
30 * [2] BlendWorks, YM2608 ADPCM,
31 * http://web.archive.org/web/20050208190547/www.memb.jp/~dearna/ma/ym2608/adpcm.html
32 * [3] Naoyuki Sawa, ADPCM no shikumi #1,
33 * http://www.piece-me.org/piece-lab/adpcm/adpcm1.html
34 * [4] ffmpeg source code, libavcodec/adpcm.c
35 */
36
37/* ADPCM data block layout
38 *
39 * when the block header exists. (for example, encoding by YAMAHA ADPCM ACM Driver)
40 * blockAlign = (frequency / 60 + 4) * channels.
41 *
42 * block
43 * <Mono> (channels = 1)
44 * int16_t first value (Little endian)
45 * uint16_t first predictor (Little endian)
46 * uint8_t ADPCM data (1st data: 0-3 bit, 2nd data: 4-7 bit)
47 * ....
48 *
49 * <Stereo> (channels = 2)
50 * int16_t Left channel first value (Little endian)
51 * uint16_t Left channel first predictor (Little endian)
52 * int16_t Right channel first value (Little endian)
53 * uint16_t Right channel first predictor (Little endian)
54 * uint8_t ADPCM data (Left channel: 0-3 bit, Right channel: 4-7 bit)
55 * ....
56 *
57 * when the block header does not exist. (for example, encoding by ffmpeg)
58 * blockAlign = 8000
59 *
60 * block
61 * <Mono> (channels = 1)
62 * uint8_t ADPCM data (1st data: 0-3 bit, 2nd data: 4-7 bit)
63 * ....
64 *
65 * <Stereo> (channels = 2)
66 * uint8_t ADPCM data (Left channel: 0-3 bit, Right channel: 4-7 bit)
67 * ....
68 */
69
70static const int32_t amplification_table[] ICONST_ATTR = {
71 230, 230, 230, 230, 307, 409, 512, 614, 230, 230, 230, 230, 307, 409, 512, 614
72};
73
74static bool has_block_header = false;
75
76static struct adpcm_data cur_data;
77static int blocksperchunk;
78
79static struct pcm_format *fmt;
80
81static bool set_format(struct pcm_format *format)
82{
83 fmt = format;
84
85 if (fmt->bitspersample != 4)
86 {
87 DEBUGF("CODEC_ERROR: yamaha adpcm must be 4 bitspersample: %d\n",
88 fmt->bitspersample);
89 return false;
90 }
91
92 /* check exists block header */
93 if (fmt->blockalign == ((ci->id3->frequency / 60) + 4) * fmt->channels)
94 {
95 has_block_header = true;
96
97 /* chunksize = about 1/30 [sec] data */
98 fmt->chunksize = fmt->blockalign;
99 blocksperchunk = 1;
100 }
101 else
102 {
103 uint32_t max_chunk_count;
104
105 has_block_header = false;
106
107 /* blockalign = 2 * channels samples */
108 fmt->blockalign = fmt->channels;
109 fmt->samplesperblock = 2;
110
111 /* chunksize = about 1/32[sec] data */
112 blocksperchunk = ci->id3->frequency >> 6;
113 fmt->chunksize = blocksperchunk * fmt->blockalign;
114
115 max_chunk_count = (uint64_t)ci->id3->length * ci->id3->frequency
116 / (2000LL * fmt->chunksize / fmt->channels);
117
118 /* initialize seek table */
119 init_seek_table(max_chunk_count);
120 /* add first data */
121 add_adpcm_data(&cur_data);
122 }
123
124 return true;
125}
126
127static int16_t create_pcmdata(int ch, uint8_t nibble)
128{
129 int32_t tmp_pcmdata = cur_data.pcmdata[ch];
130 int32_t step = cur_data.step[ch];
131 int32_t delta = step >> 3;
132
133 if (nibble & 4) delta += step;
134 if (nibble & 2) delta += (step >> 1);
135 if (nibble & 1) delta += (step >> 2);
136
137 if (nibble & 0x08)
138 tmp_pcmdata -= delta;
139 else
140 tmp_pcmdata += delta;
141
142 CLIP(tmp_pcmdata, -32768, 32767);
143 cur_data.pcmdata[ch] = tmp_pcmdata;
144
145 step = (step * amplification_table[nibble & 0x07]) >> 8;
146 CLIP(step, 127, 24576);
147 cur_data.step[ch] = step;
148
149 return cur_data.pcmdata[ch];
150}
151
152static int decode(const uint8_t *inbuf, size_t inbufsize,
153 int32_t *outbuf, int *outbufcount)
154{
155 int ch;
156 size_t nsamples = 0;
157
158 /* read block header */
159 if (has_block_header)
160 {
161 for (ch = 0; ch < fmt->channels; ch++)
162 {
163 cur_data.pcmdata[ch] = inbuf[0] | (SE(inbuf[1]) << 8);
164 cur_data.step[ch] = inbuf[2] | (inbuf[3] << 8);
165
166 inbuf += 4;
167 inbufsize -= 4;
168 }
169 }
170
171 /* read block data */
172 ch = fmt->channels - 1;
173 while (inbufsize)
174 {
175 *outbuf++ = create_pcmdata(0, *inbuf ) << 13;
176 *outbuf++ = create_pcmdata(ch, *inbuf >> 4) << 13;
177 nsamples += 2;
178
179 inbuf++;
180 inbufsize--;
181 }
182
183 if (fmt->channels == 2)
184 nsamples >>= 1;
185 *outbufcount = nsamples;
186
187 if (!has_block_header)
188 add_adpcm_data(&cur_data);
189
190 return CODEC_OK;
191}
192
193static int decode_for_seek(const uint8_t *inbuf, size_t inbufsize)
194{
195 int ch = fmt->channels - 1;
196
197 while (inbufsize)
198 {
199 create_pcmdata(0, *inbuf );
200 create_pcmdata(ch, *inbuf >> 4);
201
202 inbuf++;
203 inbufsize--;
204 }
205
206 add_adpcm_data(&cur_data);
207
208 return CODEC_OK;
209}
210
211static struct pcm_pos *get_seek_pos(long seek_time,
212 uint8_t *(*read_buffer)(size_t *realsize))
213{
214 static struct pcm_pos newpos;
215 uint32_t new_count= 0;
216
217 if (seek_time > 0)
218 new_count = ((uint64_t)seek_time * ci->id3->frequency
219 / (1000LL * fmt->samplesperblock)) / blocksperchunk;
220
221 if (!has_block_header)
222 {
223 new_count = seek(new_count, &cur_data, read_buffer, &decode_for_seek);
224 }
225 newpos.pos = new_count * fmt->chunksize;
226 newpos.samples = new_count * blocksperchunk * fmt->samplesperblock;
227 return &newpos;
228}
229
230static struct pcm_codec codec = {
231 set_format,
232 get_seek_pos,
233 decode,
234 };
235
236const struct pcm_codec *get_yamaha_adpcm_codec(void)
237{
238 /* initialize first step, pcm data */
239 cur_data.pcmdata[0] = 0;
240 cur_data.pcmdata[1] = 0;
241 cur_data.step[0] = 127;
242 cur_data.step[1] = 127;
243
244 return &codec;
245}
diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c
index a642f99a0f..293089a737 100644
--- a/apps/codecs/wav.c
+++ b/apps/codecs/wav.c
@@ -45,27 +45,37 @@ enum
45{ 45{
46 WAVE_FORMAT_UNKNOWN = 0x0000, /* Microsoft Unknown Wave Format */ 46 WAVE_FORMAT_UNKNOWN = 0x0000, /* Microsoft Unknown Wave Format */
47 WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */ 47 WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */
48 WAVE_FORMAT_ADPCM = 0x0002, /* Microsoft ADPCM Format */
48 WAVE_FORMAT_IEEE_FLOAT = 0x0003, /* IEEE Float */ 49 WAVE_FORMAT_IEEE_FLOAT = 0x0003, /* IEEE Float */
49 WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */ 50 WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */
50 WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */ 51 WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */
51 WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */ 52 WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */
53 WAVE_FORMAT_DIALOGIC_OKI_ADPCM = 0x0017, /* Dialogic OKI ADPCM */
54 WAVE_FORMAT_YAMAHA_ADPCM = 0x0020, /* Yamaha ADPCM */
55 WAVE_FORMAT_XBOX_ADPCM = 0x0069, /* XBOX ADPCM */
52 IBM_FORMAT_MULAW = 0x0101, /* same as WAVE_FORMAT_MULAW */ 56 IBM_FORMAT_MULAW = 0x0101, /* same as WAVE_FORMAT_MULAW */
53 IBM_FORMAT_ALAW = 0x0102, /* same as WAVE_FORMAT_ALAW */ 57 IBM_FORMAT_ALAW = 0x0102, /* same as WAVE_FORMAT_ALAW */
58 WAVE_FORMAT_SWF_ADPCM = 0x5346, /* Adobe SWF ADPCM */
54 WAVE_FORMAT_EXTENSIBLE = 0xFFFE 59 WAVE_FORMAT_EXTENSIBLE = 0xFFFE
55}; 60};
56 61
57const struct pcm_entry wave_codecs[] = { 62const struct pcm_entry wave_codecs[] = {
58 { WAVE_FORMAT_UNKNOWN, 0 }, 63 { WAVE_FORMAT_UNKNOWN, 0 },
59 { WAVE_FORMAT_PCM, get_linear_pcm_codec }, 64 { WAVE_FORMAT_PCM, get_linear_pcm_codec },
65 { WAVE_FORMAT_ADPCM, get_ms_adpcm_codec },
60 { WAVE_FORMAT_IEEE_FLOAT, get_ieee_float_codec }, 66 { WAVE_FORMAT_IEEE_FLOAT, get_ieee_float_codec },
61 { WAVE_FORMAT_ALAW, get_itut_g711_alaw_codec }, 67 { WAVE_FORMAT_ALAW, get_itut_g711_alaw_codec },
62 { WAVE_FORMAT_MULAW, get_itut_g711_mulaw_codec }, 68 { WAVE_FORMAT_MULAW, get_itut_g711_mulaw_codec },
63 { WAVE_FORMAT_DVI_ADPCM, get_dvi_adpcm_codec }, 69 { WAVE_FORMAT_DVI_ADPCM, get_dvi_adpcm_codec },
70 { WAVE_FORMAT_DIALOGIC_OKI_ADPCM, get_dialogic_oki_adpcm_codec },
71 { WAVE_FORMAT_YAMAHA_ADPCM, get_yamaha_adpcm_codec },
72 { WAVE_FORMAT_XBOX_ADPCM, get_dvi_adpcm_codec },
64 { IBM_FORMAT_MULAW, get_itut_g711_mulaw_codec }, 73 { IBM_FORMAT_MULAW, get_itut_g711_mulaw_codec },
65 { IBM_FORMAT_ALAW, get_itut_g711_alaw_codec }, 74 { IBM_FORMAT_ALAW, get_itut_g711_alaw_codec },
75 { WAVE_FORMAT_SWF_ADPCM, get_swf_adpcm_codec },
66}; 76};
67 77
68#define NUM_FORMATS 8 78#define NUM_FORMATS 13
69 79
70static const struct pcm_codec *get_wave_codec(uint32_t formattag) 80static const struct pcm_codec *get_wave_codec(uint32_t formattag)
71{ 81{
@@ -83,13 +93,67 @@ static const struct pcm_codec *get_wave_codec(uint32_t formattag)
83 return 0; 93 return 0;
84} 94}
85 95
96static struct pcm_format format;
97static uint32_t bytesdone;
98
99static bool set_msadpcm_coeffs(const uint8_t *buf)
100{
101 int i;
102 int num;
103 int size;
104
105 buf += 4; /* skip 'fmt ' */
106 size = buf[0] | (buf[1] << 8) | (buf[1] << 16) | (buf[1] << 24);
107 if (size < 50)
108 {
109 DEBUGF("CODEC_ERROR: microsoft adpcm 'fmt ' chunk size=%lu < 50\n",
110 (unsigned long)size);
111 return false;
112 }
113
114 /* get nNumCoef */
115 buf += 24;
116 num = buf[0] | (buf[1] << 8);
117
118 /*
119 * In many case, nNumCoef is 7.
120 * Depending upon the encoder, as for this value there is a possibility of
121 * increasing more.
122 * If you found the file where this value exceeds 7, please report.
123 */
124 if (num != MSADPCM_NUM_COEFF)
125 {
126 DEBUGF("CODEC_ERROR: microsoft adpcm nNumCoef=%d != 7\n", num);
127 return false;
128 }
129
130 /* get aCoeffs */
131 buf += 2;
132 for (i = 0; i < MSADPCM_NUM_COEFF; i++)
133 {
134 format.coeffs[i][0] = buf[0] | (SE(buf[1]) << 8);
135 format.coeffs[i][1] = buf[2] | (SE(buf[3]) << 8);
136 buf += 4;
137 }
138
139 return true;
140}
141
142static uint8_t *read_buffer(size_t *realsize)
143{
144 uint8_t *buffer = (uint8_t *)ci->request_buffer(realsize, format.chunksize);
145 if (bytesdone + (*realsize) > format.numbytes)
146 *realsize = format.numbytes - bytesdone;
147 bytesdone += *realsize;
148 ci->advance_buffer(*realsize);
149 return buffer;
150}
86 151
87/* this is the codec entry point */ 152/* this is the codec entry point */
88enum codec_status codec_main(void) 153enum codec_status codec_main(void)
89{ 154{
90 int status = CODEC_OK; 155 int status = CODEC_OK;
91 struct pcm_format format; 156 uint32_t decodedsamples;
92 uint32_t bytesdone, decodedbytes;
93 uint32_t i; 157 uint32_t i;
94 size_t n; 158 size_t n;
95 int bufcount; 159 int bufcount;
@@ -125,6 +189,7 @@ next_track:
125 goto done; 189 goto done;
126 } 190 }
127 if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0)) { 191 if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0)) {
192 DEBUGF("CODEC_ERROR: missing riff header\n");
128 status = CODEC_ERROR; 193 status = CODEC_ERROR;
129 goto done; 194 goto done;
130 } 195 }
@@ -137,7 +202,7 @@ next_track:
137 format.is_signed = true; 202 format.is_signed = true;
138 format.is_little_endian = true; 203 format.is_little_endian = true;
139 204
140 decodedbytes = 0; 205 decodedsamples = 0;
141 codec = 0; 206 codec = 0;
142 207
143 /* iterate over WAVE chunks until the 'data' chunk, which should be after the 'fmt ' chunk */ 208 /* iterate over WAVE chunks until the 'data' chunk, which should be after the 'fmt ' chunk */
@@ -200,11 +265,21 @@ next_track:
200 } 265 }
201 } 266 }
202 267
268 /* msadpcm specific */
269 if (format.formattag == WAVE_FORMAT_ADPCM)
270 {
271 if (!set_msadpcm_coeffs(buf))
272 {
273 status = CODEC_ERROR;
274 goto done;
275 }
276 }
277
203 /* get codec */ 278 /* get codec */
204 codec = get_wave_codec(format.formattag); 279 codec = get_wave_codec(format.formattag);
205 if (!codec) 280 if (!codec)
206 { 281 {
207 DEBUGF("CODEC_ERROR: unsupported wave format %x\n", 282 DEBUGF("CODEC_ERROR: unsupported wave format 0x%x\n",
208 (unsigned int) format.formattag); 283 (unsigned int) format.formattag);
209 status = CODEC_ERROR; 284 status = CODEC_ERROR;
210 goto done; 285 goto done;
@@ -215,7 +290,7 @@ next_track:
215 format.is_signed = false; 290 format.is_signed = false;
216 291
217 /* set format, parse codec specific tag, check format, and calculate chunk size */ 292 /* set format, parse codec specific tag, check format, and calculate chunk size */
218 if (!codec->set_format(&format, buf)) 293 if (!codec->set_format(&format))
219 { 294 {
220 status = CODEC_ERROR; 295 status = CODEC_ERROR;
221 goto done; 296 goto done;
@@ -256,12 +331,34 @@ next_track:
256 status = CODEC_ERROR; 331 status = CODEC_ERROR;
257 goto done; 332 goto done;
258 } 333 }
334 if (format.samplesperblock == 0) {
335 DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-wSamplesPerBlock file\n");
336 status = CODEC_ERROR;
337 goto done;
338 }
339 if (format.blockalign == 0)
340 {
341 DEBUGF("CODEC_ERROR: 'fmt ' chunk not found or 0-blockalign file\n");
342 i = CODEC_ERROR;
343 goto done;
344 }
259 if (format.numbytes == 0) { 345 if (format.numbytes == 0) {
260 DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n"); 346 DEBUGF("CODEC_ERROR: 'data' chunk not found or has zero-length\n");
261 status = CODEC_ERROR; 347 status = CODEC_ERROR;
262 goto done; 348 goto done;
263 } 349 }
264 350
351 /* check chunksize */
352 if ((format.chunksize / format.blockalign) * format.samplesperblock * format.channels
353 > PCM_CHUNK_SIZE)
354 format.chunksize = (PCM_CHUNK_SIZE / format.blockalign) * format.blockalign;
355 if (format.chunksize == 0)
356 {
357 DEBUGF("CODEC_ERROR: chunksize is 0\n");
358 i = CODEC_ERROR;
359 goto done;
360 }
361
265 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); 362 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
266 if (format.channels == 2) { 363 if (format.channels == 2) {
267 ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); 364 ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED);
@@ -295,13 +392,14 @@ next_track:
295 } 392 }
296 393
297 if (ci->seek_time) { 394 if (ci->seek_time) {
298 uint32_t newpos = codec->get_seek_pos(ci->seek_time); 395 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, &read_buffer);
299 396
300 if (newpos > format.numbytes) 397 decodedsamples = newpos->samples;
398 if (newpos->pos > format.numbytes)
301 break; 399 break;
302 if (ci->seek_buffer(firstblockposn + newpos)) 400 if (ci->seek_buffer(firstblockposn + newpos->pos))
303 { 401 {
304 bytesdone = newpos; 402 bytesdone = newpos->pos;
305 } 403 }
306 ci->seek_complete(); 404 ci->seek_complete();
307 } 405 }
@@ -324,11 +422,11 @@ next_track:
324 ci->pcmbuf_insert(samples, NULL, bufcount); 422 ci->pcmbuf_insert(samples, NULL, bufcount);
325 ci->advance_buffer(n); 423 ci->advance_buffer(n);
326 bytesdone += n; 424 bytesdone += n;
327 decodedbytes += bufcount; 425 decodedsamples += bufcount;
328 426
329 if (bytesdone >= format.numbytes) 427 if (bytesdone >= format.numbytes)
330 endofstream = 1; 428 endofstream = 1;
331 ci->set_elapsed(decodedbytes*1000LL/ci->id3->frequency); 429 ci->set_elapsed(decodedsamples*1000LL/ci->id3->frequency);
332 } 430 }
333 status = CODEC_OK; 431 status = CODEC_OK;
334 432
diff --git a/apps/metadata/aiff.c b/apps/metadata/aiff.c
index 67fb43b8c6..aba327f8c8 100644
--- a/apps/metadata/aiff.c
+++ b/apps/metadata/aiff.c
@@ -29,6 +29,9 @@
29#include "metadata_common.h" 29#include "metadata_common.h"
30#include "metadata_parsers.h" 30#include "metadata_parsers.h"
31 31
32/* compressionType: AIFC QuickTime IMA ADPCM */
33#define AIFC_FORMAT_QT_IMA_ADPCM "ima4"
34
32bool get_aiff_metadata(int fd, struct mp3entry* id3) 35bool get_aiff_metadata(int fd, struct mp3entry* id3)
33{ 36{
34 /* Use the trackname part of the id3 structure as a temporary buffer */ 37 /* Use the trackname part of the id3 structure as a temporary buffer */
@@ -40,6 +43,7 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
40 unsigned long numbytes = 0; 43 unsigned long numbytes = 0;
41 int read_bytes; 44 int read_bytes;
42 int i; 45 int i;
46 bool is_aifc = false;
43 47
44 if ((lseek(fd, 0, SEEK_SET) < 0) 48 if ((lseek(fd, 0, SEEK_SET) < 0)
45 || ((read_bytes = read(fd, buf, sizeof(id3->path))) < 54)) 49 || ((read_bytes = read(fd, buf, sizeof(id3->path))) < 54))
@@ -47,10 +51,15 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
47 return false; 51 return false;
48 } 52 }
49 53
50 if ((memcmp(buf, "FORM",4) != 0) 54 if (memcmp(buf, "FORM",4) != 0)
51 || ((memcmp(&buf[8], "AIFF", 4) !=0) && (memcmp(&buf[8], "AIFC", 4) !=0)))
52 {
53 return false; 55 return false;
56
57 if (memcmp(&buf[8], "AIFF", 4) != 0)
58 {
59 if (memcmp(&buf[8], "AIFC", 4) != 0)
60 return false;
61
62 is_aifc = true;
54 } 63 }
55 64
56 buf += 12; 65 buf += 12;
@@ -75,7 +84,13 @@ bool get_aiff_metadata(int fd, struct mp3entry* id3)
75 /* save format infos */ 84 /* save format infos */
76 id3->bitrate = (sampleSize * numChannels * sampleRate) / 1000; 85 id3->bitrate = (sampleSize * numChannels * sampleRate) / 1000;
77 id3->frequency = sampleRate; 86 id3->frequency = sampleRate;
78 id3->length = ((int64_t) numSampleFrames * 1000) / id3->frequency; 87 if (!is_aifc || memcmp(&buf[26], AIFC_FORMAT_QT_IMA_ADPCM, 4) != 0)
88 id3->length = ((int64_t) numSampleFrames * 1000) / id3->frequency;
89 else
90 {
91 /* QuickTime IMA ADPCM is 1block = 64 data for each channel */
92 id3->length = (int64_t)(numSampleFrames * 64000LL) / id3->frequency;
93 }
79 94
80 id3->vbr = false; /* AIFF files are CBR */ 95 id3->vbr = false; /* AIFF files are CBR */
81 id3->filesize = filesize(fd); 96 id3->filesize = filesize(fd);
diff --git a/apps/metadata/wave.c b/apps/metadata/wave.c
index acef32dd38..79bb8178bd 100644
--- a/apps/metadata/wave.c
+++ b/apps/metadata/wave.c
@@ -28,6 +28,7 @@
28#include "metadata.h" 28#include "metadata.h"
29#include "metadata_common.h" 29#include "metadata_common.h"
30#include "metadata_parsers.h" 30#include "metadata_parsers.h"
31#include "logf.h"
31 32
32# define AV_WL32(p, d) do { \ 33# define AV_WL32(p, d) do { \
33 ((uint8_t*)(p))[0] = (d); \ 34 ((uint8_t*)(p))[0] = (d); \
@@ -40,29 +41,101 @@
40 ((uint8_t*)(p))[1] = (d)>>8; \ 41 ((uint8_t*)(p))[1] = (d)>>8; \
41 } while(0) 42 } while(0)
42 43
44enum
45{
46 WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */
47 WAVE_FORMAT_ADPCM = 0x0002, /* Microsoft ADPCM Format */
48 WAVE_FORMAT_IEEE_FLOAT = 0x0003, /* IEEE Float */
49 WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */
50 WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */
51 WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */
52 WAVE_FORMAT_DIALOGIC_OKI_ADPCM = 0x0017, /* Dialogic OKI ADPCM */
53 WAVE_FORMAT_YAMAHA_ADPCM = 0x0020, /* Yamaha ADPCM */
54 WAVE_FORMAT_XBOX_ADPCM = 0x0069, /* XBOX ADPCM */
55 IBM_FORMAT_MULAW = 0x0101, /* same as WAVE_FORMAT_MULAW */
56 IBM_FORMAT_ALAW = 0x0102, /* same as WAVE_FORMAT_ALAW */
57 WAVE_FORMAT_ATRAC3 = 0x0270, /* Atrac3 stream */
58 WAVE_FORMAT_SWF_ADPCM = 0x5346, /* Adobe SWF ADPCM */
59};
60
61struct wave_fmt {
62 unsigned int formattag;
63 unsigned long channels;
64 unsigned int blockalign;
65 unsigned long bitspersample;
66 unsigned int samplesperblock;
67 unsigned long numbytes;
68};
69
70static unsigned long get_totalsamples(struct wave_fmt *fmt, struct mp3entry* id3)
71{
72 unsigned long totalsamples = 0;
73
74 switch (fmt->formattag)
75 {
76 case WAVE_FORMAT_PCM:
77 case WAVE_FORMAT_IEEE_FLOAT:
78 case WAVE_FORMAT_ALAW:
79 case WAVE_FORMAT_MULAW:
80 case IBM_FORMAT_ALAW:
81 case IBM_FORMAT_MULAW:
82 totalsamples =
83 fmt->numbytes / ((((fmt->bitspersample - 1) / 8) + 1) * fmt->channels);
84 break;
85 case WAVE_FORMAT_ADPCM:
86 case WAVE_FORMAT_DVI_ADPCM:
87 case WAVE_FORMAT_XBOX_ADPCM:
88 totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock;
89 break;
90 case WAVE_FORMAT_YAMAHA_ADPCM:
91 if (fmt->samplesperblock == 0)
92 {
93 if (fmt->blockalign == ((id3->frequency / 60) + 4) * fmt->channels)
94 fmt->samplesperblock = id3->frequency / 30;
95 else
96 fmt->samplesperblock = fmt->blockalign * 2 / fmt->channels;
97 }
98 totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock;
99 break;
100 case WAVE_FORMAT_DIALOGIC_OKI_ADPCM:
101 totalsamples = 2 * fmt->numbytes;
102 break;
103 case WAVE_FORMAT_SWF_ADPCM:
104 if (fmt->samplesperblock == 0)
105 fmt->samplesperblock = (((fmt->blockalign << 3) - 2) / fmt->channels - 22)
106 / fmt->bitspersample;
107
108 totalsamples = (fmt->numbytes / fmt->blockalign) * fmt->samplesperblock;
109 break;
110 default:
111 totalsamples = 0;
112 break;
113 }
114 return totalsamples;
115}
116
43bool get_wave_metadata(int fd, struct mp3entry* id3) 117bool get_wave_metadata(int fd, struct mp3entry* id3)
44{ 118{
45 /* Use the trackname part of the id3 structure as a temporary buffer */ 119 /* Use the trackname part of the id3 structure as a temporary buffer */
46 unsigned char* buf = (unsigned char *)id3->path; 120 unsigned char* buf = (unsigned char *)id3->path;
121 struct wave_fmt fmt;
47 unsigned long totalsamples = 0; 122 unsigned long totalsamples = 0;
48 unsigned long channels = 0;
49 unsigned long bitspersample = 0;
50 unsigned long numbytes = 0;
51 unsigned long offset = 0; 123 unsigned long offset = 0;
52 int read_bytes; 124 int read_bytes;
53 int i; 125 int i;
54 126
127 memset(&fmt, 0, sizeof(struct wave_fmt));
128
55 /* get RIFF chunk header */ 129 /* get RIFF chunk header */
56 if ((lseek(fd, 0, SEEK_SET) < 0) 130 if ((lseek(fd, 0, SEEK_SET) < 0) || (read(fd, buf, 12) < 12))
57 || ((read_bytes = read(fd, buf, 12)) < 12))
58 { 131 {
59 return false; 132 return false;
60 } 133 }
61 offset += 12; 134 offset += 12;
62 135
63 if ((memcmp(buf, "RIFF",4) != 0) 136 if ((memcmp(buf, "RIFF", 4) != 0) || (memcmp(&buf[8], "WAVE", 4) != 0))
64 || (memcmp(&buf[8], "WAVE", 4) !=0 ))
65 { 137 {
138 DEBUGF("metadata error: missing riff header.\n");
66 return false; 139 return false;
67 } 140 }
68 141
@@ -70,7 +143,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
70 while (true) 143 while (true)
71 { 144 {
72 /* get chunk header */ 145 /* get chunk header */
73 if ((read_bytes = read(fd, buf, 8)) < 8) 146 if (read(fd, buf, 8) < 8)
74 return false; 147 return false;
75 offset += 8; 148 offset += 8;
76 149
@@ -80,26 +153,41 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
80 if (memcmp(buf, "fmt ", 4) == 0) 153 if (memcmp(buf, "fmt ", 4) == 0)
81 { 154 {
82 /* get rest of chunk */ 155 /* get rest of chunk */
83 if ((read_bytes = read(fd, buf, 16)) < 16) 156 if (i < 16)
84 return false; 157 return false;
85 offset += 16;
86 i -= 16;
87 158
159 read_bytes = 16;
160 if (i > 19)
161 read_bytes = 20;
88 162
89 /* skipping wFormatTag */ 163 if (read(fd, buf, read_bytes) != read_bytes)
164 return false;
165
166 offset += read_bytes;
167 i -= read_bytes;
168
169 /* wFormatTag */
170 fmt.formattag = buf[0] | (buf[1] << 8);
90 /* wChannels */ 171 /* wChannels */
91 channels = buf[2] | (buf[3] << 8); 172 fmt.channels = buf[2] | (buf[3] << 8);
92 /* dwSamplesPerSec */ 173 /* dwSamplesPerSec */
93 id3->frequency = get_long_le(&buf[4]); 174 id3->frequency = get_long_le(&buf[4]);
94 /* dwAvgBytesPerSec */ 175 /* dwAvgBytesPerSec */
95 id3->bitrate = (get_long_le(&buf[8]) * 8) / 1000; 176 id3->bitrate = (get_long_le(&buf[8]) * 8) / 1000;
96 /* wBlockAlign */ 177 /* wBlockAlign */
97 id3->bytesperframe = buf[12] | (buf[13] << 8); 178 fmt.blockalign = buf[12] | (buf[13] << 8);
179 id3->bytesperframe = fmt.blockalign;
98 /* wBitsPerSample */ 180 /* wBitsPerSample */
99 bitspersample = buf[14] | (buf[15] << 8); 181 fmt.bitspersample = buf[14] | (buf[15] << 8);
182 if (read_bytes > 19)
183 {
184 /* wSamplesPerBlock */
185 fmt.samplesperblock = buf[18] | (buf[19] << 8);
186 }
187
100 /* Check for ATRAC3 stream */ 188 /* Check for ATRAC3 stream */
101 if((buf[0] | (buf[1] << 8)) == 0x0270) 189 if (fmt.formattag == WAVE_FORMAT_ATRAC3)
102 { 190 {
103 int jsflag = 0; 191 int jsflag = 0;
104 if(id3->bitrate == 66 || id3->bitrate == 94) 192 if(id3->bitrate == 66 || id3->bitrate == 94)
105 jsflag = 1; 193 jsflag = 1;
@@ -107,7 +195,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
107 id3->extradata_size = 14; 195 id3->extradata_size = 14;
108 id3->channels = 2; 196 id3->channels = 2;
109 id3->codectype = AFMT_OMA_ATRAC3; 197 id3->codectype = AFMT_OMA_ATRAC3;
110 /* Store the extradata for the codec */ 198 /* Store the extradata for the codec */
111 AV_WL16(&id3->id3v2buf[0], 1); // always 1 199 AV_WL16(&id3->id3v2buf[0], 1); // always 1
112 AV_WL32(&id3->id3v2buf[2], id3->frequency); // samples rate 200 AV_WL32(&id3->id3v2buf[2], id3->frequency); // samples rate
113 AV_WL16(&id3->id3v2buf[6], jsflag); // coding mode 201 AV_WL16(&id3->id3v2buf[6], jsflag); // coding mode
@@ -118,8 +206,9 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
118 } 206 }
119 else if (memcmp(buf, "data", 4) == 0) 207 else if (memcmp(buf, "data", 4) == 0)
120 { 208 {
121 numbytes = i; 209 fmt.numbytes = i;
122 id3->first_frame_offset = offset; 210 if (fmt.formattag == WAVE_FORMAT_ATRAC3)
211 id3->first_frame_offset = offset;
123 break; 212 break;
124 } 213 }
125 else if (memcmp(buf, "fact", 4) == 0) 214 else if (memcmp(buf, "fact", 4) == 0)
@@ -128,7 +217,7 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
128 if (i >= 4) 217 if (i >= 4)
129 { 218 {
130 /* get rest of chunk */ 219 /* get rest of chunk */
131 if ((read_bytes = read(fd, buf, 4)) < 4) 220 if (read(fd, buf, 4) < 4)
132 return false; 221 return false;
133 offset += 4; 222 offset += 4;
134 i -= 4; 223 i -= 4;
@@ -145,16 +234,15 @@ bool get_wave_metadata(int fd, struct mp3entry* id3)
145 offset += i; 234 offset += i;
146 } 235 }
147 236
148 if ((numbytes == 0) || (channels == 0)) 237 if ((fmt.numbytes == 0) || (fmt.channels == 0) || (fmt.blockalign == 0))
149 { 238 {
239 DEBUGF("metadata error: numbytes, channels, or blockalign is 0.\n");
150 return false; 240 return false;
151 } 241 }
152 242
153 if (totalsamples == 0) 243 if (totalsamples == 0)
154 { 244 {
155 /* for PCM only */ 245 totalsamples = get_totalsamples(&fmt, id3);
156 totalsamples = numbytes
157 / ((((bitspersample - 1) / 8) + 1) * channels);
158 } 246 }
159 247
160 id3->vbr = false; /* All WAV files are CBR */ 248 id3->vbr = false; /* All WAV files are CBR */