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_FLUSH,
|
||||||
Q_AUDIO_TRACK_CHANGED,
|
Q_AUDIO_TRACK_CHANGED,
|
||||||
Q_AUDIO_DIR_SKIP,
|
Q_AUDIO_DIR_SKIP,
|
||||||
|
Q_AUDIO_NEW_PLAYLIST,
|
||||||
Q_AUDIO_POSTINIT,
|
Q_AUDIO_POSTINIT,
|
||||||
Q_AUDIO_FILL_BUFFER,
|
Q_AUDIO_FILL_BUFFER,
|
||||||
|
|
||||||
|
@ -237,6 +238,7 @@ extern struct codec_api ci_voice;
|
||||||
/* Was the skip being executed manual or automatic? */
|
/* Was the skip being executed manual or automatic? */
|
||||||
static bool automatic_skip;
|
static bool automatic_skip;
|
||||||
static bool dir_skip = false;
|
static bool dir_skip = false;
|
||||||
|
static bool new_playlist = false;
|
||||||
|
|
||||||
/* Callback function to call when current track has really changed. */
|
/* Callback function to call when current track has really changed. */
|
||||||
void (*track_changed_callback)(struct mp3entry *id3);
|
void (*track_changed_callback)(struct mp3entry *id3);
|
||||||
|
@ -258,7 +260,8 @@ static int mp3_get_file_pos(void);
|
||||||
static void audio_clear_track_entries(
|
static void audio_clear_track_entries(
|
||||||
bool clear_buffered, bool clear_unbuffered);
|
bool clear_buffered, bool clear_unbuffered);
|
||||||
static void initialize_buffer_fill(bool clear_tracks);
|
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)
|
static void swap_codec(void)
|
||||||
{
|
{
|
||||||
|
@ -883,13 +886,11 @@ static void audio_rebuffer(void)
|
||||||
audio_clear_track_entries(false, true);
|
audio_clear_track_entries(false, true);
|
||||||
filebufused = 0;
|
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 */
|
/* Fill the buffer */
|
||||||
last_peek_offset = -1;
|
last_peek_offset = -1;
|
||||||
cur_ti->filesize = 0;
|
cur_ti->filesize = 0;
|
||||||
cur_ti->start_pos = 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)
|
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 the playlist isn't that big */
|
||||||
if (!playlist_check(ci.new_track))
|
if (!playlist_check(ci.new_track))
|
||||||
{
|
{
|
||||||
|
@ -935,15 +939,15 @@ static void audio_check_new_track(void)
|
||||||
last_peek_offset -= ci.new_track;
|
last_peek_offset -= ci.new_track;
|
||||||
playlist_next(ci.new_track);
|
playlist_next(ci.new_track);
|
||||||
|
|
||||||
|
if (new_playlist)
|
||||||
|
ci.new_track = 1;
|
||||||
|
|
||||||
track_ridx+=ci.new_track;
|
track_ridx+=ci.new_track;
|
||||||
if (track_ridx >= MAX_TRACK)
|
if (track_ridx >= MAX_TRACK)
|
||||||
track_ridx -= MAX_TRACK;
|
track_ridx -= MAX_TRACK;
|
||||||
else if (track_ridx < 0)
|
else if (track_ridx < 0)
|
||||||
track_ridx += MAX_TRACK;
|
track_ridx += MAX_TRACK;
|
||||||
|
|
||||||
forward = ci.new_track > 0;
|
|
||||||
ci.new_track = 0;
|
|
||||||
|
|
||||||
/* Save the old track */
|
/* Save the old track */
|
||||||
prev_ti = cur_ti;
|
prev_ti = cur_ti;
|
||||||
/* Move to the new track */
|
/* Move to the new track */
|
||||||
|
@ -959,6 +963,9 @@ static void audio_check_new_track(void)
|
||||||
goto skip_done;
|
goto skip_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forward = ci.new_track > 0;
|
||||||
|
ci.new_track = 0;
|
||||||
|
|
||||||
/* If the target track is clearly not in memory */
|
/* If the target track is clearly not in memory */
|
||||||
if (cur_ti->filesize == 0 || !cur_ti->taginfo_ready)
|
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;
|
size_t copy_n;
|
||||||
int rc;
|
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
|
/* 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
|
* is an event to handle. In the latter case, break this fill cycle
|
||||||
* immediately */
|
* immediately */
|
||||||
if (yield_codecs())
|
if (quick || yield_codecs())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1581,7 +1588,7 @@ static bool read_next_metadata(void)
|
||||||
return status;
|
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;
|
char *trackname;
|
||||||
off_t size;
|
off_t size;
|
||||||
|
@ -1732,7 +1739,8 @@ static bool audio_load_track(int offset, bool start_play)
|
||||||
|
|
||||||
logf("alt:%s", trackname);
|
logf("alt:%s", trackname);
|
||||||
tracks[track_widx].buf_idx = buf_widx;
|
tracks[track_widx].buf_idx = buf_widx;
|
||||||
audio_read_file();
|
|
||||||
|
audio_read_file(rebuffer);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1851,7 +1859,7 @@ static void audio_play_start(size_t offset)
|
||||||
|
|
||||||
last_peek_offset = -1;
|
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. */
|
/* Send callback events to notify about new tracks. */
|
||||||
|
@ -1911,7 +1919,8 @@ static void initialize_buffer_fill(bool clear_tracks)
|
||||||
filling = true;
|
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;
|
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,
|
/* If we have a partially buffered track, continue loading,
|
||||||
* otherwise load a new track */
|
* otherwise load a new track */
|
||||||
if (tracks[track_widx].filesize > 0)
|
if (tracks[track_widx].filesize > 0)
|
||||||
audio_read_file();
|
audio_read_file(false);
|
||||||
else if (!audio_load_track(offset, start_play))
|
else if (!audio_load_track(offset, start_play, rebuffer))
|
||||||
fill_bytesleft = 0;
|
fill_bytesleft = 0;
|
||||||
|
|
||||||
if (!had_next_track && audio_next_track())
|
if (!had_next_track && audio_next_track())
|
||||||
|
@ -2048,11 +2057,10 @@ static bool codec_request_next_track_callback(void)
|
||||||
void audio_invalidate_tracks(void)
|
void audio_invalidate_tracks(void)
|
||||||
{
|
{
|
||||||
if (have_tracks()) {
|
if (have_tracks()) {
|
||||||
playlist_end = false;
|
|
||||||
last_peek_offset = 0;
|
last_peek_offset = 0;
|
||||||
|
|
||||||
|
playlist_end = false;
|
||||||
track_widx = track_ridx;
|
track_widx = track_ridx;
|
||||||
|
|
||||||
audio_clear_track_entries(true, true);
|
audio_clear_track_entries(true, true);
|
||||||
|
|
||||||
/* If the current track is fully buffered, advance the write pointer */
|
/* 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)
|
static void initiate_track_change(long direction)
|
||||||
{
|
{
|
||||||
playlist_end = false;
|
playlist_end = false;
|
||||||
|
@ -2105,7 +2142,7 @@ void audio_thread(void)
|
||||||
if (!filling)
|
if (!filling)
|
||||||
if (!playing || playlist_end || ci.stop_codec)
|
if (!playing || playlist_end || ci.stop_codec)
|
||||||
break;
|
break;
|
||||||
audio_fill_file_buffer(false, 0);
|
audio_fill_file_buffer(false, false, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Q_AUDIO_PLAY:
|
case Q_AUDIO_PLAY:
|
||||||
|
@ -2161,6 +2198,11 @@ void audio_thread(void)
|
||||||
initiate_dir_change((long)ev.data);
|
initiate_dir_change((long)ev.data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Q_AUDIO_NEW_PLAYLIST:
|
||||||
|
logf("new_playlist");
|
||||||
|
audio_new_playlist();
|
||||||
|
break;
|
||||||
|
|
||||||
case Q_AUDIO_FLUSH:
|
case Q_AUDIO_FLUSH:
|
||||||
logf("flush & reload");
|
logf("flush & reload");
|
||||||
audio_invalidate_tracks();
|
audio_invalidate_tracks();
|
||||||
|
@ -2441,17 +2483,13 @@ bool audio_has_changed_track(void)
|
||||||
void audio_play(long offset)
|
void audio_play(long offset)
|
||||||
{
|
{
|
||||||
logf("audio_play");
|
logf("audio_play");
|
||||||
if (pcmbuf_is_crossfade_enabled())
|
if (playing)
|
||||||
{
|
queue_post(&audio_queue, Q_AUDIO_NEW_PLAYLIST, 0);
|
||||||
ci.stop_codec = true;
|
|
||||||
sleep(1);
|
|
||||||
pcmbuf_crossfade_init(true);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
stop_codec_flush();
|
{
|
||||||
|
|
||||||
playing = true;
|
playing = true;
|
||||||
queue_post(&audio_queue, Q_AUDIO_PLAY, (void *)offset);
|
queue_post(&audio_queue, Q_AUDIO_PLAY, (void *)offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio_stop(void)
|
void audio_stop(void)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue