diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2005-06-20 14:27:06 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2005-06-20 14:27:06 +0000 |
commit | 3e88b58f6c68c740e9c1ec9ee0ef85f531269310 (patch) | |
tree | 919a0773129de59e0473d03671b13fd671147679 | |
parent | 644d073652924a78b065fe10d4fbde1261b597cd (diff) |
Crossfade fixes.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6778 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/playback.c | 6 | ||||
-rw-r--r-- | firmware/export/pcm_playback.h | 2 | ||||
-rw-r--r-- | firmware/pcm_playback.c | 32 |
3 files changed, 28 insertions, 12 deletions
diff --git a/apps/playback.c b/apps/playback.c index c0b2db985e..1f0586a104 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -203,7 +203,7 @@ bool pcm_is_lowdata(void) return false; } -bool pcm_crossfade_start(void) +bool pcm_crossfade_init(void) { return false; } @@ -863,7 +863,7 @@ void audio_update_trackinfo(void) if (buf_ridx >= codecbuflen) buf_ridx -= codecbuflen; - pcm_crossfade_start(); + pcm_crossfade_init(); if (!filling) pcm_set_boost_mode(false); } else { @@ -1213,7 +1213,7 @@ static void initiate_track_change(int peek_index) queue_post(&audio_queue, AUDIO_PLAY, 0); } - else if (!pcm_crossfade_start()) { + else if (!pcm_crossfade_init()) { //pcm_play_stop(); } } diff --git a/firmware/export/pcm_playback.h b/firmware/export/pcm_playback.h index 874ed6ac6c..aa29601f70 100644 --- a/firmware/export/pcm_playback.h +++ b/firmware/export/pcm_playback.h @@ -41,7 +41,7 @@ void pcm_play_set_watermark(int numbytes, void (*callback)(int bytes_left)); void pcm_set_boost_mode(bool state); bool pcm_is_lowdata(void); -bool pcm_crossfade_start(void); +bool pcm_crossfade_init(void); void audiobuffer_add_event(void (*event_handler)(void)); unsigned int audiobuffer_get_latency(void); bool audiobuffer_insert(char *buf, size_t length); diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c index 758c14782a..06949963cc 100644 --- a/firmware/pcm_playback.c +++ b/firmware/pcm_playback.c @@ -62,6 +62,7 @@ static bool boost_mode; static bool crossfade_enabled; static bool crossfade_active; +static bool crossfade_init; static int crossfade_pos; static int crossfade_amount; static int crossfade_rem; @@ -386,13 +387,27 @@ bool pcm_is_lowdata(void) return false; } -bool pcm_crossfade_start(void) +bool pcm_crossfade_init(void) { if (PCMBUF_SIZE - audiobuffer_free < CHUNK_SIZE * 8 || !crossfade_enabled) { return false; } logf("crossfading!"); + crossfade_init = true; + return true; + +} + +static void crossfade_start(void) +{ + if (!crossfade_init) + return ; + + crossfade_init = 0; + if (PCMBUF_SIZE - audiobuffer_free < CHUNK_SIZE * 6) + return ; + if (audiobuffer_fillpos) { while (!pcm_play_add_chunk(&audiobuffer[audiobuffer_pos], audiobuffer_fillpos, pcm_event_handler)) { @@ -403,27 +418,26 @@ bool pcm_crossfade_start(void) pcm_boost(true); crossfade_active = true; crossfade_pos = audiobuffer_pos; - crossfade_amount = (PCMBUF_SIZE - audiobuffer_free - (CHUNK_SIZE * 6))/2; + crossfade_amount = (PCMBUF_SIZE - audiobuffer_free - (CHUNK_SIZE * 2))/2; crossfade_rem = crossfade_amount; audiobuffer_fillpos = 0; crossfade_pos -= crossfade_amount*2; if (crossfade_pos < 0) crossfade_pos += PCMBUF_SIZE; - return true; } static __inline int crossfade(short *buf, const short *buf2, int length) { int i, size; - int val1 = (crossfade_rem)*1000/crossfade_amount; - int val2 = (crossfade_amount-crossfade_rem)*1000/crossfade_amount; + int val1 = (crossfade_rem<<10)/crossfade_amount; + int val2 = ((crossfade_amount-crossfade_rem)<<10)/crossfade_amount; - logf("cfi: %d/%d", length, crossfade_rem); + // logf("cfi: %d/%d", length, crossfade_rem); size = MIN(length, crossfade_rem); - for (i = 0; i < length; i++) { - buf[i] = ((buf[i] * val1) + (buf2[i] * val2)) / 1000; + for (i = 0; i < size; i++) { + buf[i] = ((buf[i] * val1) + (buf2[i] * val2)) >> 10; } crossfade_rem -= i; if (crossfade_rem <= 0) @@ -436,6 +450,7 @@ bool audiobuffer_insert(char *buf, size_t length) { size_t copy_n = 0; + crossfade_start(); if (audiobuffer_free < length + CHUNK_SIZE && !crossfade_active) { pcm_boost(false); return false; @@ -510,6 +525,7 @@ void pcm_play_init(void) pcmbuf_write_index = 0; pcmbuf_unplayed_bytes = 0; crossfade_active = false; + crossfade_init = false; pcm_event_handler = NULL; if (crossfade_enabled) { pcm_play_set_watermark(PCM_CF_WATERMARK, pcm_watermark_callback); |