summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2005-06-20 14:27:06 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2005-06-20 14:27:06 +0000
commit3e88b58f6c68c740e9c1ec9ee0ef85f531269310 (patch)
tree919a0773129de59e0473d03671b13fd671147679
parent644d073652924a78b065fe10d4fbde1261b597cd (diff)
Crossfade fixes.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6778 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/playback.c6
-rw-r--r--firmware/export/pcm_playback.h2
-rw-r--r--firmware/pcm_playback.c32
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);