From ef53bb9edc2333ef3071bc452d98a217f1f03a3e Mon Sep 17 00:00:00 2001 From: uchida Date: Sun, 7 Mar 2010 07:27:45 +0000 Subject: [PATCH] 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 --- apps/codecs/libpcm/dvi_adpcm.c | 70 +++++++++++++++++++----------------------- 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 6774b1447..2784b2178 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, return &newpos; } -static inline void decode_2bit(const uint8_t **inbuf, +static inline void decode_2bit(const uint8_t **inbuf, size_t inbufsize, int32_t **outbuf, int *outbufcount) { int ch; @@ -75,7 +75,7 @@ static inline void decode_2bit(const uint8_t **inbuf, int32_t *pcmbuf; int samples; - samples = fmt->blockalign / (4 * fmt->channels) - 1; + samples = inbufsize / (4 * fmt->channels) - 1; *outbufcount += (samples << 4); while (samples-- > 0) { @@ -99,7 +99,7 @@ static inline void decode_2bit(const uint8_t **inbuf, } } -static inline void decode_3bit(const uint8_t **inbuf, +static inline void decode_3bit(const uint8_t **inbuf, size_t inbufsize, int32_t **outbuf, int *outbufcount) { const uint8_t *adpcmbuf; @@ -109,7 +109,7 @@ static inline void decode_3bit(const uint8_t **inbuf, int32_t *pcmbuf; int samples; - samples = (fmt->blockalign - 4 * fmt->channels) / (12 * fmt->channels); + samples = (inbufsize - 4 * fmt->channels) / (12 * fmt->channels); *outbufcount += (samples << 5); while (samples--) { @@ -157,7 +157,7 @@ static inline void decode_3bit(const uint8_t **inbuf, } } -static inline void decode_4bit(const uint8_t **inbuf, +static inline void decode_4bit(const uint8_t **inbuf, size_t inbufsize, int32_t **outbuf, int *outbufcount) { int ch; @@ -165,7 +165,7 @@ static inline void decode_4bit(const uint8_t **inbuf, int32_t *pcmbuf; int samples; - samples = fmt->blockalign / (4 * fmt->channels) - 1; + samples = inbufsize / (4 * fmt->channels) - 1; *outbufcount += (samples << 3); while (samples-- > 0) { @@ -185,7 +185,7 @@ static inline void decode_4bit(const uint8_t **inbuf, } } -static inline void decode_5bit(const uint8_t **inbuf, +static inline void decode_5bit(const uint8_t **inbuf, size_t inbufsize, int32_t **outbuf, int *outbufcount) { const uint8_t *adpcmbuf; @@ -195,7 +195,7 @@ static inline void decode_5bit(const uint8_t **inbuf, int32_t *pcmbuf; int samples; - samples = (fmt->blockalign - 4 * fmt->channels) / (20 * fmt->channels); + samples = (inbufsize - 4 * fmt->channels) / (20 * fmt->channels); *outbufcount += (samples << 5); while (samples--) { @@ -257,46 +257,40 @@ static int decode(const uint8_t *inbuf, size_t inbufsize, int32_t *outbuf, int *outbufcount) { int ch; - unsigned int i; int32_t init_pcmdata[2]; int8_t init_index[2]; - unsigned int nblocks = fmt->chunksize / fmt->blockalign; - - (void)inbufsize; *outbufcount = 0; - for (i = 0; i < nblocks; i++) + for (ch = 0; ch < fmt->channels; ch++) { - for (ch = 0; ch < fmt->channels; ch++) + init_pcmdata[ch] = inbuf[0] | (inbuf[1] << 8); + if (init_pcmdata[ch] > 32767) + init_pcmdata[ch] -= 65536; + + init_index[ch] = inbuf[2]; + if (init_index[ch] > 88 || init_index[ch] < 0) { - init_pcmdata[ch] = inbuf[0] | (inbuf[1] << 8); - if (init_pcmdata[ch] > 32767) - init_pcmdata[ch] -= 65536; + DEBUGF("CODEC_ERROR: dvi adpcm illegal step index=%d > 88\n", + init_index[ch]); + return CODEC_ERROR; + } + inbuf += 4; - init_index[ch] = inbuf[2]; - if (init_index[ch] > 88 || init_index[ch] < 0) - { - DEBUGF("CODEC_ERROR: dvi adpcm illegal step index=%d > 88\n", - init_index[ch]); - return CODEC_ERROR; - } - inbuf += 4; + *outbuf++ = init_pcmdata[ch] << IMA_ADPCM_INC_DEPTH; + } - *outbuf++ = init_pcmdata[ch] << IMA_ADPCM_INC_DEPTH; - } + *outbufcount += 1; + set_decode_parameters(fmt->channels, init_pcmdata, init_index); - *outbufcount += 1; - set_decode_parameters(fmt->channels, init_pcmdata, init_index); + if (fmt->bitspersample == 4) + decode_4bit(&inbuf, inbufsize, &outbuf, outbufcount); + else if (fmt->bitspersample == 3) + decode_3bit(&inbuf, inbufsize, &outbuf, outbufcount); + else if (fmt->bitspersample == 5) + decode_5bit(&inbuf, inbufsize, &outbuf, outbufcount); + else /* fmt->bitspersample == 2 */ + decode_2bit(&inbuf, inbufsize, &outbuf, outbufcount); - if (fmt->bitspersample == 4) - decode_4bit(&inbuf, &outbuf, outbufcount); - else if (fmt->bitspersample == 3) - decode_3bit(&inbuf, &outbuf, outbufcount); - else if (fmt->bitspersample == 5) - decode_5bit(&inbuf, &outbuf, outbufcount); - else /* fmt->bitspersample == 2 */ - decode_2bit(&inbuf, &outbuf, outbufcount); - } return CODEC_OK; } diff --git a/apps/codecs/libpcm/swf_adpcm.c b/apps/codecs/libpcm/swf_adpcm.c index 3441c667d..ebc4328c5 100644 --- a/apps/codecs/libpcm/swf_adpcm.c +++ b/apps/codecs/libpcm/swf_adpcm.c @@ -47,6 +47,8 @@ static bool after_seek = false; static struct pcm_format *fmt; +#define GET_SAMPLE_COUNT(s) ((((s) << 3) / fmt->channels - 22) / fmt->bitspersample + 1) + static bool set_format(struct pcm_format *format) { fmt = format; @@ -139,14 +141,14 @@ static int decode(const uint8_t *inbuf, size_t inbufsize, { int ch; int adpcm_code_size; - int count = fmt->samplesperblock; + int count = ((size_t)fmt->chunksize == inbufsize) ? fmt->samplesperblock : + GET_SAMPLE_COUNT(inbufsize); int32_t init_pcmdata[2]; int8_t init_index[2]; static uint8_t lastbyte = 0; - (void)inbufsize; - validity_bits = 8; + *outbufcount = count; /* read block header */ ch = fmt->channels - 1; @@ -208,8 +210,6 @@ static int decode(const uint8_t *inbuf, size_t inbufsize, << IMA_ADPCM_INC_DEPTH; } - *outbufcount = fmt->samplesperblock; - lastbyte = *inbuf; lastbytebits = (8 - validity_bits) & 0x07; -- 2.11.4.GIT