diff options
Diffstat (limited to 'apps/pcmbuf.c')
-rw-r--r-- | apps/pcmbuf.c | 122 |
1 files changed, 52 insertions, 70 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index a39a69a21c..cda20d9f48 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c | |||
@@ -92,7 +92,7 @@ static bool crossfade_enabled; | |||
92 | static bool crossfade_enable_request; | 92 | static bool crossfade_enable_request; |
93 | static bool crossfade_mixmode; | 93 | static bool crossfade_mixmode; |
94 | static bool crossfade_active IDATA_ATTR; | 94 | static bool crossfade_active IDATA_ATTR; |
95 | static bool crossfade_init IDATA_ATTR; | 95 | static bool crossfade_track_change_started IDATA_ATTR; |
96 | 96 | ||
97 | /* Track the current location for processing crossfade */ | 97 | /* Track the current location for processing crossfade */ |
98 | static struct chunkdesc *crossfade_chunk IDATA_ATTR; | 98 | static struct chunkdesc *crossfade_chunk IDATA_ATTR; |
@@ -132,12 +132,11 @@ extern unsigned int codec_thread_id; | |||
132 | #define LOW_DATA(quarter_secs) \ | 132 | #define LOW_DATA(quarter_secs) \ |
133 | (pcmbuf_unplayed_bytes < NATIVE_FREQUENCY * quarter_secs) | 133 | (pcmbuf_unplayed_bytes < NATIVE_FREQUENCY * quarter_secs) |
134 | 134 | ||
135 | static void pcmbuf_finish_track_change(void); | 135 | static void finish_gapless_track_change(void); |
136 | #ifdef HAVE_CROSSFADE | 136 | #ifdef HAVE_CROSSFADE |
137 | static void crossfade_start(void); | 137 | static void crossfade_start(void); |
138 | static void flush_crossfade(char *buf, size_t length); | 138 | static void flush_crossfade(char *buf, size_t length); |
139 | #endif | 139 | #endif |
140 | static bool pcmbuf_crossfade_init(bool manual_skip); | ||
141 | static void pcmbuf_finish_crossfade_enable(void); | 140 | static void pcmbuf_finish_crossfade_enable(void); |
142 | static bool pcmbuf_is_crossfade_enabled(void); | 141 | static bool pcmbuf_is_crossfade_enabled(void); |
143 | 142 | ||
@@ -348,7 +347,7 @@ static bool prepare_insert(size_t length) | |||
348 | void *pcmbuf_request_buffer(int *count) | 347 | void *pcmbuf_request_buffer(int *count) |
349 | { | 348 | { |
350 | #ifdef HAVE_CROSSFADE | 349 | #ifdef HAVE_CROSSFADE |
351 | if (crossfade_init) | 350 | if (crossfade_track_change_started) |
352 | crossfade_start(); | 351 | crossfade_start(); |
353 | #endif | 352 | #endif |
354 | 353 | ||
@@ -401,7 +400,7 @@ void pcmbuf_write_complete(int count) | |||
401 | 400 | ||
402 | /* Init */ | 401 | /* Init */ |
403 | 402 | ||
404 | static void pcmbuf_init_pcmbuffers(void) | 403 | static inline void init_pcmbuffers(void) |
405 | { | 404 | { |
406 | #ifdef DESC_DEBUG | 405 | #ifdef DESC_DEBUG |
407 | first_desc = write_chunk; | 406 | first_desc = write_chunk; |
@@ -417,7 +416,7 @@ static void pcmbuf_init_pcmbuffers(void) | |||
417 | DISPLAY_DESC("init"); | 416 | DISPLAY_DESC("init"); |
418 | } | 417 | } |
419 | 418 | ||
420 | static size_t pcmbuf_get_next_required_pcmbuf_size(void) | 419 | static size_t get_next_required_pcmbuf_size(void) |
421 | { | 420 | { |
422 | size_t seconds = 1; | 421 | size_t seconds = 1; |
423 | 422 | ||
@@ -444,13 +443,13 @@ static char *pcmbuf_calc_pcmbuffer_ptr(size_t bufsize) | |||
444 | size_t pcmbuf_init(unsigned char *bufend) | 443 | size_t pcmbuf_init(unsigned char *bufend) |
445 | { | 444 | { |
446 | pcmbuf_bufend = bufend; | 445 | pcmbuf_bufend = bufend; |
447 | pcmbuf_size = pcmbuf_get_next_required_pcmbuf_size(); | 446 | pcmbuf_size = get_next_required_pcmbuf_size(); |
448 | pcmbuffer = pcmbuf_calc_pcmbuffer_ptr(pcmbuf_size); | 447 | pcmbuffer = pcmbuf_calc_pcmbuffer_ptr(pcmbuf_size); |
449 | fadebuf = &pcmbuffer[pcmbuf_size]; | 448 | fadebuf = &pcmbuffer[pcmbuf_size]; |
450 | voicebuf = &fadebuf[PCMBUF_MIX_CHUNK]; | 449 | voicebuf = &fadebuf[PCMBUF_MIX_CHUNK]; |
451 | write_chunk = (struct chunkdesc *)&voicebuf[PCMBUF_MIX_CHUNK]; | 450 | write_chunk = (struct chunkdesc *)&voicebuf[PCMBUF_MIX_CHUNK]; |
452 | 451 | ||
453 | pcmbuf_init_pcmbuffers(); | 452 | init_pcmbuffers(); |
454 | 453 | ||
455 | if(track_transition){logf("pcmbuf: (init) track transition false");} | 454 | if(track_transition){logf("pcmbuf: (init) track transition false");} |
456 | end_of_track = false; | 455 | end_of_track = false; |
@@ -488,7 +487,7 @@ static void pcmbuf_pcm_callback(unsigned char** start, size_t* size) | |||
488 | 487 | ||
489 | /* if last buffer in the track, let the audio thread know */ | 488 | /* if last buffer in the track, let the audio thread know */ |
490 | if (pcmbuf_current->end_of_track) | 489 | if (pcmbuf_current->end_of_track) |
491 | pcmbuf_finish_track_change(); | 490 | finish_gapless_track_change(); |
492 | 491 | ||
493 | /* Put the finished buffer back into circulation */ | 492 | /* Put the finished buffer back into circulation */ |
494 | write_end_chunk->link = pcmbuf_current; | 493 | write_end_chunk->link = pcmbuf_current; |
@@ -532,7 +531,7 @@ static void pcmbuf_pcm_callback(unsigned char** start, size_t* size) | |||
532 | *realsize = 0; | 531 | *realsize = 0; |
533 | *realstart = NULL; | 532 | *realstart = NULL; |
534 | if (end_of_track) | 533 | if (end_of_track) |
535 | pcmbuf_finish_track_change(); | 534 | finish_gapless_track_change(); |
536 | } | 535 | } |
537 | } | 536 | } |
538 | DISPLAY_DESC("callback"); | 537 | DISPLAY_DESC("callback"); |
@@ -563,7 +562,7 @@ void pcmbuf_play_stop(void) | |||
563 | } | 562 | } |
564 | pcmbuffer_pos = 0; | 563 | pcmbuffer_pos = 0; |
565 | pcmbuffer_fillpos = 0; | 564 | pcmbuffer_fillpos = 0; |
566 | crossfade_init = false; | 565 | crossfade_track_change_started = false; |
567 | crossfade_active = false; | 566 | crossfade_active = false; |
568 | flush_pcmbuf = false; | 567 | flush_pcmbuf = false; |
569 | DISPLAY_DESC("play_stop"); | 568 | DISPLAY_DESC("play_stop"); |
@@ -587,7 +586,7 @@ void pcmbuf_pause(bool pause) | |||
587 | * still playing. Set flags to make sure the elapsed time of the current | 586 | * still playing. Set flags to make sure the elapsed time of the current |
588 | * track is updated properly, and mark the currently written chunk as the | 587 | * track is updated properly, and mark the currently written chunk as the |
589 | * last one in the track. */ | 588 | * last one in the track. */ |
590 | static void pcmbuf_gapless_track_change(void) | 589 | static void start_gapless_track_change(void) |
591 | { | 590 | { |
592 | /* we're starting a track transition */ | 591 | /* we're starting a track transition */ |
593 | track_transition = true; | 592 | track_transition = true; |
@@ -596,22 +595,42 @@ static void pcmbuf_gapless_track_change(void) | |||
596 | end_of_track = true; | 595 | end_of_track = true; |
597 | } | 596 | } |
598 | 597 | ||
599 | static void pcmbuf_crossfade_track_change(void) | 598 | static void start_crossfade_track_change(bool auto_skip) |
600 | { | 599 | { |
601 | /* Initiate automatic crossfade mode */ | ||
602 | pcmbuf_crossfade_init(false); | ||
603 | /* Notify the wps that the track change starts now */ | 600 | /* Notify the wps that the track change starts now */ |
604 | audio_post_track_change(false); | 601 | audio_post_track_change(false); |
602 | |||
603 | /* Can't do two crossfades at once and, no fade if pcm is off now */ | ||
604 | if (pcmbuf_is_crossfade_active() || !pcm_is_playing()) | ||
605 | { | ||
606 | pcmbuf_play_stop(); | ||
607 | return; | ||
608 | } | ||
609 | |||
610 | trigger_cpu_boost(); | ||
611 | |||
612 | /* Not enough data, or crossfade disabled, flush the old data instead */ | ||
613 | if (LOW_DATA(2) || !pcmbuf_is_crossfade_enabled() || low_latency_mode) | ||
614 | { | ||
615 | /* commit everything to this point and keep going, but... */ | ||
616 | commit_chunk(); | ||
617 | /* ... when the next chunk commits, throw away everything but itself */ | ||
618 | flush_pcmbuf = true; | ||
619 | return; | ||
620 | } | ||
621 | |||
622 | /* Don't enable mix mode when skipping tracks manually. */ | ||
623 | crossfade_mixmode = auto_skip && global_settings.crossfade_fade_out_mixmode; | ||
624 | |||
625 | crossfade_track_change_started = true; | ||
605 | } | 626 | } |
606 | 627 | ||
607 | void pcmbuf_start_track_change(bool manual_skip) | 628 | void pcmbuf_start_track_change(bool auto_skip) |
608 | { | 629 | { |
609 | /* Manual track change (always crossfade or flush audio). */ | 630 | /* Manual track change (always crossfade or flush audio). */ |
610 | if (manual_skip) | 631 | if (!auto_skip) |
611 | { | 632 | start_crossfade_track_change(false); |
612 | pcmbuf_crossfade_init(true); | 633 | |
613 | audio_post_track_change(false); | ||
614 | } | ||
615 | /* Automatic track change w/crossfade, if not in "Track Skip Only" mode. */ | 634 | /* Automatic track change w/crossfade, if not in "Track Skip Only" mode. */ |
616 | else if (pcmbuf_is_crossfade_enabled() && !pcmbuf_is_crossfade_active() | 635 | else if (pcmbuf_is_crossfade_enabled() && !pcmbuf_is_crossfade_active() |
617 | && global_settings.crossfade != CROSSFADE_ENABLE_TRACKSKIP) | 636 | && global_settings.crossfade != CROSSFADE_ENABLE_TRACKSKIP) |
@@ -620,22 +639,22 @@ void pcmbuf_start_track_change(bool manual_skip) | |||
620 | { | 639 | { |
621 | if (global_settings.playlist_shuffle) | 640 | if (global_settings.playlist_shuffle) |
622 | /* shuffle mode is on, so crossfade: */ | 641 | /* shuffle mode is on, so crossfade: */ |
623 | pcmbuf_crossfade_track_change(); | 642 | start_crossfade_track_change(true); |
624 | else | 643 | else |
625 | /* shuffle mode is off, so normal gapless playback */ | 644 | /* shuffle mode is off, so normal gapless playback */ |
626 | pcmbuf_gapless_track_change(); | 645 | start_gapless_track_change(); |
627 | } | 646 | } |
628 | else | 647 | else |
629 | /* normal crossfade: */ | 648 | /* normal crossfade: */ |
630 | pcmbuf_crossfade_track_change(); | 649 | start_crossfade_track_change(true); |
631 | } | 650 | } |
632 | else | 651 | else |
633 | /* normal gapless playback. */ | 652 | /* normal gapless playback. */ |
634 | pcmbuf_gapless_track_change(); | 653 | start_gapless_track_change(); |
635 | } | 654 | } |
636 | 655 | ||
637 | /* Called when the last chunk in the track has been played */ | 656 | /* Called when the last chunk in the track has been played */ |
638 | static void pcmbuf_finish_track_change(void) | 657 | static void finish_gapless_track_change(void) |
639 | { | 658 | { |
640 | /* not in a track transition anymore */ | 659 | /* not in a track transition anymore */ |
641 | if(track_transition){logf("pcmbuf: (finish change) track transition false");} | 660 | if(track_transition){logf("pcmbuf: (finish change) track transition false");} |
@@ -732,7 +751,7 @@ static void crossfade_start(void) | |||
732 | size_t fade_out_delay; | 751 | size_t fade_out_delay; |
733 | size_t fade_in_delay; | 752 | size_t fade_in_delay; |
734 | 753 | ||
735 | crossfade_init = false; | 754 | crossfade_track_change_started = false; |
736 | /* Reject crossfade if less than .5s of data */ | 755 | /* Reject crossfade if less than .5s of data */ |
737 | if (LOW_DATA(2)) { | 756 | if (LOW_DATA(2)) { |
738 | logf("crossfade rejected"); | 757 | logf("crossfade rejected"); |
@@ -900,37 +919,6 @@ static void flush_crossfade(char *buf, size_t length) | |||
900 | } | 919 | } |
901 | #endif /* HAVE_CROSSFADE */ | 920 | #endif /* HAVE_CROSSFADE */ |
902 | 921 | ||
903 | static bool pcmbuf_crossfade_init(bool manual_skip) | ||
904 | { | ||
905 | /* Can't do two crossfades at once and, no fade if pcm is off now */ | ||
906 | if (crossfade_init || crossfade_active || !pcm_is_playing()) | ||
907 | { | ||
908 | pcmbuf_play_stop(); | ||
909 | return false; | ||
910 | } | ||
911 | |||
912 | trigger_cpu_boost(); | ||
913 | |||
914 | /* Not enough data, or crossfade disabled, flush the old data instead */ | ||
915 | if (LOW_DATA(2) || !pcmbuf_is_crossfade_enabled() || low_latency_mode) | ||
916 | { | ||
917 | commit_chunk(); | ||
918 | flush_pcmbuf = true; | ||
919 | return false; | ||
920 | } | ||
921 | |||
922 | /* Don't enable mix mode when skipping tracks manually. */ | ||
923 | if (manual_skip) | ||
924 | crossfade_mixmode = false; | ||
925 | else | ||
926 | crossfade_mixmode = global_settings.crossfade_fade_out_mixmode; | ||
927 | |||
928 | crossfade_init = true; | ||
929 | |||
930 | return true; | ||
931 | |||
932 | } | ||
933 | |||
934 | static void pcmbuf_finish_crossfade_enable(void) | 922 | static void pcmbuf_finish_crossfade_enable(void) |
935 | { | 923 | { |
936 | /* Copy the pending setting over now */ | 924 | /* Copy the pending setting over now */ |
@@ -953,7 +941,7 @@ static bool pcmbuf_is_crossfade_enabled(void) | |||
953 | 941 | ||
954 | bool pcmbuf_is_crossfade_active(void) | 942 | bool pcmbuf_is_crossfade_active(void) |
955 | { | 943 | { |
956 | return crossfade_active || crossfade_init; | 944 | return crossfade_active || crossfade_track_change_started; |
957 | } | 945 | } |
958 | 946 | ||
959 | void pcmbuf_request_crossfade_enable(bool on_off) | 947 | void pcmbuf_request_crossfade_enable(bool on_off) |
@@ -964,16 +952,11 @@ void pcmbuf_request_crossfade_enable(bool on_off) | |||
964 | 952 | ||
965 | bool pcmbuf_is_same_size(void) | 953 | bool pcmbuf_is_same_size(void) |
966 | { | 954 | { |
967 | bool same_size; | 955 | /* if pcmbuffer is NULL, then not set up yet even once so always */ |
968 | 956 | bool same_size = pcmbuffer ? | |
969 | if (pcmbuffer == NULL) | 957 | (get_next_required_pcmbuf_size() == pcmbuf_size) : true; |
970 | same_size = true; /* Not set up yet even once so always */ | ||
971 | else | ||
972 | { | ||
973 | size_t bufsize = pcmbuf_get_next_required_pcmbuf_size(); | ||
974 | same_size = pcmbuf_calc_pcmbuffer_ptr(bufsize) == pcmbuffer; | ||
975 | } | ||
976 | 958 | ||
959 | /* no buffer change needed, so finish crossfade setup now */ | ||
977 | if (same_size) | 960 | if (same_size) |
978 | pcmbuf_finish_crossfade_enable(); | 961 | pcmbuf_finish_crossfade_enable(); |
979 | 962 | ||
@@ -1128,8 +1111,7 @@ unsigned char * pcmbuf_get_meminfo(size_t *length) | |||
1128 | 1111 | ||
1129 | bool pcmbuf_is_lowdata(void) | 1112 | bool pcmbuf_is_lowdata(void) |
1130 | { | 1113 | { |
1131 | if (!pcm_is_playing() || pcm_is_paused() || | 1114 | if (!pcm_is_playing() || pcm_is_paused() || pcmbuf_is_crossfade_active()) |
1132 | crossfade_init || crossfade_active) | ||
1133 | return false; | 1115 | return false; |
1134 | 1116 | ||
1135 | #if MEMORYSIZE > 2 | 1117 | #if MEMORYSIZE > 2 |