diff options
author | Yoshihisa Uchida <uchida@rockbox.org> | 2010-03-07 07:27:45 +0000 |
---|---|---|
committer | Yoshihisa Uchida <uchida@rockbox.org> | 2010-03-07 07:27:45 +0000 |
commit | 1e9789879ff620c78b594801bf37abc256bdcc2b (patch) | |
tree | 5fd66125e86089485fa03a97670683c4a84eaa1d | |
parent | f640b89a12eb6a222c0371624fe56a2a6dd6d649 (diff) | |
download | rockbox-1e9789879ff620c78b594801bf37abc256bdcc2b.tar.gz rockbox-1e9789879ff620c78b594801bf37abc256bdcc2b.zip |
ima adpcm/swf adpcm: corrects the problem the noise occurs after the play ends.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25052 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/codecs/libpcm/dvi_adpcm.c | 70 | ||||
-rw-r--r-- | apps/codecs/libpcm/swf_adpcm.c | 10 |
2 files changed, 37 insertions, 43 deletions
diff --git a/apps/codecs/libpcm/dvi_adpcm.c b/apps/codecs/libpcm/dvi_adpcm.c index 6774b14473..2784b21786 100644 --- a/apps/codecs/libpcm/dvi_adpcm.c +++ b/apps/codecs/libpcm/dvi_adpcm.c | |||
@@ -67,7 +67,7 @@ static struct pcm_pos *get_seek_pos(long seek_time, | |||
67 | return &newpos; | 67 | return &newpos; |
68 | } | 68 | } |
69 | 69 | ||
70 | static inline void decode_2bit(const uint8_t **inbuf, | 70 | static inline void decode_2bit(const uint8_t **inbuf, size_t inbufsize, |
71 | int32_t **outbuf, int *outbufcount) | 71 | int32_t **outbuf, int *outbufcount) |
72 | { | 72 | { |
73 | int ch; | 73 | int ch; |
@@ -75,7 +75,7 @@ static inline void decode_2bit(const uint8_t **inbuf, | |||
75 | int32_t *pcmbuf; | 75 | int32_t *pcmbuf; |
76 | int samples; | 76 | int samples; |
77 | 77 | ||
78 | samples = fmt->blockalign / (4 * fmt->channels) - 1; | 78 | samples = inbufsize / (4 * fmt->channels) - 1; |
79 | *outbufcount += (samples << 4); | 79 | *outbufcount += (samples << 4); |
80 | while (samples-- > 0) | 80 | while (samples-- > 0) |
81 | { | 81 | { |
@@ -99,7 +99,7 @@ static inline void decode_2bit(const uint8_t **inbuf, | |||
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | static inline void decode_3bit(const uint8_t **inbuf, | 102 | static inline void decode_3bit(const uint8_t **inbuf, size_t inbufsize, |
103 | int32_t **outbuf, int *outbufcount) | 103 | int32_t **outbuf, int *outbufcount) |
104 | { | 104 | { |
105 | const uint8_t *adpcmbuf; | 105 | const uint8_t *adpcmbuf; |
@@ -109,7 +109,7 @@ static inline void decode_3bit(const uint8_t **inbuf, | |||
109 | int32_t *pcmbuf; | 109 | int32_t *pcmbuf; |
110 | int samples; | 110 | int samples; |
111 | 111 | ||
112 | samples = (fmt->blockalign - 4 * fmt->channels) / (12 * fmt->channels); | 112 | samples = (inbufsize - 4 * fmt->channels) / (12 * fmt->channels); |
113 | *outbufcount += (samples << 5); | 113 | *outbufcount += (samples << 5); |
114 | while (samples--) | 114 | while (samples--) |
115 | { | 115 | { |
@@ -157,7 +157,7 @@ static inline void decode_3bit(const uint8_t **inbuf, | |||
157 | } | 157 | } |
158 | } | 158 | } |
159 | 159 | ||
160 | static inline void decode_4bit(const uint8_t **inbuf, | 160 | static inline void decode_4bit(const uint8_t **inbuf, size_t inbufsize, |
161 | int32_t **outbuf, int *outbufcount) | 161 | int32_t **outbuf, int *outbufcount) |
162 | { | 162 | { |
163 | int ch; | 163 | int ch; |
@@ -165,7 +165,7 @@ static inline void decode_4bit(const uint8_t **inbuf, | |||
165 | int32_t *pcmbuf; | 165 | int32_t *pcmbuf; |
166 | int samples; | 166 | int samples; |
167 | 167 | ||
168 | samples = fmt->blockalign / (4 * fmt->channels) - 1; | 168 | samples = inbufsize / (4 * fmt->channels) - 1; |
169 | *outbufcount += (samples << 3); | 169 | *outbufcount += (samples << 3); |
170 | while (samples-- > 0) | 170 | while (samples-- > 0) |
171 | { | 171 | { |
@@ -185,7 +185,7 @@ static inline void decode_4bit(const uint8_t **inbuf, | |||
185 | } | 185 | } |
186 | } | 186 | } |
187 | 187 | ||
188 | static inline void decode_5bit(const uint8_t **inbuf, | 188 | static inline void decode_5bit(const uint8_t **inbuf, size_t inbufsize, |
189 | int32_t **outbuf, int *outbufcount) | 189 | int32_t **outbuf, int *outbufcount) |
190 | { | 190 | { |
191 | const uint8_t *adpcmbuf; | 191 | const uint8_t *adpcmbuf; |
@@ -195,7 +195,7 @@ static inline void decode_5bit(const uint8_t **inbuf, | |||
195 | int32_t *pcmbuf; | 195 | int32_t *pcmbuf; |
196 | int samples; | 196 | int samples; |
197 | 197 | ||
198 | samples = (fmt->blockalign - 4 * fmt->channels) / (20 * fmt->channels); | 198 | samples = (inbufsize - 4 * fmt->channels) / (20 * fmt->channels); |
199 | *outbufcount += (samples << 5); | 199 | *outbufcount += (samples << 5); |
200 | while (samples--) | 200 | while (samples--) |
201 | { | 201 | { |
@@ -257,46 +257,40 @@ static int decode(const uint8_t *inbuf, size_t inbufsize, | |||
257 | int32_t *outbuf, int *outbufcount) | 257 | int32_t *outbuf, int *outbufcount) |
258 | { | 258 | { |
259 | int ch; | 259 | int ch; |
260 | unsigned int i; | ||
261 | int32_t init_pcmdata[2]; | 260 | int32_t init_pcmdata[2]; |
262 | int8_t init_index[2]; | 261 | int8_t init_index[2]; |
263 | unsigned int nblocks = fmt->chunksize / fmt->blockalign; | ||
264 | |||
265 | (void)inbufsize; | ||
266 | 262 | ||
267 | *outbufcount = 0; | 263 | *outbufcount = 0; |
268 | for (i = 0; i < nblocks; i++) | 264 | for (ch = 0; ch < fmt->channels; ch++) |
269 | { | 265 | { |
270 | for (ch = 0; ch < fmt->channels; ch++) | 266 | init_pcmdata[ch] = inbuf[0] | (inbuf[1] << 8); |
267 | if (init_pcmdata[ch] > 32767) | ||
268 | init_pcmdata[ch] -= 65536; | ||
269 | |||
270 | init_index[ch] = inbuf[2]; | ||
271 | if (init_index[ch] > 88 || init_index[ch] < 0) | ||
271 | { | 272 | { |
272 | init_pcmdata[ch] = inbuf[0] | (inbuf[1] << 8); | 273 | DEBUGF("CODEC_ERROR: dvi adpcm illegal step index=%d > 88\n", |
273 | if (init_pcmdata[ch] > 32767) | 274 | init_index[ch]); |
274 | init_pcmdata[ch] -= 65536; | 275 | return CODEC_ERROR; |
276 | } | ||
277 | inbuf += 4; | ||
275 | 278 | ||
276 | init_index[ch] = inbuf[2]; | 279 | *outbuf++ = init_pcmdata[ch] << IMA_ADPCM_INC_DEPTH; |
277 | if (init_index[ch] > 88 || init_index[ch] < 0) | 280 | } |
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 | 281 | ||
285 | *outbuf++ = init_pcmdata[ch] << IMA_ADPCM_INC_DEPTH; | 282 | *outbufcount += 1; |
286 | } | 283 | set_decode_parameters(fmt->channels, init_pcmdata, init_index); |
287 | 284 | ||
288 | *outbufcount += 1; | 285 | if (fmt->bitspersample == 4) |
289 | set_decode_parameters(fmt->channels, init_pcmdata, init_index); | 286 | decode_4bit(&inbuf, inbufsize, &outbuf, outbufcount); |
287 | else if (fmt->bitspersample == 3) | ||
288 | decode_3bit(&inbuf, inbufsize, &outbuf, outbufcount); | ||
289 | else if (fmt->bitspersample == 5) | ||
290 | decode_5bit(&inbuf, inbufsize, &outbuf, outbufcount); | ||
291 | else /* fmt->bitspersample == 2 */ | ||
292 | decode_2bit(&inbuf, inbufsize, &outbuf, outbufcount); | ||
290 | 293 | ||
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); | ||
299 | } | ||
300 | return CODEC_OK; | 294 | return CODEC_OK; |
301 | } | 295 | } |
302 | 296 | ||
diff --git a/apps/codecs/libpcm/swf_adpcm.c b/apps/codecs/libpcm/swf_adpcm.c index 3441c667d4..ebc4328c59 100644 --- a/apps/codecs/libpcm/swf_adpcm.c +++ b/apps/codecs/libpcm/swf_adpcm.c | |||
@@ -47,6 +47,8 @@ static bool after_seek = false; | |||
47 | 47 | ||
48 | static struct pcm_format *fmt; | 48 | static struct pcm_format *fmt; |
49 | 49 | ||
50 | #define GET_SAMPLE_COUNT(s) ((((s) << 3) / fmt->channels - 22) / fmt->bitspersample + 1) | ||
51 | |||
50 | static bool set_format(struct pcm_format *format) | 52 | static bool set_format(struct pcm_format *format) |
51 | { | 53 | { |
52 | fmt = format; | 54 | fmt = format; |
@@ -139,14 +141,14 @@ static int decode(const uint8_t *inbuf, size_t inbufsize, | |||
139 | { | 141 | { |
140 | int ch; | 142 | int ch; |
141 | int adpcm_code_size; | 143 | int adpcm_code_size; |
142 | int count = fmt->samplesperblock; | 144 | int count = ((size_t)fmt->chunksize == inbufsize) ? fmt->samplesperblock : |
145 | GET_SAMPLE_COUNT(inbufsize); | ||
143 | int32_t init_pcmdata[2]; | 146 | int32_t init_pcmdata[2]; |
144 | int8_t init_index[2]; | 147 | int8_t init_index[2]; |
145 | static uint8_t lastbyte = 0; | 148 | static uint8_t lastbyte = 0; |
146 | 149 | ||
147 | (void)inbufsize; | ||
148 | |||
149 | validity_bits = 8; | 150 | validity_bits = 8; |
151 | *outbufcount = count; | ||
150 | 152 | ||
151 | /* read block header */ | 153 | /* read block header */ |
152 | ch = fmt->channels - 1; | 154 | ch = fmt->channels - 1; |
@@ -208,8 +210,6 @@ static int decode(const uint8_t *inbuf, size_t inbufsize, | |||
208 | << IMA_ADPCM_INC_DEPTH; | 210 | << IMA_ADPCM_INC_DEPTH; |
209 | } | 211 | } |
210 | 212 | ||
211 | *outbufcount = fmt->samplesperblock; | ||
212 | |||
213 | lastbyte = *inbuf; | 213 | lastbyte = *inbuf; |
214 | lastbytebits = (8 - validity_bits) & 0x07; | 214 | lastbytebits = (8 - validity_bits) & 0x07; |
215 | 215 | ||