forked from len0rd/rockbox
This seems to make selecting a new track from the file browser work very close to right.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9810 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
96dce1d3b7
commit
da1cddfcbb
1 changed files with 66 additions and 28 deletions
|
@ -119,6 +119,7 @@ enum {
|
|||
Q_AUDIO_FLUSH,
|
||||
Q_AUDIO_TRACK_CHANGED,
|
||||
Q_AUDIO_DIR_SKIP,
|
||||
Q_AUDIO_NEW_PLAYLIST,
|
||||
Q_AUDIO_POSTINIT,
|
||||
Q_AUDIO_FILL_BUFFER,
|
||||
|
||||
|
@ -237,6 +238,7 @@ extern struct codec_api ci_voice;
|
|||
/* Was the skip being executed manual or automatic? */
|
||||
static bool automatic_skip;
|
||||
static bool dir_skip = false;
|
||||
static bool new_playlist = false;
|
||||
|
||||
/* Callback function to call when current track has really changed. */
|
||||
void (*track_changed_callback)(struct mp3entry *id3);
|
||||
|
@ -258,7 +260,8 @@ static int mp3_get_file_pos(void);
|
|||
static void audio_clear_track_entries(
|
||||
bool clear_buffered, bool clear_unbuffered);
|
||||
static void initialize_buffer_fill(bool clear_tracks);
|
||||
static void audio_fill_file_buffer(bool start_play, size_t offset);
|
||||
static void audio_fill_file_buffer(
|
||||
bool start_play, bool rebuffer, size_t offset);
|
||||
|
||||
static void swap_codec(void)
|
||||
{
|
||||
|
@ -883,13 +886,11 @@ static void audio_rebuffer(void)
|
|||
audio_clear_track_entries(false, true);
|
||||
filebufused = 0;
|
||||
|
||||
/* Cause the buffer fill to return as soon as the codec is loaded */
|
||||
queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0);
|
||||
/* Fill the buffer */
|
||||
last_peek_offset = -1;
|
||||
cur_ti->filesize = 0;
|
||||
cur_ti->start_pos = 0;
|
||||
audio_fill_file_buffer(false, 0);
|
||||
audio_fill_file_buffer(false, true, 0);
|
||||
}
|
||||
|
||||
static void audio_check_new_track(void)
|
||||
|
@ -915,6 +916,9 @@ static void audio_check_new_track(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (new_playlist)
|
||||
ci.new_track = 0;
|
||||
|
||||
/* If the playlist isn't that big */
|
||||
if (!playlist_check(ci.new_track))
|
||||
{
|
||||
|
@ -935,15 +939,15 @@ static void audio_check_new_track(void)
|
|||
last_peek_offset -= ci.new_track;
|
||||
playlist_next(ci.new_track);
|
||||
|
||||
if (new_playlist)
|
||||
ci.new_track = 1;
|
||||
|
||||
track_ridx+=ci.new_track;
|
||||
if (track_ridx >= MAX_TRACK)
|
||||
track_ridx -= MAX_TRACK;
|
||||
else if (track_ridx < 0)
|
||||
track_ridx += MAX_TRACK;
|
||||
|
||||
forward = ci.new_track > 0;
|
||||
ci.new_track = 0;
|
||||
|
||||
/* Save the old track */
|
||||
prev_ti = cur_ti;
|
||||
/* Move to the new track */
|
||||
|
@ -959,6 +963,9 @@ static void audio_check_new_track(void)
|
|||
goto skip_done;
|
||||
}
|
||||
|
||||
forward = ci.new_track > 0;
|
||||
ci.new_track = 0;
|
||||
|
||||
/* If the target track is clearly not in memory */
|
||||
if (cur_ti->filesize == 0 || !cur_ti->taginfo_ready)
|
||||
{
|
||||
|
@ -1313,7 +1320,7 @@ static void strip_id3v1_tag(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void audio_read_file(void)
|
||||
static void audio_read_file(bool quick)
|
||||
{
|
||||
size_t copy_n;
|
||||
int rc;
|
||||
|
@ -1360,7 +1367,7 @@ static void audio_read_file(void)
|
|||
/* Let the codec process until it is out of the danger zone, or there
|
||||
* is an event to handle. In the latter case, break this fill cycle
|
||||
* immediately */
|
||||
if (yield_codecs())
|
||||
if (quick || yield_codecs())
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1581,7 +1588,7 @@ static bool read_next_metadata(void)
|
|||
return status;
|
||||
}
|
||||
|
||||
static bool audio_load_track(int offset, bool start_play)
|
||||
static bool audio_load_track(int offset, bool start_play, bool rebuffer)
|
||||
{
|
||||
char *trackname;
|
||||
off_t size;
|
||||
|
@ -1732,7 +1739,8 @@ static bool audio_load_track(int offset, bool start_play)
|
|||
|
||||
logf("alt:%s", trackname);
|
||||
tracks[track_widx].buf_idx = buf_widx;
|
||||
audio_read_file();
|
||||
|
||||
audio_read_file(rebuffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1851,7 +1859,7 @@ static void audio_play_start(size_t offset)
|
|||
|
||||
last_peek_offset = -1;
|
||||
|
||||
audio_fill_file_buffer(true, offset);
|
||||
audio_fill_file_buffer(true, false, offset);
|
||||
}
|
||||
|
||||
/* Send callback events to notify about new tracks. */
|
||||
|
@ -1911,7 +1919,8 @@ static void initialize_buffer_fill(bool clear_tracks)
|
|||
filling = true;
|
||||
}
|
||||
|
||||
static void audio_fill_file_buffer(bool start_play, size_t offset)
|
||||
static void audio_fill_file_buffer(
|
||||
bool start_play, bool rebuffer, size_t offset)
|
||||
{
|
||||
bool had_next_track = audio_next_track() != NULL;
|
||||
|
||||
|
@ -1920,8 +1929,8 @@ static void audio_fill_file_buffer(bool start_play, size_t offset)
|
|||
/* If we have a partially buffered track, continue loading,
|
||||
* otherwise load a new track */
|
||||
if (tracks[track_widx].filesize > 0)
|
||||
audio_read_file();
|
||||
else if (!audio_load_track(offset, start_play))
|
||||
audio_read_file(false);
|
||||
else if (!audio_load_track(offset, start_play, rebuffer))
|
||||
fill_bytesleft = 0;
|
||||
|
||||
if (!had_next_track && audio_next_track())
|
||||
|
@ -2048,11 +2057,10 @@ static bool codec_request_next_track_callback(void)
|
|||
void audio_invalidate_tracks(void)
|
||||
{
|
||||
if (have_tracks()) {
|
||||
playlist_end = false;
|
||||
last_peek_offset = 0;
|
||||
|
||||
playlist_end = false;
|
||||
track_widx = track_ridx;
|
||||
|
||||
audio_clear_track_entries(true, true);
|
||||
|
||||
/* If the current track is fully buffered, advance the write pointer */
|
||||
|
@ -2070,6 +2078,35 @@ void audio_invalidate_tracks(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void audio_new_playlist(void)
|
||||
{
|
||||
/* Prepare to start a new fill from the beginning of the playlist */
|
||||
last_peek_offset = -1;
|
||||
if (have_tracks()) {
|
||||
playlist_end = false;
|
||||
track_widx = track_ridx;
|
||||
audio_clear_track_entries(true, true);
|
||||
|
||||
if (++track_widx >= MAX_TRACK)
|
||||
track_widx -= MAX_TRACK;
|
||||
|
||||
/* Stop reading the current track */
|
||||
cur_ti->filerem = 0;
|
||||
close(current_fd);
|
||||
current_fd = -1;
|
||||
|
||||
/* Invalidate the buffer other than the playing track */
|
||||
filebufused = cur_ti->available;
|
||||
buf_widx = buf_ridx + cur_ti->available;
|
||||
if (buf_widx >= filebuflen)
|
||||
buf_widx -= filebuflen;
|
||||
}
|
||||
/* Signal the codec to initiate a track change forward */
|
||||
new_playlist = true;
|
||||
ci.new_track = 1;
|
||||
audio_fill_file_buffer(false, true, 0);
|
||||
}
|
||||
|
||||
static void initiate_track_change(long direction)
|
||||
{
|
||||
playlist_end = false;
|
||||
|
@ -2105,7 +2142,7 @@ void audio_thread(void)
|
|||
if (!filling)
|
||||
if (!playing || playlist_end || ci.stop_codec)
|
||||
break;
|
||||
audio_fill_file_buffer(false, 0);
|
||||
audio_fill_file_buffer(false, false, 0);
|
||||
break;
|
||||
|
||||
case Q_AUDIO_PLAY:
|
||||
|
@ -2161,6 +2198,11 @@ void audio_thread(void)
|
|||
initiate_dir_change((long)ev.data);
|
||||
break;
|
||||
|
||||
case Q_AUDIO_NEW_PLAYLIST:
|
||||
logf("new_playlist");
|
||||
audio_new_playlist();
|
||||
break;
|
||||
|
||||
case Q_AUDIO_FLUSH:
|
||||
logf("flush & reload");
|
||||
audio_invalidate_tracks();
|
||||
|
@ -2441,18 +2483,14 @@ bool audio_has_changed_track(void)
|
|||
void audio_play(long offset)
|
||||
{
|
||||
logf("audio_play");
|
||||
if (pcmbuf_is_crossfade_enabled())
|
||||
{
|
||||
ci.stop_codec = true;
|
||||
sleep(1);
|
||||
pcmbuf_crossfade_init(true);
|
||||
}
|
||||
if (playing)
|
||||
queue_post(&audio_queue, Q_AUDIO_NEW_PLAYLIST, 0);
|
||||
else
|
||||
stop_codec_flush();
|
||||
|
||||
{
|
||||
playing = true;
|
||||
queue_post(&audio_queue, Q_AUDIO_PLAY, (void *)offset);
|
||||
}
|
||||
}
|
||||
|
||||
void audio_stop(void)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue