diff options
| author | Magnus Holmgren <magnushol@gmail.com> | 2005-07-16 12:25:28 +0000 |
|---|---|---|
| committer | Magnus Holmgren <magnushol@gmail.com> | 2005-07-16 12:25:28 +0000 |
| commit | 08761aaa52f62700515903f709eabc2494d01487 (patch) | |
| tree | 4aa53263643921736accee752130327135c30666 /apps/playback.c | |
| parent | a0266a8bfe2b42baaf917c6f588bce1f1eba66d3 (diff) | |
| download | rockbox-08761aaa52f62700515903f709eabc2494d01487.zip rockbox-08761aaa52f62700515903f709eabc2494d01487.tar.gz rockbox-08761aaa52f62700515903f709eabc2494d01487.tar.bz2 rockbox-08761aaa52f62700515903f709eabc2494d01487.tar.xz | |
Restructured DSP code for readability and speed. Simplified the API.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7174 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/playback.c')
| -rw-r--r-- | apps/playback.c | 116 |
1 files changed, 41 insertions, 75 deletions
diff --git a/apps/playback.c b/apps/playback.c index 5257a18..78ee15f 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -178,94 +178,60 @@ static bool v1first = false; static void mp3_set_elapsed(struct mp3entry* id3); int mp3_get_file_pos(void); -bool codec_pcmbuf_insert_callback(char *buf, long length) +bool codec_pcmbuf_insert_split_callback(void *ch1, void *ch2, + long length) { + char* src[2]; char *dest; - long realsize; - int factor; - int next_channel = 0; - int processed_length; - int mono = 0; - - /* If non-interleaved stereo mode. */ - if (dsp_config.stereo_mode == STEREO_NONINTERLEAVED) - next_channel = length / 2; - else if (dsp_config.stereo_mode == STEREO_MONO) { - length *= 2; - mono = 1; - } - - if (dsp_config.sample_depth > 16) { - length /= 2; - factor = 1; - } else { - factor = 0; + long input_size; + long output_size; + + src[0] = ch1; + src[1] = ch2; + + if (dsp_stereo_mode() == STEREO_NONINTERLEAVED) + { + length *= 2; /* Length is per channel */ } - + while (length > 0) { - /* Request a few extra bytes for resampling. */ - /* FIXME: Required extra bytes SHOULD be calculated. */ - while ((dest = pcmbuf_request_buffer(length+16384, &realsize)) == NULL) + while ((dest = pcmbuf_request_buffer(dsp_output_size(length), + &output_size)) == NULL) { yield(); - - if (realsize < 16384) { - pcmbuf_flush_buffer(0); - continue ; } - - realsize -= 16384; - - if (next_channel) { - processed_length = dsp_process(dest, buf, realsize / 4) * 2; - dsp_process(dest, buf + next_channel, realsize / 4); - } else { - processed_length = dsp_process(dest, buf, realsize >> (mono + 1)); + + input_size = dsp_input_size(output_size); + /* Guard against rounding errors (output_size can be too large). */ + input_size = MIN(input_size, length); + + if (input_size <= 0) { + pcmbuf_flush_buffer(0); + continue; } - pcmbuf_flush_buffer(processed_length); - length -= realsize; - buf += realsize << (factor + mono); + + output_size = dsp_process(dest, src, input_size); + pcmbuf_flush_buffer(output_size); + length -= input_size; } - + return true; } -bool codec_pcmbuf_insert_split_callback(void *ch1, void *ch2, - long length) +bool codec_pcmbuf_insert_callback(char *buf, long length) { - char *dest; - long realsize; - int factor; - int processed_length; - - /* non-interleaved stereo mode. */ - if (dsp_config.sample_depth > 16) { - factor = 0; - } else { - length /= 2; - factor = 1; - } - - while (length > 0) { - /* Request a few extra bytes for resampling. */ - while ((dest = pcmbuf_request_buffer(length+4096, &realsize)) == NULL) - yield(); - - if (realsize < 4096) { - pcmbuf_flush_buffer(0); - continue ; - } - - realsize -= 4096; - - processed_length = dsp_process(dest, ch1, realsize / 4) * 2; - dsp_process(dest, ch2, realsize / 4); - pcmbuf_flush_buffer(processed_length); - length -= realsize; - ch1 += realsize >> factor; - ch2 += realsize >> factor; + /* TODO: The audiobuffer API should probably be updated, and be based on + * pcmbuf_insert_split(). + */ + long real_length = length; + + if (dsp_stereo_mode() == STEREO_NONINTERLEAVED) + { + length /= 2; /* Length is per channel */ } - - return true; + + /* Second channel is only used for non-interleaved stereo. */ + return codec_pcmbuf_insert_split_callback(buf, buf + (real_length / 2), + length); } void* get_codec_memory_callback(long *size) |