diff options
Diffstat (limited to 'apps/playback.c')
-rw-r--r-- | apps/playback.c | 163 |
1 files changed, 87 insertions, 76 deletions
diff --git a/apps/playback.c b/apps/playback.c index 18f62fb69b..a284a1858d 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -2022,8 +2022,7 @@ static int audio_load_track(void) | |||
2022 | if (fd >= 0) | 2022 | if (fd >= 0) |
2023 | { | 2023 | { |
2024 | id3_mutex_lock(); | 2024 | id3_mutex_lock(); |
2025 | if(!get_metadata(ub_id3, fd, path)) | 2025 | get_metadata(ub_id3, fd, path); |
2026 | wipe_mp3entry(ub_id3); | ||
2027 | id3_mutex_unlock(); | 2026 | id3_mutex_unlock(); |
2028 | } | 2027 | } |
2029 | 2028 | ||
@@ -2495,6 +2494,23 @@ static inline char* single_mode_get_id3_tag(struct mp3entry *id3) | |||
2495 | return NULL; | 2494 | return NULL; |
2496 | } | 2495 | } |
2497 | 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 | |||
2498 | /* 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 |
2499 | transition events */ | 2515 | transition events */ |
2500 | static void audio_finalise_track_change(void) | 2516 | static void audio_finalise_track_change(void) |
@@ -2541,43 +2557,28 @@ static void audio_finalise_track_change(void) | |||
2541 | bool have_info = track_list_current(0, &info); | 2557 | bool have_info = track_list_current(0, &info); |
2542 | struct mp3entry *track_id3 = NULL; | 2558 | struct mp3entry *track_id3 = NULL; |
2543 | 2559 | ||
2544 | id3_mutex_lock(); | ||
2545 | |||
2546 | /* Update the current cuesheet if any and enabled */ | 2560 | /* Update the current cuesheet if any and enabled */ |
2547 | if (have_info) | 2561 | if (have_info) |
2548 | { | 2562 | { |
2549 | buf_read_cuesheet(info.cuesheet_hid); | 2563 | buf_read_cuesheet(info.cuesheet_hid); |
2550 | track_id3 = bufgetid3(info.id3_hid); | 2564 | track_id3 = bufgetid3(info.id3_hid); |
2551 | } | ||
2552 | |||
2553 | if (SINGLE_MODE_OFF != global_settings.single_mode && global_settings.party_mode == 0 && | ||
2554 | ((skip_pending == TRACK_SKIP_AUTO) || (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST))) | ||
2555 | { | ||
2556 | bool single_mode_do_pause = true; | ||
2557 | if (SINGLE_MODE_TRACK != global_settings.single_mode) | ||
2558 | { | ||
2559 | char *previous_tag = single_mode_get_id3_tag(id3_get(PLAYING_ID3)); | ||
2560 | char *new_tag = single_mode_get_id3_tag(track_id3); | ||
2561 | single_mode_do_pause = previous_tag == NULL || | ||
2562 | new_tag == NULL || | ||
2563 | strcmp(previous_tag, new_tag) != 0; | ||
2564 | } | ||
2565 | 2565 | ||
2566 | if (single_mode_do_pause) | 2566 | if (single_mode_do_pause(info.id3_hid)) |
2567 | { | 2567 | { |
2568 | play_status = PLAY_PAUSED; | 2568 | play_status = PLAY_PAUSED; |
2569 | pcmbuf_pause(true); | 2569 | pcmbuf_pause(true); |
2570 | } | 2570 | } |
2571 | } | 2571 | } |
2572 | /* Sync the next track information */ | ||
2573 | have_info = track_list_current(1, &info); | ||
2574 | |||
2575 | id3_mutex_lock(); | ||
2572 | 2576 | ||
2573 | id3_write(PLAYING_ID3, track_id3); | 2577 | id3_write(PLAYING_ID3, track_id3); |
2574 | 2578 | ||
2575 | /* The skip is technically over */ | 2579 | /* The skip is technically over */ |
2576 | skip_pending = TRACK_SKIP_NONE; | 2580 | skip_pending = TRACK_SKIP_NONE; |
2577 | 2581 | ||
2578 | /* Sync the next track information */ | ||
2579 | have_info = track_list_current(1, &info); | ||
2580 | |||
2581 | id3_write(NEXTTRACK_ID3, have_info ? bufgetid3(info.id3_hid) : | 2582 | id3_write(NEXTTRACK_ID3, have_info ? bufgetid3(info.id3_hid) : |
2582 | id3_get(UNBUFFERED_ID3)); | 2583 | id3_get(UNBUFFERED_ID3)); |
2583 | 2584 | ||
@@ -2642,54 +2643,12 @@ static void audio_monitor_end_of_playlist(void) | |||
2642 | pcmbuf_start_track_change(TRACK_CHANGE_END_OF_DATA); | 2643 | pcmbuf_start_track_change(TRACK_CHANGE_END_OF_DATA); |
2643 | } | 2644 | } |
2644 | 2645 | ||
2645 | /* Codec has completed decoding the track | 2646 | /* Does this track have an entry allocated? */ |
2646 | (usually Q_AUDIO_CODEC_COMPLETE) */ | 2647 | static bool audio_can_change_track(int *trackstat, int *id3_hid) |
2647 | static void audio_on_codec_complete(int status) | ||
2648 | { | 2648 | { |
2649 | logf("%s(%d)", __func__, status); | ||
2650 | |||
2651 | if (play_status == PLAY_STOPPED) | ||
2652 | return; | ||
2653 | |||
2654 | /* If it didn't notify us first, don't expect "seek complete" message | ||
2655 | since the codec can't post it now - do things like it would have | ||
2656 | done */ | ||
2657 | audio_complete_codec_seek(); | ||
2658 | |||
2659 | if (play_status == PLAY_PAUSED || skip_pending != TRACK_SKIP_NONE) | ||
2660 | { | ||
2661 | /* Old-hay on the ip-skay - codec has completed decoding | ||
2662 | |||
2663 | Paused: We're not sounding it, so just remember that it happened | ||
2664 | and the resume will begin the transition | ||
2665 | |||
2666 | Skipping: There was already a skip in progress, remember it and | ||
2667 | allow no further progress until the PCM from the previous | ||
2668 | song has finished | ||
2669 | |||
2670 | This function will be reentered upon completing the existing | ||
2671 | transition in order to do the one that was just tried (below) | ||
2672 | */ | ||
2673 | codec_skip_pending = true; | ||
2674 | codec_skip_status = status; | ||
2675 | |||
2676 | /* PCM buffer must know; audio could still be filling and hasn't | ||
2677 | yet reached the play watermark */ | ||
2678 | pcmbuf_start_track_change(TRACK_CHANGE_AUTO_PILEUP); | ||
2679 | return; | ||
2680 | } | ||
2681 | |||
2682 | codec_skip_pending = false; | ||
2683 | |||
2684 | int trackstat = LOAD_TRACK_OK; | ||
2685 | |||
2686 | track_event_flags = TEF_AUTO_SKIP; | ||
2687 | skip_pending = TRACK_SKIP_AUTO; | ||
2688 | |||
2689 | /* Does this track have an entry allocated? */ | ||
2690 | struct track_info info; | 2649 | struct track_info info; |
2691 | bool have_track = track_list_advance_current(1, &info); | 2650 | bool have_track = track_list_advance_current(1, &info); |
2692 | 2651 | *id3_hid = info.id3_hid; | |
2693 | if (!have_track || info.audio_hid < 0) | 2652 | if (!have_track || info.audio_hid < 0) |
2694 | { | 2653 | { |
2695 | bool end_of_playlist = false; | 2654 | bool end_of_playlist = false; |
@@ -2698,8 +2657,8 @@ static void audio_on_codec_complete(int status) | |||
2698 | { | 2657 | { |
2699 | if (filling == STATE_STOPPED) | 2658 | if (filling == STATE_STOPPED) |
2700 | { | 2659 | { |
2701 | audio_begin_track_change(TRACK_CHANGE_END_OF_DATA, trackstat); | 2660 | audio_begin_track_change(TRACK_CHANGE_END_OF_DATA, *trackstat); |
2702 | return; | 2661 | return false; |
2703 | } | 2662 | } |
2704 | 2663 | ||
2705 | /* Track load is not complete - it might have stopped on a | 2664 | /* Track load is not complete - it might have stopped on a |
@@ -2720,8 +2679,7 @@ static void audio_on_codec_complete(int status) | |||
2720 | { | 2679 | { |
2721 | /* Continue filling after this track */ | 2680 | /* Continue filling after this track */ |
2722 | audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1); | 2681 | audio_reset_and_rebuffer(TRACK_LIST_KEEP_CURRENT, 1); |
2723 | audio_begin_track_change(TRACK_CHANGE_AUTO, trackstat); | 2682 | return true; |
2724 | return; | ||
2725 | } | 2683 | } |
2726 | /* else rebuffer at this track; status applies to the track we | 2684 | /* else rebuffer at this track; status applies to the track we |
2727 | want */ | 2685 | want */ |
@@ -2737,10 +2695,10 @@ static void audio_on_codec_complete(int status) | |||
2737 | 2695 | ||
2738 | if (!end_of_playlist) | 2696 | if (!end_of_playlist) |
2739 | { | 2697 | { |
2740 | trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, | 2698 | *trackstat = audio_reset_and_rebuffer(TRACK_LIST_CLEAR_ALL, |
2741 | skip_pending == TRACK_SKIP_AUTO ? 0 : -1); | 2699 | skip_pending == TRACK_SKIP_AUTO ? 0 : -1); |
2742 | 2700 | ||
2743 | if (trackstat == LOAD_TRACK_ERR_NO_MORE) | 2701 | if (*trackstat == LOAD_TRACK_ERR_NO_MORE) |
2744 | { | 2702 | { |
2745 | /* Failed to find anything after all - do playlist switchover | 2703 | /* Failed to find anything after all - do playlist switchover |
2746 | instead */ | 2704 | instead */ |
@@ -2752,11 +2710,64 @@ static void audio_on_codec_complete(int status) | |||
2752 | if (end_of_playlist) | 2710 | if (end_of_playlist) |
2753 | { | 2711 | { |
2754 | audio_monitor_end_of_playlist(); | 2712 | audio_monitor_end_of_playlist(); |
2755 | return; | 2713 | return false; |
2756 | } | 2714 | } |
2757 | } | 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); | ||
2758 | 2724 | ||
2759 | 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 | } | ||
2760 | } | 2771 | } |
2761 | 2772 | ||
2762 | /* Called when codec completes seek operation | 2773 | /* Called when codec completes seek operation |