summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/playback.c7
-rw-r--r--firmware/pcm_playback.c23
2 files changed, 18 insertions, 12 deletions
diff --git a/apps/playback.c b/apps/playback.c
index e251a1ee89..8186cf3191 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -614,13 +614,16 @@ void codec_track_changed(void)
614 queue_post(&audio_queue, AUDIO_TRACK_CHANGED, 0); 614 queue_post(&audio_queue, AUDIO_TRACK_CHANGED, 0);
615} 615}
616 616
617/* Give codecs or file buffering the right amount of processing time
618 to prevent pcm audio buffer from going empty. */
617void yield_codecs(void) 619void yield_codecs(void)
618{ 620{
619 yield(); 621 yield();
620 if (!pcm_is_playing()) 622 if (!pcm_is_playing())
621 sleep(5); 623 sleep(5);
622 while (pcm_is_lowdata() && !ci.stop_codec && 624 while ((pcm_is_crossfade_active() || pcm_is_lowdata())
623 playing && queue_empty(&audio_queue) && codecbufused > (128*1024)) 625 && !ci.stop_codec && playing && queue_empty(&audio_queue)
626 && codecbufused > (128*1024))
624 yield(); 627 yield();
625} 628}
626 629
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index a58069d5f1..20cd1f2dbd 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -420,10 +420,10 @@ unsigned int audiobuffer_get_latency(void)
420 420
421bool pcm_is_lowdata(void) 421bool pcm_is_lowdata(void)
422{ 422{
423 if (!pcm_is_playing() || pcm_paused) 423 if (!pcm_is_playing() || pcm_paused || crossfade_init || crossfade_active)
424 return false; 424 return false;
425 425
426 if (pcmbuf_unplayed_bytes < PCM_WATERMARK || crossfade_active) 426 if (pcmbuf_unplayed_bytes < PCM_WATERMARK)
427 return true; 427 return true;
428 428
429 return false; 429 return false;
@@ -435,7 +435,7 @@ bool pcm_crossfade_init(void)
435 || crossfade_active) { 435 || crossfade_active) {
436 return false; 436 return false;
437 } 437 }
438 logf("crossfading!"); 438 logf("pcm_crossfade_init");
439 pcm_boost(true); 439 pcm_boost(true);
440 crossfade_mode = CFM_CROSSFADE; 440 crossfade_mode = CFM_CROSSFADE;
441 crossfade_init = true; 441 crossfade_init = true;
@@ -478,13 +478,16 @@ void pcm_flush_fillpos(void)
478 478
479static void crossfade_start(void) 479static void crossfade_start(void)
480{ 480{
481 int bytesleft = pcmbuf_unplayed_bytes;
482
481 crossfade_init = 0; 483 crossfade_init = 0;
482 if (PCMBUF_SIZE - audiobuffer_free < CHUNK_SIZE * 4) { 484 if (bytesleft < CHUNK_SIZE * 3) {
483 if (crossfade_mode == CFM_FLUSH) 485 logf("crossfade rejected");
484 pcm_play_stop(); 486 pcm_play_stop();
485 return ; 487 return ;
486 } 488 }
487 489
490 logf("crossfade_start");
488 pcm_flush_fillpos(); 491 pcm_flush_fillpos();
489 pcm_boost(true); 492 pcm_boost(true);
490 crossfade_active = true; 493 crossfade_active = true;
@@ -492,12 +495,12 @@ static void crossfade_start(void)
492 495
493 switch (crossfade_mode) { 496 switch (crossfade_mode) {
494 case CFM_CROSSFADE: 497 case CFM_CROSSFADE:
495 crossfade_amount = (PCMBUF_SIZE - audiobuffer_free - (CHUNK_SIZE * 2))/2; 498 crossfade_amount = (bytesleft - (CHUNK_SIZE * 2))/2;
496 crossfade_rem = crossfade_amount; 499 crossfade_rem = crossfade_amount;
497 break ; 500 break ;
498 501
499 case CFM_FLUSH: 502 case CFM_FLUSH:
500 crossfade_amount = (PCMBUF_SIZE - audiobuffer_free - (CHUNK_SIZE * 2))/2; 503 crossfade_amount = (bytesleft - (CHUNK_SIZE * 2))/2;
501 crossfade_rem = crossfade_amount; 504 crossfade_rem = crossfade_amount;
502 break ; 505 break ;
503 } 506 }
@@ -586,7 +589,7 @@ void* pcm_request_buffer(long length, long *realsize)
586 589
587bool pcm_is_crossfade_active(void) 590bool pcm_is_crossfade_active(void)
588{ 591{
589 return crossfade_active; 592 return crossfade_active || crossfade_init;
590} 593}
591 594
592void pcm_flush_buffer(long length) 595void pcm_flush_buffer(long length)