diff options
Diffstat (limited to 'apps/pcmbuf.c')
-rw-r--r-- | apps/pcmbuf.c | 67 |
1 files changed, 47 insertions, 20 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index 93ce4266c1..2cec40b7e7 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "pcmbuf.h" | 26 | #include "pcmbuf.h" |
27 | #include "pcm.h" | 27 | #include "pcm.h" |
28 | #include "playback.h" | 28 | #include "playback.h" |
29 | #include "codec_thread.h" | ||
29 | 30 | ||
30 | /* Define LOGF_ENABLE to enable logf output in this file */ | 31 | /* Define LOGF_ENABLE to enable logf output in this file */ |
31 | /*#define LOGF_ENABLE*/ | 32 | /*#define LOGF_ENABLE*/ |
@@ -86,8 +87,7 @@ static size_t pcmbuffer_pos IDATA_ATTR; | |||
86 | static size_t pcmbuffer_fillpos IDATA_ATTR; | 87 | static size_t pcmbuffer_fillpos IDATA_ATTR; |
87 | 88 | ||
88 | /* Gapless playback */ | 89 | /* Gapless playback */ |
89 | static bool end_of_track IDATA_ATTR; | 90 | static bool track_transition IDATA_ATTR; |
90 | bool track_transition IDATA_ATTR; | ||
91 | 91 | ||
92 | #ifdef HAVE_CROSSFADE | 92 | #ifdef HAVE_CROSSFADE |
93 | /* Crossfade buffer */ | 93 | /* Crossfade buffer */ |
@@ -131,8 +131,6 @@ static bool flush_pcmbuf = false; | |||
131 | static int codec_thread_priority = PRIORITY_PLAYBACK; | 131 | static int codec_thread_priority = PRIORITY_PLAYBACK; |
132 | #endif | 132 | #endif |
133 | 133 | ||
134 | extern unsigned int codec_thread_id; | ||
135 | |||
136 | /* Helpful macros for use in conditionals this assumes some of the above | 134 | /* Helpful macros for use in conditionals this assumes some of the above |
137 | * static variable names */ | 135 | * static variable names */ |
138 | #define COMMIT_IF_NEEDED if(pcmbuffer_fillpos > PCMBUF_TARGET_CHUNK || \ | 136 | #define COMMIT_IF_NEEDED if(pcmbuffer_fillpos > PCMBUF_TARGET_CHUNK || \ |
@@ -223,9 +221,8 @@ static void commit_chunk(bool flush_next_time) | |||
223 | /* Fill in the values in the new buffer chunk */ | 221 | /* Fill in the values in the new buffer chunk */ |
224 | pcmbuf_current->addr = &pcmbuffer[pcmbuffer_pos]; | 222 | pcmbuf_current->addr = &pcmbuffer[pcmbuffer_pos]; |
225 | pcmbuf_current->size = size; | 223 | pcmbuf_current->size = size; |
226 | pcmbuf_current->end_of_track = end_of_track; | 224 | pcmbuf_current->end_of_track = false; |
227 | pcmbuf_current->link = NULL; | 225 | pcmbuf_current->link = NULL; |
228 | end_of_track = false; /* This is single use only */ | ||
229 | 226 | ||
230 | if (read_chunk != NULL) | 227 | if (read_chunk != NULL) |
231 | { | 228 | { |
@@ -297,7 +294,7 @@ static void boost_codec_thread(int pcm_fill_state) | |||
297 | * will starve if the codec thread's priority is boosted. */ | 294 | * will starve if the codec thread's priority is boosted. */ |
298 | if (new_prio != codec_thread_priority) | 295 | if (new_prio != codec_thread_priority) |
299 | { | 296 | { |
300 | thread_set_priority(codec_thread_id, new_prio); | 297 | codec_thread_set_priority(new_prio); |
301 | voice_thread_set_priority(new_prio); | 298 | voice_thread_set_priority(new_prio); |
302 | codec_thread_priority = new_prio; | 299 | codec_thread_priority = new_prio; |
303 | } | 300 | } |
@@ -327,7 +324,7 @@ static bool prepare_insert(size_t length) | |||
327 | /* Only codec thread initiates boost - voice boosts the cpu when playing | 324 | /* Only codec thread initiates boost - voice boosts the cpu when playing |
328 | a clip */ | 325 | a clip */ |
329 | #ifndef SIMULATOR | 326 | #ifndef SIMULATOR |
330 | if (thread_get_current() == codec_thread_id) | 327 | if (is_codec_thread()) |
331 | #endif /* SIMULATOR */ | 328 | #endif /* SIMULATOR */ |
332 | { | 329 | { |
333 | /* boost cpu if necessary */ | 330 | /* boost cpu if necessary */ |
@@ -487,6 +484,27 @@ size_t pcmbuf_init(unsigned char *bufend) | |||
487 | 484 | ||
488 | 485 | ||
489 | /** Track change */ | 486 | /** Track change */ |
487 | void pcmbuf_monitor_track_change(bool monitor) | ||
488 | { | ||
489 | pcm_play_lock(); | ||
490 | |||
491 | if (last_chunksize != 0) | ||
492 | { | ||
493 | /* If monitoring, wait until this track runs out. Place in | ||
494 | currently playing chunk. If not, cancel notification. */ | ||
495 | track_transition = monitor; | ||
496 | read_end_chunk->end_of_track = monitor; | ||
497 | } | ||
498 | else | ||
499 | { | ||
500 | /* Post now if PCM stopped and last buffer was sent. */ | ||
501 | track_transition = false; | ||
502 | if (monitor) | ||
503 | audio_post_track_change(false); | ||
504 | } | ||
505 | |||
506 | pcm_play_unlock(); | ||
507 | } | ||
490 | 508 | ||
491 | void pcmbuf_start_track_change(bool auto_skip) | 509 | void pcmbuf_start_track_change(bool auto_skip) |
492 | { | 510 | { |
@@ -523,6 +541,11 @@ void pcmbuf_start_track_change(bool auto_skip) | |||
523 | { logf(" crossfade track change"); } | 541 | { logf(" crossfade track change"); } |
524 | else | 542 | else |
525 | { logf(" manual track change"); } | 543 | { logf(" manual track change"); } |
544 | |||
545 | pcm_play_lock(); | ||
546 | |||
547 | /* Cancel any pending automatic gapless transition */ | ||
548 | pcmbuf_monitor_track_change(false); | ||
526 | 549 | ||
527 | /* Notify the wps that the track change starts now */ | 550 | /* Notify the wps that the track change starts now */ |
528 | audio_post_track_change(false); | 551 | audio_post_track_change(false); |
@@ -535,26 +558,32 @@ void pcmbuf_start_track_change(bool auto_skip) | |||
535 | !pcm_is_playing()) | 558 | !pcm_is_playing()) |
536 | { | 559 | { |
537 | pcmbuf_play_stop(); | 560 | pcmbuf_play_stop(); |
561 | pcm_play_unlock(); | ||
538 | return; | 562 | return; |
539 | } | 563 | } |
540 | 564 | ||
541 | trigger_cpu_boost(); | ||
542 | |||
543 | /* Not enough data, or not crossfading, flush the old data instead */ | 565 | /* Not enough data, or not crossfading, flush the old data instead */ |
544 | if (LOW_DATA(2) || !crossfade || low_latency_mode) | 566 | if (LOW_DATA(2) || !crossfade || low_latency_mode) |
545 | { | 567 | { |
546 | commit_chunk(true); | 568 | commit_chunk(true); |
547 | return; | ||
548 | } | 569 | } |
549 | |||
550 | #ifdef HAVE_CROSSFADE | 570 | #ifdef HAVE_CROSSFADE |
551 | /* Don't enable mix mode when skipping tracks manually. */ | 571 | else |
552 | crossfade_mixmode = auto_skip && global_settings.crossfade_fade_out_mixmode; | 572 | { |
553 | 573 | /* Don't enable mix mode when skipping tracks manually. */ | |
554 | crossfade_auto_skip = auto_skip; | 574 | crossfade_mixmode = auto_skip && |
575 | global_settings.crossfade_fade_out_mixmode; | ||
576 | |||
577 | crossfade_auto_skip = auto_skip; | ||
555 | 578 | ||
556 | crossfade_track_change_started = crossfade; | 579 | crossfade_track_change_started = crossfade; |
580 | } | ||
557 | #endif | 581 | #endif |
582 | pcm_play_unlock(); | ||
583 | |||
584 | /* Keep trigger outside the play lock or HW FIFO underruns can happen | ||
585 | since frequency scaling is *not* always fast */ | ||
586 | trigger_cpu_boost(); | ||
558 | } | 587 | } |
559 | else /* automatic and not crossfading, so do gapless track change */ | 588 | else /* automatic and not crossfading, so do gapless track change */ |
560 | { | 589 | { |
@@ -563,8 +592,7 @@ void pcmbuf_start_track_change(bool auto_skip) | |||
563 | * current track will be updated properly, and mark the current chunk | 592 | * current track will be updated properly, and mark the current chunk |
564 | * as the last one in the track. */ | 593 | * as the last one in the track. */ |
565 | logf(" gapless track change"); | 594 | logf(" gapless track change"); |
566 | track_transition = true; | 595 | pcmbuf_monitor_track_change(true); |
567 | end_of_track = true; | ||
568 | } | 596 | } |
569 | } | 597 | } |
570 | 598 | ||
@@ -674,7 +702,6 @@ void pcmbuf_play_stop(void) | |||
674 | crossfade_track_change_started = false; | 702 | crossfade_track_change_started = false; |
675 | crossfade_active = false; | 703 | crossfade_active = false; |
676 | #endif | 704 | #endif |
677 | end_of_track = false; | ||
678 | track_transition = false; | 705 | track_transition = false; |
679 | flush_pcmbuf = false; | 706 | flush_pcmbuf = false; |
680 | DISPLAY_DESC("play_stop"); | 707 | DISPLAY_DESC("play_stop"); |