diff options
-rw-r--r-- | apps/pcmbuf.c | 3 | ||||
-rw-r--r-- | apps/playback.c | 160 |
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 | ||
2497 | static 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 */ |
2499 | static void audio_finalise_track_change(void) | 2516 | static 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) */ | 2647 | static bool audio_can_change_track(int *trackstat, int *id3_hid) |
2646 | static 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) */ | ||
2721 | static 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 |