diff options
Diffstat (limited to 'apps/playback.c')
-rw-r--r-- | apps/playback.c | 74 |
1 files changed, 60 insertions, 14 deletions
diff --git a/apps/playback.c b/apps/playback.c index 3c4af6e205..2085549090 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -651,7 +651,13 @@ void audio_remove_encoder(void) | |||
651 | #ifdef HAVE_ALBUMART | 651 | #ifdef HAVE_ALBUMART |
652 | int audio_current_aa_hid(void) | 652 | int audio_current_aa_hid(void) |
653 | { | 653 | { |
654 | return CUR_TI->aa_hid; | 654 | int cur_idx; |
655 | int offset = ci.new_track + wps_offset; | ||
656 | |||
657 | cur_idx = track_ridx + offset; | ||
658 | cur_idx &= MAX_TRACK_MASK; | ||
659 | |||
660 | return tracks[cur_idx].aa_hid; | ||
655 | } | 661 | } |
656 | #endif | 662 | #endif |
657 | 663 | ||
@@ -667,11 +673,26 @@ struct mp3entry* audio_current_track(void) | |||
667 | cur_idx &= MAX_TRACK_MASK; | 673 | cur_idx &= MAX_TRACK_MASK; |
668 | 674 | ||
669 | if (cur_idx == track_ridx && *curtrack_id3.path) | 675 | if (cur_idx == track_ridx && *curtrack_id3.path) |
676 | { | ||
677 | /* The usual case */ | ||
670 | return &curtrack_id3; | 678 | return &curtrack_id3; |
679 | } | ||
671 | else if (offset == -1 && *prevtrack_id3.path) | 680 | else if (offset == -1 && *prevtrack_id3.path) |
681 | { | ||
682 | /* We're in a track transition. The codec has moved on to the nex track, | ||
683 | but the audio being played is still the same (now previous) track. | ||
684 | prevtrack_id3.elapsed is being updated in an ISR by | ||
685 | codec_pcmbuf_position_callback */ | ||
672 | return &prevtrack_id3; | 686 | return &prevtrack_id3; |
687 | } | ||
673 | else if (tracks[cur_idx].id3_hid >= 0) | 688 | else if (tracks[cur_idx].id3_hid >= 0) |
689 | { | ||
690 | /* Get the ID3 metadata from the main buffer */ | ||
674 | return bufgetid3(tracks[cur_idx].id3_hid); | 691 | return bufgetid3(tracks[cur_idx].id3_hid); |
692 | } | ||
693 | |||
694 | /* We didn't find the ID3 metadata, so we fill temp_id3 with the little info | ||
695 | we have and return that. */ | ||
675 | 696 | ||
676 | memset(&temp_id3, 0, sizeof(struct mp3entry)); | 697 | memset(&temp_id3, 0, sizeof(struct mp3entry)); |
677 | 698 | ||
@@ -704,13 +725,21 @@ struct mp3entry* audio_next_track(void) | |||
704 | return NULL; | 725 | return NULL; |
705 | 726 | ||
706 | if (wps_offset == -1 && *prevtrack_id3.path) | 727 | if (wps_offset == -1 && *prevtrack_id3.path) |
728 | { | ||
729 | /* We're in a track transition. The next track for the WPS is the one | ||
730 | currently being decoded. */ | ||
707 | return &curtrack_id3; | 731 | return &curtrack_id3; |
732 | } | ||
708 | 733 | ||
709 | next_idx++; | 734 | next_idx++; |
710 | next_idx &= MAX_TRACK_MASK; | 735 | next_idx &= MAX_TRACK_MASK; |
711 | 736 | ||
712 | if (next_idx == track_widx) | 737 | if (next_idx == track_widx) |
738 | { | ||
739 | /* The next track hasn't been buffered yet, so we return the static | ||
740 | version of its metadata. */ | ||
713 | return &lasttrack_id3; | 741 | return &lasttrack_id3; |
742 | } | ||
714 | 743 | ||
715 | if (tracks[next_idx].id3_hid < 0) | 744 | if (tracks[next_idx].id3_hid < 0) |
716 | return NULL; | 745 | return NULL; |
@@ -1455,6 +1484,10 @@ static void* codec_get_memory_callback(size_t *size) | |||
1455 | return malloc_buf; | 1484 | return malloc_buf; |
1456 | } | 1485 | } |
1457 | 1486 | ||
1487 | /* Between the codec and PCM track change, we need to keep updating the | ||
1488 | "elapsed" value of the previous (to the codec, but current to the | ||
1489 | user/PCM/WPS) track, so that the progressbar reaches the end. | ||
1490 | During that transition, the WPS will display prevtrack_id3. */ | ||
1458 | static void codec_pcmbuf_position_callback(size_t size) ICODE_ATTR; | 1491 | static void codec_pcmbuf_position_callback(size_t size) ICODE_ATTR; |
1459 | static void codec_pcmbuf_position_callback(size_t size) | 1492 | static void codec_pcmbuf_position_callback(size_t size) |
1460 | { | 1493 | { |
@@ -2574,6 +2607,8 @@ static void audio_rebuffer(void) | |||
2574 | audio_fill_file_buffer(false, 0); | 2607 | audio_fill_file_buffer(false, 0); |
2575 | } | 2608 | } |
2576 | 2609 | ||
2610 | /* Called on request from the codec to get a new track. This is the codec part | ||
2611 | of the track transition. */ | ||
2577 | static int audio_check_new_track(void) | 2612 | static int audio_check_new_track(void) |
2578 | { | 2613 | { |
2579 | int track_count = audio_track_count(); | 2614 | int track_count = audio_track_count(); |
@@ -2631,7 +2666,7 @@ static int audio_check_new_track(void) | |||
2631 | new_playlist = false; | 2666 | new_playlist = false; |
2632 | } | 2667 | } |
2633 | 2668 | ||
2634 | /* Save the old track */ | 2669 | /* Save the old track to allow the WPS to display it */ |
2635 | copy_mp3entry(&prevtrack_id3, &curtrack_id3); | 2670 | copy_mp3entry(&prevtrack_id3, &curtrack_id3); |
2636 | 2671 | ||
2637 | for (i = 0; i < ci.new_track; i++) | 2672 | for (i = 0; i < ci.new_track; i++) |
@@ -2641,8 +2676,10 @@ static int audio_check_new_track(void) | |||
2641 | ssize_t offset = buf_handle_offset(tracks[idx].audio_hid); | 2676 | ssize_t offset = buf_handle_offset(tracks[idx].audio_hid); |
2642 | if (!id3 || offset < 0 || (unsigned)offset > id3->first_frame_offset) | 2677 | if (!id3 || offset < 0 || (unsigned)offset > id3->first_frame_offset) |
2643 | { | 2678 | { |
2644 | /* We don't have all the audio data for that track, so clear it */ | 2679 | /* We don't have all the audio data for that track, so clear it, |
2645 | clear_track_info(&tracks[idx]); | 2680 | but keep the metadata. */ |
2681 | if (tracks[idx].audio_hid >= 0 && bufclose(tracks[idx].audio_hid)) | ||
2682 | tracks[idx].audio_hid = -1; | ||
2646 | } | 2683 | } |
2647 | } | 2684 | } |
2648 | 2685 | ||
@@ -2912,6 +2949,23 @@ static void audio_initiate_dir_change(long direction) | |||
2912 | skipped_during_pause = true; | 2949 | skipped_during_pause = true; |
2913 | } | 2950 | } |
2914 | 2951 | ||
2952 | /* Called when PCM track change is complete */ | ||
2953 | static void audio_finalise_track_change(void) | ||
2954 | { | ||
2955 | logf("audio_finalise_track_change"); | ||
2956 | |||
2957 | if (automatic_skip) | ||
2958 | { | ||
2959 | wps_offset = 0; | ||
2960 | automatic_skip = false; | ||
2961 | } | ||
2962 | prevtrack_id3.path[0] = 0; | ||
2963 | if (track_changed_callback) | ||
2964 | track_changed_callback(&curtrack_id3); | ||
2965 | track_changed = true; | ||
2966 | playlist_update_resume_info(audio_current_track()); | ||
2967 | } | ||
2968 | |||
2915 | /* | 2969 | /* |
2916 | * Layout audio buffer as follows - iram buffer depends on target: | 2970 | * Layout audio buffer as follows - iram buffer depends on target: |
2917 | * [|SWAP:iram][|TALK]|MALLOC|FILE|GUARD|PCM|[SWAP:dram[|iram]|] | 2971 | * [|SWAP:iram][|TALK]|MALLOC|FILE|GUARD|PCM|[SWAP:dram[|iram]|] |
@@ -3135,17 +3189,9 @@ static void audio_thread(void) | |||
3135 | break; | 3189 | break; |
3136 | 3190 | ||
3137 | case Q_AUDIO_TRACK_CHANGED: | 3191 | case Q_AUDIO_TRACK_CHANGED: |
3192 | /* PCM track change done */ | ||
3138 | LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED"); | 3193 | LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED"); |
3139 | if (automatic_skip) | 3194 | audio_finalise_track_change(); |
3140 | { | ||
3141 | wps_offset = 0; | ||
3142 | automatic_skip = false; | ||
3143 | } | ||
3144 | prevtrack_id3.path[0] = 0; | ||
3145 | if (track_changed_callback) | ||
3146 | track_changed_callback(&curtrack_id3); | ||
3147 | track_changed = true; | ||
3148 | playlist_update_resume_info(audio_current_track()); | ||
3149 | break; | 3195 | break; |
3150 | 3196 | ||
3151 | #ifndef SIMULATOR | 3197 | #ifndef SIMULATOR |