summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorRoman Artiukhin <bahusdrive@gmail.com>2024-01-24 10:57:17 +0200
committerChristian Soffke <christian.soffke@gmail.com>2024-07-21 11:51:02 -0400
commitfe5375a6cb8761e6af33ac1c2cddbe0c76200d91 (patch)
tree7cf27ac9b179addf0ddb57c8d49376d4d8590f8c /apps
parent9f366b1b8a00acdec6b0161293a404d4237a2557 (diff)
downloadrockbox-fe5375a6cb8761e6af33ac1c2cddbe0c76200d91.tar.gz
rockbox-fe5375a6cb8761e6af33ac1c2cddbe0c76200d91.zip
Improve Crossfade handling in Single Mode
Crossfade (see Playback Settings -> Crossfade) now works between songs in Single Mode (see Playback Settings -> Single Mode) unless it’s the last song to be played. Change-Id: Icfe3d48459bb35bbc050f237a68b27e793ab9152
Diffstat (limited to 'apps')
-rw-r--r--apps/pcmbuf.c3
-rw-r--r--apps/playback.c160
2 files changed, 86 insertions, 77 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index 8718d730fb..773e97cce0 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -741,9 +741,6 @@ void pcmbuf_start_track_change(enum pcm_track_change_type type)
741 } 741 }
742 } 742 }
743 743
744 if (auto_skip && global_settings.single_mode != SINGLE_MODE_OFF && !global_settings.party_mode)
745 crossfade = false;
746
747 if (crossfade) 744 if (crossfade)
748 { 745 {
749 logf("crossfade track change"); 746 logf("crossfade track change");
diff --git a/apps/playback.c b/apps/playback.c
index 8a30af5199..a284a1858d 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -2494,6 +2494,23 @@ static inline char* single_mode_get_id3_tag(struct mp3entry *id3)
2494 return NULL; 2494 return NULL;
2495} 2495}
2496 2496
2497static bool single_mode_do_pause(int id3_hid)
2498{
2499 if (global_settings.single_mode != SINGLE_MODE_OFF && global_settings.party_mode == 0 &&
2500 ((skip_pending == TRACK_SKIP_AUTO) || (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST))) {
2501
2502 if (global_settings.single_mode == SINGLE_MODE_TRACK)
2503 return true;
2504
2505 char *previous_tag = single_mode_get_id3_tag(id3_get(PLAYING_ID3));
2506 char *new_tag = single_mode_get_id3_tag(bufgetid3(id3_hid));
2507 return previous_tag == NULL ||
2508 new_tag == NULL ||
2509 strcmp(previous_tag, new_tag) != 0;
2510 }
2511 return false;
2512}
2513
2497/* Called to make an outstanding track skip the current track and to send the 2514/* Called to make an outstanding track skip the current track and to send the
2498 transition events */ 2515 transition events */
2499static void audio_finalise_track_change(void) 2516static void audio_finalise_track_change(void)
@@ -2540,43 +2557,28 @@ static void audio_finalise_track_change(void)
2540 bool have_info = track_list_current(0, &info); 2557 bool have_info = track_list_current(0, &info);
2541 struct mp3entry *track_id3 = NULL; 2558 struct mp3entry *track_id3 = NULL;
2542 2559
2543 id3_mutex_lock();
2544
2545 /* Update the current cuesheet if any and enabled */ 2560 /* Update the current cuesheet if any and enabled */
2546 if (have_info) 2561 if (have_info)
2547 { 2562 {
2548 buf_read_cuesheet(info.cuesheet_hid); 2563 buf_read_cuesheet(info.cuesheet_hid);
2549 track_id3 = bufgetid3(info.id3_hid); 2564 track_id3 = bufgetid3(info.id3_hid);
2550 }
2551
2552 if (SINGLE_MODE_OFF != global_settings.single_mode && global_settings.party_mode == 0 &&
2553 ((skip_pending == TRACK_SKIP_AUTO) || (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)))
2554 {
2555 bool single_mode_do_pause = true;
2556 if (SINGLE_MODE_TRACK != global_settings.single_mode)
2557 {
2558 char *previous_tag = single_mode_get_id3_tag(id3_get(PLAYING_ID3));
2559 char *new_tag = single_mode_get_id3_tag(track_id3);
2560 single_mode_do_pause = previous_tag == NULL ||
2561 new_tag == NULL ||
2562 strcmp(previous_tag, new_tag) != 0;
2563 }
2564 2565
2565 if (single_mode_do_pause) 2566 if (single_mode_do_pause(info.id3_hid))
2566 { 2567 {
2567 play_status = PLAY_PAUSED; 2568 play_status = PLAY_PAUSED;
2568 pcmbuf_pause(true); 2569 pcmbuf_pause(true);
2569 } 2570 }
2570 } 2571 }
2572 /* Sync the next track information */
2573 have_info = track_list_current(1, &info);
2574
2575 id3_mutex_lock();
2571 2576
2572 id3_write(PLAYING_ID3, track_id3); 2577 id3_write(PLAYING_ID3, track_id3);
2573 2578
2574 /* The skip is technically over */ 2579 /* The skip is technically over */
2575 skip_pending = TRACK_SKIP_NONE; 2580 skip_pending = TRACK_SKIP_NONE;
2576 2581
2577 /* Sync the next track information */
2578 have_info = track_list_current(1, &info);
2579
2580 id3_write(NEXTTRACK_ID3, have_info ? bufgetid3(info.id3_hid) : 2582 id3_write(NEXTTRACK_ID3, have_info ? bufgetid3(info.id3_hid) :
2581 id3_get(UNBUFFERED_ID3)); 2583 id3_get(UNBUFFERED_ID3));
2582 2584
@@ -2641,54 +2643,12 @@ static void audio_monitor_end_of_playlist(void)
2641 pcmbuf_start_track_change(TRACK_CHANGE_END_OF_DATA); 2643 pcmbuf_start_track_change(TRACK_CHANGE_END_OF_DATA);
2642} 2644}
2643 2645
2644/* Codec has completed decoding the track 2646/* Does this track have an entry allocated? */
2645 (usually Q_AUDIO_CODEC_COMPLETE) */ 2647static bool audio_can_change_track(int *trackstat, int *id3_hid)
2646static void audio_on_codec_complete(int status)
2647{ 2648{
2648 logf("%s(%d)", __func__, status);
2649
2650 if (play_status == PLAY_STOPPED)
2651 return;
2652
2653 /* If it didn't notify us first, don't expect "seek complete" message
2654 since the codec can't post it now - do things like it would have
2655 done */
2656 audio_complete_codec_seek();
2657
2658 if (play_status == PLAY_PAUSED || skip_pending != TRACK_SKIP_NONE)
2659 {
2660 /* Old-hay on the ip-skay - codec has completed decoding
2661
2662 Paused: We're not sounding it, so just remember that it happened
2663 and the resume will begin the transition
2664
2665 Skipping: There was already a skip in progress, remember it and
2666 allow no further progress until the PCM from the previous
2667 song has finished
2668
2669 This function will be reentered upon completing the existing
2670 transition in order to do the one that was just tried (below)
2671 */
2672 codec_skip_pending = true;
2673 codec_skip_status = status;
2674
2675 /* PCM buffer must know; audio could still be filling and hasn't
2676 yet reached the play watermark */
2677 pcmbuf_start_track_change(TRACK_CHANGE_AUTO_PILEUP);
2678 return;
2679 }
2680
2681 codec_skip_pending = false;
2682
2683 int trackstat = LOAD_TRACK_OK;
2684
2685 track_event_flags = TEF_AUTO_SKIP;
2686 skip_pending = TRACK_SKIP_AUTO;
2687
2688 /* Does this track have an entry allocated? */
2689 struct track_info info; 2649 struct track_info info;
2690 bool have_track = track_list_advance_current(1, &info); 2650 bool have_track = track_list_advance_current(1, &info);
2691 2651 *id3_hid = info.id3_hid;
2692 if (!have_track || info.audio_hid < 0) 2652 if (!have_track || info.audio_hid < 0)
2693 { 2653 {
2694 bool end_of_playlist = false; 2654 bool end_of_playlist = false;
@@ -2697,8 +2657,8 @@ static void audio_on_codec_complete(int status)
2697 { 2657 {
2698 if (filling == STATE_STOPPED) 2658 if (filling == STATE_STOPPED)
2699 { 2659 {
2700 audio_begin_track_change(TRACK_CHANGE_END_OF_DATA, trackstat); 2660 audio_begin_track_change(TRACK_CHANGE_END_OF_DATA, *trackstat);
2701 return; 2661 return false;
2702 } 2662 }
2703 2663
2704 /* Track load is not complete - it might have stopped on a 2664 /* Track load is not complete - it might have stopped on a
@@ -2719,8 +2679,7 @@ static void audio_on_codec_complete(int status)
2719 { 2679 {
2720 /* Continue filling after this track */ 2680 /* Continue filling after this track */
2721 audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1); 2681 audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1);
2722 audio_begin_track_change(TRACK_CHANGE_AUTO, trackstat); 2682 return true;
2723 return;
2724 } 2683 }
2725 /* else rebuffer at this track; status applies to the track we 2684 /* else rebuffer at this track; status applies to the track we
2726 want */ 2685 want */
@@ -2736,10 +2695,10 @@ static void audio_on_codec_complete(int status)
2736 2695
2737 if (!end_of_playlist) 2696 if (!end_of_playlist)
2738 { 2697 {
2739 trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, 2698 *trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL,
2740 skip_pending == TRACK_SKIP_AUTO ? 0 : -1); 2699 skip_pending == TRACK_SKIP_AUTO ? 0 : -1);
2741 2700
2742 if (trackstat == LOAD_TRACK_ERR_NO_MORE) 2701 if (*trackstat == LOAD_TRACK_ERR_NO_MORE)
2743 { 2702 {
2744 /* Failed to find anything after all - do playlist switchover 2703 /* Failed to find anything after all - do playlist switchover
2745 instead */ 2704 instead */
@@ -2751,11 +2710,64 @@ static void audio_on_codec_complete(int status)
2751 if (end_of_playlist) 2710 if (end_of_playlist)
2752 { 2711 {
2753 audio_monitor_end_of_playlist(); 2712 audio_monitor_end_of_playlist();
2754 return; 2713 return false;
2755 } 2714 }
2756 } 2715 }
2716 return true;
2717}
2718
2719/* Codec has completed decoding the track
2720 (usually Q_AUDIO_CODEC_COMPLETE) */
2721static void audio_on_codec_complete(int status)
2722{
2723 logf("%s(%d)", __func__, status);
2757 2724
2758 audio_begin_track_change(TRACK_CHANGE_AUTO, trackstat); 2725 if (play_status == PLAY_STOPPED)
2726 return;
2727
2728 /* If it didn't notify us first, don't expect "seek complete" message
2729 since the codec can't post it now - do things like it would have
2730 done */
2731 audio_complete_codec_seek();
2732
2733 if (play_status == PLAY_PAUSED || skip_pending != TRACK_SKIP_NONE)
2734 {
2735 /* Old-hay on the ip-skay - codec has completed decoding
2736
2737 Paused: We're not sounding it, so just remember that it happened
2738 and the resume will begin the transition
2739
2740 Skipping: There was already a skip in progress, remember it and
2741 allow no further progress until the PCM from the previous
2742 song has finished
2743
2744 This function will be reentered upon completing the existing
2745 transition in order to do the one that was just tried (below)
2746 */
2747 codec_skip_pending = true;
2748 codec_skip_status = status;
2749
2750 /* PCM buffer must know; audio could still be filling and hasn't
2751 yet reached the play watermark */
2752 pcmbuf_start_track_change(TRACK_CHANGE_AUTO_PILEUP);
2753 return;
2754 }
2755
2756 codec_skip_pending = false;
2757
2758 int trackstat = LOAD_TRACK_OK;
2759
2760 track_event_flags = TEF_AUTO_SKIP;
2761 skip_pending = TRACK_SKIP_AUTO;
2762
2763 int id3_hid = 0;
2764 if (audio_can_change_track(&trackstat, &id3_hid))
2765 {
2766 audio_begin_track_change(
2767 single_mode_do_pause(id3_hid)
2768 ? TRACK_CHANGE_END_OF_DATA
2769 : TRACK_CHANGE_AUTO, trackstat);
2770 }
2759} 2771}
2760 2772
2761/* Called when codec completes seek operation 2773/* Called when codec completes seek operation