summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2005-06-13 22:09:12 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2005-06-13 22:09:12 +0000
commit58af47c8f23531fe1947fc1a01c46060e4071cb2 (patch)
tree08626174a34e744576fd72e0adc14d0efee51e02
parent789791e659dd1288e8d5ab9159c8d75b17c8a458 (diff)
downloadrockbox-58af47c8f23531fe1947fc1a01c46060e4071cb2.zip
rockbox-58af47c8f23531fe1947fc1a01c46060e4071cb2.tar.gz
rockbox-58af47c8f23531fe1947fc1a01c46060e4071cb2.tar.bz2
rockbox-58af47c8f23531fe1947fc1a01c46060e4071cb2.tar.xz
Seeking forwards works a little better. Playlist handling still buggy.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6702 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/playback.c103
1 files changed, 74 insertions, 29 deletions
diff --git a/apps/playback.c b/apps/playback.c
index df0353b..cda67ac 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -82,6 +82,7 @@ static volatile bool paused;
#define AUDIO_FF_REWIND 7
#define AUDIO_FLUSH_RELOAD 8
#define AUDIO_CODEC_DONE 9
+#define AUDIO_FLUSH 10
#define CODEC_LOAD 1
#define CODEC_LOAD_DISK 2
@@ -283,24 +284,30 @@ void codec_advance_buffer_callback(size_t amount)
{
if ((int)amount > cur_ti->available + cur_ti->filerem)
amount = cur_ti->available + cur_ti->filerem;
-
+
+ try_again:
if ((int)amount > cur_ti->available) {
+ if (filling) {
+ while (filling)
+ yield();
+ goto try_again;
+ }
codecbufused = 0;
buf_ridx = 0;
buf_widx = 0;
- cur_ti->start_pos += amount;
+ cur_ti->start_pos = ci.curpos + amount;
amount -= cur_ti->available;
ci.curpos += cur_ti->available;
cur_ti->available = 0;
- while ((int)amount < cur_ti->available && !ci.stop_codec)
+ while ((int)amount > cur_ti->available && !ci.stop_codec)
yield();
- } else {
- cur_ti->available -= amount;
- codecbufused -= amount;
- buf_ridx += amount;
- if (buf_ridx >= codecbuflen)
- buf_ridx -= codecbuflen;
}
+
+ buf_ridx += amount;
+ if (buf_ridx >= codecbuflen)
+ buf_ridx -= codecbuflen;
+ cur_ti->available -= amount;
+ codecbufused -= amount;
ci.curpos += amount;
cur_ti->id3.offset = ci.curpos;
}
@@ -447,6 +454,7 @@ void audio_fill_file_buffer(void)
size_t i;
int rc;
+ tracks[track_widx].start_pos = ci.curpos;
logf("Filling buffer...");
i = 0;
while ((off_t)i < tracks[track_widx].filerem) {
@@ -455,8 +463,8 @@ void audio_fill_file_buffer(void)
if (!queue_empty(&audio_queue)) {
logf("Filling interrupted");
- close(current_fd);
- current_fd = -1;
+ //close(current_fd);
+ //current_fd = -1;
return ;
}
@@ -480,13 +488,9 @@ void audio_fill_file_buffer(void)
codecbufused += i;
tracks[track_widx].filerem -= i;
- tracks[track_widx].start_pos = tracks[track_widx].filepos;
tracks[track_widx].filepos += i;
logf("Done:%d", tracks[track_widx].available);
if (tracks[track_widx].filerem == 0) {
- if (++track_widx == MAX_TRACK)
- track_widx = 0;
- tracks[track_widx].filerem = 0;
close(current_fd);
current_fd = -1;
}
@@ -667,7 +671,7 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
if (!queue_empty(&audio_queue)) {
logf("Interrupted!");
- ci.stop_codec = true;
+ //ci.stop_codec = true;
close(fd);
return false;
}
@@ -949,8 +953,11 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
break;
}
- track_changed = true;
- track_count++;
+ if (start_play) {
+ track_count++;
+ track_changed = true;
+ }
+
i = tracks[track_widx].start_pos;
while (i < size) {
/* Give codecs some processing time to prevent glitches. */
@@ -990,6 +997,9 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
fill_bytesleft -= rc;
}
+ if (!start_play)
+ track_count++;
+
tracks[track_widx].filepos = i;
/* Leave the file handle open for faster buffer refill. */
@@ -1042,6 +1052,19 @@ void audio_play_start(int offset)
#endif
}
+void audio_clear_track_entries(void)
+{
+ int cur_idx;
+ int i;
+
+ cur_idx = track_widx;
+ for (i = 0; i < MAX_TRACK - track_count; i++) {
+ if (++cur_idx >= MAX_TRACK)
+ cur_idx = 0;
+ memset(&tracks[cur_idx], 0, sizeof(struct track_info));
+ }
+}
+
void audio_check_buffer(void)
{
int i;
@@ -1077,22 +1100,24 @@ void audio_check_buffer(void)
}
track_count = i;
- if (tracks[cur_idx].filerem != 0)
+ if (tracks[track_widx].filerem != 0)
track_count++;
/* Mark all other entries null. */
- cur_idx = track_widx;
- for (i = 0; i < MAX_TRACK - track_count; i++) {
- if (++cur_idx >= MAX_TRACK)
- cur_idx = 0;
- tracks[cur_idx].filesize = 0;
- tracks[cur_idx].available = 0;
- }
+ audio_clear_track_entries();
/* Try to load remainings of the file. */
if (tracks[track_widx].filerem > 0)
audio_fill_file_buffer();
+ /* Increase track write index as necessary. */
+ if (tracks[track_widx].filerem == 0 && tracks[track_widx].filesize != 0) {
+ if (++track_widx == MAX_TRACK)
+ track_widx = 0;
+ logf("new ti: %d", track_widx);
+ }
+
+ logf("ti: %d", track_widx);
/* Load new files to fill the entire buffer. */
if (tracks[track_widx].filerem == 0)
audio_insert_tracks(0, false, 1);
@@ -1224,15 +1249,30 @@ bool codec_request_next_track_callback(void)
return true;
}
+/* Invalidates all but currently playing track. */
+void audio_invalidate_tracks(void)
+{
+ if (track_count == 0) {
+ queue_post(&audio_queue, AUDIO_PLAY, 0);
+ return ;
+ }
+
+ track_count = 1;
+ track_widx = track_ridx;
+ audio_clear_track_entries();
+ codecbufused = cur_ti->available;
+ buf_widx = buf_ridx + cur_ti->available;
+ if (buf_widx >= codecbuflen)
+ buf_widx -= codecbuflen;
+}
+
void audio_thread(void)
{
struct event ev;
while (1) {
- sleep(50);
audio_check_buffer();
-
- queue_wait_w_tmo(&audio_queue, &ev, 10);
+ queue_wait_w_tmo(&audio_queue, &ev, 100);
switch (ev.id) {
case AUDIO_PLAY:
ci.stop_codec = true;
@@ -1261,6 +1301,10 @@ void audio_thread(void)
case AUDIO_NEXT:
break ;
+ case AUDIO_FLUSH:
+ audio_invalidate_tracks();
+ break ;
+
case AUDIO_CODEC_DONE:
//if (playing)
// audio_change_track();
@@ -1476,6 +1520,7 @@ void audio_ff_rewind(int newpos)
void audio_flush_and_reload_tracks(void)
{
logf("flush & reload");
+ queue_post(&audio_queue, AUDIO_FLUSH, 0);
}
void audio_error_clear(void)