diff options
Diffstat (limited to 'firmware/pcm_playback.c')
-rw-r--r-- | firmware/pcm_playback.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c index 0ab3d0272f..da7f06fa29 100644 --- a/firmware/pcm_playback.c +++ b/firmware/pcm_playback.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "uda1380.h" | 27 | #include "uda1380.h" |
28 | #include "system.h" | 28 | #include "system.h" |
29 | #endif | 29 | #endif |
30 | #include "logf.h" | ||
30 | 31 | ||
31 | #include <stdio.h> | 32 | #include <stdio.h> |
32 | #include <string.h> | 33 | #include <string.h> |
@@ -225,6 +226,7 @@ void pcm_play_stop(void) | |||
225 | if (pcm_playing) { | 226 | if (pcm_playing) { |
226 | uda1380_enable_output(false); | 227 | uda1380_enable_output(false); |
227 | pcm_boost(false); | 228 | pcm_boost(false); |
229 | sleep(HZ/16); | ||
228 | dma_stop(); | 230 | dma_stop(); |
229 | } | 231 | } |
230 | pcmbuf_unplayed_bytes = 0; | 232 | pcmbuf_unplayed_bytes = 0; |
@@ -384,36 +386,38 @@ bool pcm_is_lowdata(void) | |||
384 | 386 | ||
385 | bool pcm_crossfade_start(void) | 387 | bool pcm_crossfade_start(void) |
386 | { | 388 | { |
387 | //logf("cf:%d", audiobuffer_free / CHUNK_SIZE); | 389 | if (PCMBUF_SIZE - audiobuffer_free < CHUNK_SIZE * 4 || !crossfade_enabled) { |
388 | if (audiobuffer_free > CHUNK_SIZE * 4 || !crossfade_enabled) { | ||
389 | return false; | 390 | return false; |
390 | } | 391 | } |
392 | logf("crossfading!"); | ||
391 | pcm_boost(true); | 393 | pcm_boost(true); |
392 | crossfade_active = true; | 394 | crossfade_active = true; |
393 | crossfade_pos = audiobuffer_pos; | 395 | crossfade_pos = audiobuffer_pos; |
394 | crossfade_amount = (PCMBUF_SIZE - audiobuffer_free - CHUNK_SIZE * 22)/2; | 396 | crossfade_amount = (PCMBUF_SIZE - audiobuffer_free - (CHUNK_SIZE * 4))/2; |
395 | crossfade_rem = crossfade_amount; | 397 | crossfade_rem = crossfade_amount; |
396 | audiobuffer_fillpos = 0; | 398 | audiobuffer_fillpos = 0; |
397 | 399 | ||
398 | crossfade_pos -= crossfade_amount*2; | 400 | crossfade_pos -= crossfade_amount*2; |
399 | if (crossfade_pos < 0) | 401 | if (crossfade_pos < 0) |
400 | crossfade_pos = PCMBUF_SIZE + crossfade_pos; | 402 | crossfade_pos += PCMBUF_SIZE; |
401 | return true; | 403 | return true; |
402 | } | 404 | } |
403 | 405 | ||
404 | static __inline | 406 | static __inline |
405 | void crossfade(short *buf, const short *buf2, int length) | 407 | void crossfade(short *buf, const short *buf2, int length) |
406 | { | 408 | { |
407 | while (length--) { | 409 | int i, size; |
408 | *buf = (int)((*buf * ((crossfade_rem)*1000/crossfade_amount))/1000); | 410 | |
409 | *buf += (int)((*buf2 * ((crossfade_amount-crossfade_rem)*1000/crossfade_amount))/1000); | 411 | logf("cfi: %d/%d", length, crossfade_rem); |
410 | buf++; | 412 | size = MIN(length, crossfade_rem); |
411 | buf2++; | 413 | for (i = 0; i < length; i++) { |
412 | if (--crossfade_rem <= 0) { | 414 | /* This is not yet realtime, needs optimizations for crossfade to work. */ |
413 | crossfade_active = false; | 415 | buf[i] = ((buf[i] * ((crossfade_rem)*1000/crossfade_amount))/1000) |
414 | break ; | 416 | + ((buf2[i] * ((crossfade_amount-crossfade_rem)*1000/crossfade_amount))/1000); |
415 | } | ||
416 | } | 417 | } |
418 | |||
419 | if (--crossfade_rem <= 0) | ||
420 | crossfade_active = false; | ||
417 | } | 421 | } |
418 | 422 | ||
419 | bool audiobuffer_insert(char *buf, size_t length) | 423 | bool audiobuffer_insert(char *buf, size_t length) |