1
0
Fork 0
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:
Brandon Low 2006-04-26 04:01:35 +00:00
parent 96dce1d3b7
commit da1cddfcbb

View file

@ -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,17 +2483,13 @@ 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);
{
playing = true;
queue_post(&audio_queue, Q_AUDIO_PLAY, (void *)offset);
}
}
void audio_stop(void)