From aba6ca0881d1481b4047b2d7834d70ca2eb5c64b Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Wed, 7 Feb 2007 00:51:50 +0000 Subject: Fix resampling clicking as much as possible at the moment. 1) Upsampling clicked because of size inaccuracies returned by DSP. Fix by simplifying audio system to use per-channel sample count from codec to pcm buffer. 2) Downsampling affected by 1) and was often starting passed the end of the data when not enough was available to generate an output sample. Fix by clamping input range to last sample in buffer and using the last sample value in the buffer. A perfect fix will require a double buffering scheme on the resampler to sufficient data during small data transients on both ends at all times of the down ratio on input and the up ratio on output. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12218 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/a52.c | 7 ++----- apps/codecs/aac.c | 8 ++------ apps/codecs/adx.c | 7 ++++--- apps/codecs/aiff.c | 17 ++++++++++------- apps/codecs/alac.c | 5 +---- apps/codecs/flac.c | 7 ++----- apps/codecs/mpa.c | 10 +++++----- apps/codecs/mpc.c | 7 +++---- apps/codecs/nsf.c | 4 +--- apps/codecs/shorten.c | 7 ++----- apps/codecs/sid.c | 3 +-- apps/codecs/vorbis.c | 5 +---- apps/codecs/wav.c | 25 +++++++++++++++---------- apps/codecs/wavpack.c | 3 +-- 14 files changed, 50 insertions(+), 65 deletions(-) (limited to 'apps/codecs') diff --git a/apps/codecs/a52.c b/apps/codecs/a52.c index 4f41bfe..028dff6 100644 --- a/apps/codecs/a52.c +++ b/apps/codecs/a52.c @@ -35,12 +35,9 @@ unsigned long frequency; /* used outside liba52 */ static uint8_t buf[3840] IBSS_ATTR; -void output_audio(sample_t *samples) +static inline void output_audio(sample_t *samples) { - do { - ci->yield(); - } while (!ci->pcmbuf_insert_split(&samples[0], &samples[256], - 256*sizeof(sample_t))); + ci->pcmbuf_insert(&samples[0], &samples[256], 256); } void a52_decode_data(uint8_t *start, uint8_t *end) diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c index 4695caa..7656c41 100644 --- a/apps/codecs/aac.c +++ b/apps/codecs/aac.c @@ -183,12 +183,8 @@ next_track: /* Output the audio */ ci->yield(); - while (!ci->pcmbuf_insert_split(decoder->time_out[0], - decoder->time_out[1], - frame_info.samples * 2)) - { - ci->sleep(1); - } + ci->pcmbuf_insert(decoder->time_out[0], decoder->time_out[1], + frame_info.samples >> 1); /* Update the elapsed-time indicator */ sound_samples_done += sample_duration; diff --git a/apps/codecs/adx.c b/apps/codecs/adx.c index 608d9f0..85e55a4 100644 --- a/apps/codecs/adx.c +++ b/apps/codecs/adx.c @@ -320,9 +320,10 @@ next_track: } } - /* 2 bytes per sample */ - while (!ci->pcmbuf_insert((char *)samples, sampleswritten*2)) - ci->yield(); + if (channels == 2) + sampleswritten >>= 1; /* make samples/channel */ + + ci->pcmbuf_insert(samples, NULL, sampleswritten); ci->set_elapsed( ((end_adr-start_adr)*loop_count + bufoff-chanstart)* diff --git a/apps/codecs/aiff.c b/apps/codecs/aiff.c index d1bb14a..628f994 100644 --- a/apps/codecs/aiff.c +++ b/apps/codecs/aiff.c @@ -51,7 +51,8 @@ enum codec_status codec_main(void) uint16_t sample_size = 0; uint32_t sample_rate = 0; uint32_t i; - size_t n, bufsize; + size_t n; + int bufcount; int endofstream; unsigned char *buf; uint8_t *aifbuf; @@ -229,25 +230,27 @@ next_track: samples[i/4] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13) |(aifbuf[i + 2]<<5)|(aifbuf[i + 3]>>3); } - bufsize = n; + bufcount = n >> 2; } else if (sample_size > 16) { for (i = 0; i < n; i += 3) { samples[i/3] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13) |(aifbuf[i + 2]<<5); } - bufsize = n*4/3; + bufcount = n/3; } else if (sample_size > 8) { for (i = 0; i < n; i += 2) samples[i/2] = (SE(aifbuf[i])<<21)|(aifbuf[i + 1]<<13); - bufsize = n*2; + bufcount = n >> 1; } else { for (i = 0; i < n; i++) samples[i] = SE(aifbuf[i]) << 21; - bufsize = n*4; + bufcount = n; } - while (!ci->pcmbuf_insert((char *)samples, bufsize)) - ci->yield(); + if (num_channels == 2) + bufcount >>= 1; + + ci->pcmbuf_insert(samples, NULL, bufcount); ci->advance_buffer(n); bytesdone += n; diff --git a/apps/codecs/alac.c b/apps/codecs/alac.c index 1c1b14a..cfa713a 100644 --- a/apps/codecs/alac.c +++ b/apps/codecs/alac.c @@ -121,10 +121,7 @@ enum codec_status codec_main(void) /* Output the audio */ ci->yield(); - while(!ci->pcmbuf_insert_split(outputbuffer[0], - outputbuffer[1], - samplesdecoded*sizeof(int32_t))) - ci->yield(); + ci->pcmbuf_insert(outputbuffer[0], outputbuffer[1], samplesdecoded); /* Update the elapsed-time indicator */ samplesdone+=sample_duration; diff --git a/apps/codecs/flac.c b/apps/codecs/flac.c index 649c26a..738e4bb 100644 --- a/apps/codecs/flac.c +++ b/apps/codecs/flac.c @@ -489,11 +489,8 @@ enum codec_status codec_main(void) frame++; ci->yield(); - while(!ci->pcmbuf_insert_split((char*)&decoded0[fc.sample_skip], - (char*)&decoded1[fc.sample_skip], - (fc.blocksize-fc.sample_skip)*4)) { - ci->yield(); - } + ci->pcmbuf_insert(&decoded0[fc.sample_skip], &decoded1[fc.sample_skip], + fc.blocksize - fc.sample_skip); fc.sample_skip = 0; diff --git a/apps/codecs/mpa.c b/apps/codecs/mpa.c index 6e474c1..4c99778 100644 --- a/apps/codecs/mpa.c +++ b/apps/codecs/mpa.c @@ -199,9 +199,9 @@ next_track: loop we will need to process the final frame that was decoded. */ if (framelength > 0) { /* In case of a mono file, the second array will be ignored. */ - ci->pcmbuf_insert_split(&synth.pcm.samples[0][samples_to_skip], - &synth.pcm.samples[1][samples_to_skip], - framelength * 4); + ci->pcmbuf_insert(&synth.pcm.samples[0][samples_to_skip], + &synth.pcm.samples[1][samples_to_skip], + framelength); /* Only skip samples for the first frame added. */ samples_to_skip = 0; @@ -244,8 +244,8 @@ next_track: /* Finish the remaining decoded frame. Cut the required samples from the end. */ if (framelength > stop_skip) - ci->pcmbuf_insert_split(synth.pcm.samples[0], synth.pcm.samples[1], - (framelength - stop_skip) * 4); + ci->pcmbuf_insert(synth.pcm.samples[0], synth.pcm.samples[1], + framelength - stop_skip); stream.error = 0; diff --git a/apps/codecs/mpc.c b/apps/codecs/mpc.c index 1075d88..8aba8e5 100644 --- a/apps/codecs/mpc.c +++ b/apps/codecs/mpc.c @@ -168,10 +168,9 @@ next_track: retval = CODEC_ERROR; goto done; } else { - while (!ci->pcmbuf_insert_split(sample_buffer, - sample_buffer + MPC_FRAME_LENGTH, - status*sizeof(MPC_SAMPLE_FORMAT))) - ci->yield(); + ci->pcmbuf_insert(sample_buffer, + sample_buffer + MPC_FRAME_LENGTH, + status); samplesdone += status; ci->set_elapsed(samplesdone/frequency); } diff --git a/apps/codecs/nsf.c b/apps/codecs/nsf.c index 77043b6..f138fa1 100644 --- a/apps/codecs/nsf.c +++ b/apps/codecs/nsf.c @@ -4445,9 +4445,7 @@ init_nsf: goto init_nsf; } - while (!ci->pcmbuf_insert((char *)samples, written)) - ci->yield(); - + ci->pcmbuf_insert(samples, NULL, written >> 1); } print_timers(last_path,track); diff --git a/apps/codecs/shorten.c b/apps/codecs/shorten.c index 1b9563a..3c099bc 100644 --- a/apps/codecs/shorten.c +++ b/apps/codecs/shorten.c @@ -134,11 +134,8 @@ seek_start: /* Insert decoded samples in pcmbuf */ if (nsamples) { ci->yield(); - while (!ci->pcmbuf_insert_split((char*)(decoded0 + sc.nwrap), - (char*)(decoded1 + sc.nwrap), - 4*nsamples)) { - ci->yield(); - } + ci->pcmbuf_insert(decoded0 + sc.nwrap, decoded1 + sc.nwrap, + nsamples); /* Update the elapsed-time indicator */ samplesdone += nsamples; diff --git a/apps/codecs/sid.c b/apps/codecs/sid.c index 58eb725..59683e9 100644 --- a/apps/codecs/sid.c +++ b/apps/codecs/sid.c @@ -1309,8 +1309,7 @@ next_track: } } - while (!ci->pcmbuf_insert((char *)samples, CHUNK_SIZE*4)) - ci->yield(); + ci->pcmbuf_insert(samples, NULL, CHUNK_SIZE); } if (ci->request_next_track()) diff --git a/apps/codecs/vorbis.c b/apps/codecs/vorbis.c index a6a9065..8ab4a95 100644 --- a/apps/codecs/vorbis.c +++ b/apps/codecs/vorbis.c @@ -217,10 +217,7 @@ next_track: } else if (n < 0) { DEBUGF("Error decoding frame\n"); } else { - while (!ci->pcmbuf_insert_split(pcm[0], pcm[1], - n*sizeof(ogg_int32_t))) { - ci->sleep(1); - } + ci->pcmbuf_insert(pcm[0], pcm[1], n); ci->set_offset(ov_raw_tell(&vf)); ci->set_elapsed(ov_time_tell(&vf)); } diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c index 26cbf7f..ec268a3 100644 --- a/apps/codecs/wav.c +++ b/apps/codecs/wav.c @@ -212,7 +212,8 @@ enum codec_status codec_main(void) int bytespersample = 0; uint16_t bitspersample; uint32_t i; - size_t n, bufsize; + size_t n; + int bufcount; int endofstream; unsigned char *buf; uint8_t *wavbuf; @@ -466,34 +467,39 @@ next_track: (wavbuf[i + 1]<<5)|(wavbuf[i + 2]<<13)| (SE(wavbuf[i + 3])<<21); } - bufsize = n; + bufcount = n >> 2; } else if (bitspersample > 16) { for (i = 0; i < n; i += 3) { samples[i/3] = (wavbuf[i]<<5)| (wavbuf[i + 1]<<13)|(SE(wavbuf[i + 2])<<21); } - bufsize = n*4/3; + bufcount = n/3; } else if (bitspersample > 8) { for (i = 0; i < n; i += 2) { samples[i/2] = (wavbuf[i]<<13)|(SE(wavbuf[i + 1])<<21); } - bufsize = n*2; + bufcount = n >> 1; } else { for (i = 0; i < n; i++) { samples[i] = (wavbuf[i] - 0x80)<<21; } - bufsize = n*4; + bufcount = n; } + + if (channels == 2) + bufcount >>= 1; } else if (formattag == WAVE_FORMAT_ALAW || formattag == IBM_FORMAT_ALAW) { for (i = 0; i < n; i++) samples[i] = alaw2linear16[wavbuf[i]] << 13; - bufsize = n*4; + + bufcount = (channels == 2) ? (n >> 1) : n; } else if (formattag == WAVE_FORMAT_MULAW || formattag == IBM_FORMAT_MULAW) { for (i = 0; i < n; i++) samples[i] = ulaw2linear16[wavbuf[i]] << 13; - bufsize = n*4; + + bufcount = (channels == 2) ? (n >> 1) : n; } else if (formattag == WAVE_FORMAT_DVI_ADPCM) { unsigned int nblocks = chunksize/blockalign; @@ -508,15 +514,14 @@ next_track: goto done; } } - bufsize = nblocks*samplesperblock*channels*4; + bufcount = nblocks*samplesperblock; } else { DEBUGF("CODEC_ERROR: unsupported format %x\n", formattag); i = CODEC_ERROR; goto done; } - while (!ci->pcmbuf_insert((char *)samples, bufsize)) - ci->yield(); + ci->pcmbuf_insert(samples, NULL, bufcount); ci->advance_buffer(n); bytesdone += n; diff --git a/apps/codecs/wavpack.c b/apps/codecs/wavpack.c index e2c19c8..34616d7 100644 --- a/apps/codecs/wavpack.c +++ b/apps/codecs/wavpack.c @@ -118,8 +118,7 @@ enum codec_status codec_main(void) if (ci->stop_codec || ci->new_track) break; - while (!ci->pcmbuf_insert ((char *) temp_buffer, nsamples * nchans * 4)) - ci->sleep (1); + ci->pcmbuf_insert (temp_buffer, NULL, nsamples); ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); ci->yield (); -- cgit v1.1