From 496027d8bb89ba6d503b544f5652f4d1683d43af Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Sun, 11 Nov 2007 15:50:52 +0000 Subject: * Make the album art be updated on PCM track change, not codec track change (changes in audio_current_aa_hid). * On codec track change, if not all the audio data is present, only get rid of the audio data and not all the track's handles. This will prevent alum art from disappearing on codec track change after resuming playback (changes in audio_check_new_track). * Add audio_finalise_track_change() to handle what happens after the PCM track change (no functional change here). * Add some comments about how the track transition works. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15577 a1c6a512-1295-4272-9138-f99709370657 --- apps/playback.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file 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) #ifdef HAVE_ALBUMART int audio_current_aa_hid(void) { - return CUR_TI->aa_hid; + int cur_idx; + int offset = ci.new_track + wps_offset; + + cur_idx = track_ridx + offset; + cur_idx &= MAX_TRACK_MASK; + + return tracks[cur_idx].aa_hid; } #endif @@ -667,11 +673,26 @@ struct mp3entry* audio_current_track(void) cur_idx &= MAX_TRACK_MASK; if (cur_idx == track_ridx && *curtrack_id3.path) + { + /* The usual case */ return &curtrack_id3; + } else if (offset == -1 && *prevtrack_id3.path) + { + /* We're in a track transition. The codec has moved on to the nex track, + but the audio being played is still the same (now previous) track. + prevtrack_id3.elapsed is being updated in an ISR by + codec_pcmbuf_position_callback */ return &prevtrack_id3; + } else if (tracks[cur_idx].id3_hid >= 0) + { + /* Get the ID3 metadata from the main buffer */ return bufgetid3(tracks[cur_idx].id3_hid); + } + + /* We didn't find the ID3 metadata, so we fill temp_id3 with the little info + we have and return that. */ memset(&temp_id3, 0, sizeof(struct mp3entry)); @@ -704,13 +725,21 @@ struct mp3entry* audio_next_track(void) return NULL; if (wps_offset == -1 && *prevtrack_id3.path) + { + /* We're in a track transition. The next track for the WPS is the one + currently being decoded. */ return &curtrack_id3; + } next_idx++; next_idx &= MAX_TRACK_MASK; if (next_idx == track_widx) + { + /* The next track hasn't been buffered yet, so we return the static + version of its metadata. */ return &lasttrack_id3; + } if (tracks[next_idx].id3_hid < 0) return NULL; @@ -1455,6 +1484,10 @@ static void* codec_get_memory_callback(size_t *size) return malloc_buf; } +/* Between the codec and PCM track change, we need to keep updating the + "elapsed" value of the previous (to the codec, but current to the + user/PCM/WPS) track, so that the progressbar reaches the end. + During that transition, the WPS will display prevtrack_id3. */ static void codec_pcmbuf_position_callback(size_t size) ICODE_ATTR; static void codec_pcmbuf_position_callback(size_t size) { @@ -2574,6 +2607,8 @@ static void audio_rebuffer(void) audio_fill_file_buffer(false, 0); } +/* Called on request from the codec to get a new track. This is the codec part + of the track transition. */ static int audio_check_new_track(void) { int track_count = audio_track_count(); @@ -2631,7 +2666,7 @@ static int audio_check_new_track(void) new_playlist = false; } - /* Save the old track */ + /* Save the old track to allow the WPS to display it */ copy_mp3entry(&prevtrack_id3, &curtrack_id3); for (i = 0; i < ci.new_track; i++) @@ -2641,8 +2676,10 @@ static int audio_check_new_track(void) ssize_t offset = buf_handle_offset(tracks[idx].audio_hid); if (!id3 || offset < 0 || (unsigned)offset > id3->first_frame_offset) { - /* We don't have all the audio data for that track, so clear it */ - clear_track_info(&tracks[idx]); + /* We don't have all the audio data for that track, so clear it, + but keep the metadata. */ + if (tracks[idx].audio_hid >= 0 && bufclose(tracks[idx].audio_hid)) + tracks[idx].audio_hid = -1; } } @@ -2912,6 +2949,23 @@ static void audio_initiate_dir_change(long direction) skipped_during_pause = true; } +/* Called when PCM track change is complete */ +static void audio_finalise_track_change(void) +{ + logf("audio_finalise_track_change"); + + if (automatic_skip) + { + wps_offset = 0; + automatic_skip = false; + } + prevtrack_id3.path[0] = 0; + if (track_changed_callback) + track_changed_callback(&curtrack_id3); + track_changed = true; + playlist_update_resume_info(audio_current_track()); +} + /* * Layout audio buffer as follows - iram buffer depends on target: * [|SWAP:iram][|TALK]|MALLOC|FILE|GUARD|PCM|[SWAP:dram[|iram]|] @@ -3135,17 +3189,9 @@ static void audio_thread(void) break; case Q_AUDIO_TRACK_CHANGED: + /* PCM track change done */ LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED"); - if (automatic_skip) - { - wps_offset = 0; - automatic_skip = false; - } - prevtrack_id3.path[0] = 0; - if (track_changed_callback) - track_changed_callback(&curtrack_id3); - track_changed = true; - playlist_update_resume_info(audio_current_track()); + audio_finalise_track_change(); break; #ifndef SIMULATOR -- cgit v1.2.3