summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2005-10-21 06:40:45 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2005-10-21 06:40:45 +0000
commitc52f7f1b5e02b48272037f7e82d1af43cea74b1d (patch)
tree1dbc6a56a36d66cec2d9701da3c188ffead6ed2b /apps
parentddad7197ed4d3c9db25bcbbcafd40ff82ad4b717 (diff)
downloadrockbox-c52f7f1b5e02b48272037f7e82d1af43cea74b1d.tar.gz
rockbox-c52f7f1b5e02b48272037f7e82d1af43cea74b1d.tar.bz2
rockbox-c52f7f1b5e02b48272037f7e82d1af43cea74b1d.zip
iRiver: Fixed broken items skipping on playlist: Now skipping and
marking them as bad instead of deleting the entries from playlist. Faster buffered track skipping and preventing glitches from previous tracks (still something might occur though, please report them). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7647 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/pcmbuf.c20
-rw-r--r--apps/playback.c25
-rw-r--r--apps/playlist.c86
-rw-r--r--apps/playlist.h2
-rw-r--r--apps/playlist_viewer.c10
5 files changed, 113 insertions, 30 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index 1bcfb25f5e..b67e889a95 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -193,7 +193,7 @@ void pcmbuf_watermark_callback(int bytes_left)
{
/* Fill audio buffer by boosting cpu */
pcmbuf_boost(true);
- if (bytes_left <= CHUNK_SIZE * 2)
+ if (bytes_left <= CHUNK_SIZE * 2 && crossfade_mode != CFM_FLUSH)
crossfade_active = false;
}
@@ -347,8 +347,9 @@ static void crossfade_start(void)
}
logf("crossfade_start");
- audiobuffer_fillpos = 0;
pcmbuf_boost(true);
+ while (audiobuffer_fillpos != 0)
+ pcmbuf_flush_fillpos();
crossfade_active = true;
crossfade_pos = audiobuffer_pos;
@@ -360,7 +361,7 @@ static void crossfade_start(void)
break ;
case CFM_FLUSH:
- crossfade_amount = (bytesleft - (CHUNK_SIZE * 2))/2;
+ crossfade_amount = bytesleft /2;
crossfade_rem = crossfade_amount;
break ;
}
@@ -439,13 +440,10 @@ void* pcmbuf_request_buffer(long length, long *realsize)
{
void *ptr = NULL;
- if (crossfade_init)
- crossfade_start();
-
- while (audiobuffer_free < length + audiobuffer_fillpos
- + CHUNK_SIZE && !crossfade_active) {
- pcmbuf_boost(false);
- sleep(1);
+ if (!prepare_insert(length))
+ {
+ *realsize = 0;
+ return NULL;
}
if (crossfade_active) {
@@ -473,8 +471,6 @@ void pcmbuf_flush_buffer(long length)
int copy_n;
char *buf;
- prepare_insert(length);
-
if (crossfade_active) {
buf = &guardbuf[0];
length = MIN(length, PCMBUF_GUARD);
diff --git a/apps/playback.c b/apps/playback.c
index 5b78ad53ba..7c3d63c5a8 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -296,9 +296,15 @@ bool codec_pcmbuf_insert_split_callback(void *ch1, void *ch2,
}
while (length > 0) {
+ /* This will prevent old audio from playing when skipping tracks. */
+ if (ci.reload_codec || ci.stop_codec)
+ return true;
+
while ((dest = pcmbuf_request_buffer(dsp_output_size(length),
&output_size)) == NULL) {
- yield();
+ sleep(1);
+ if (ci.reload_codec || ci.stop_codec)
+ return true;
}
/* Get the real input_size for output_size bytes, guarding
@@ -1008,7 +1014,6 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
off_t size;
int rc, i;
int copy_n;
- int playlist_index;
/* Stop buffer filling if there is no free track entries.
Don't fill up the last track entry (we wan't to store next track
@@ -1025,10 +1030,6 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
return false;
last_index = playlist_get_display_index();
- playlist_index = playlist_get_display_index() - 1
- + playlist_get_first_index(NULL) + peek_offset;
- if (playlist_index >= playlist_amount())
- playlist_index -= playlist_amount();
peek_again:
/* Get track name from current playlist read position. */
@@ -1038,8 +1039,8 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
fd = open(trackname, O_RDONLY);
if (fd < 0) {
logf("Open failed");
- /* Delete invalid entry from playlist. */
- playlist_delete(NULL, playlist_index);
+ /* Skip invalid entry from playlist. */
+ playlist_skip_entry(NULL, peek_offset);
continue ;
}
break ;
@@ -1088,8 +1089,8 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
/* Try skipping to next track. */
if (fill_bytesleft > 0) {
- /* Delete invalid entry from playlist. */
- playlist_delete(NULL, playlist_index);
+ /* Skip invalid entry from playlist. */
+ playlist_skip_entry(NULL, peek_offset);
goto peek_again;
}
return false;
@@ -1104,8 +1105,8 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
tracks[track_widx].filesize = 0;
tracks[track_widx].filerem = 0;
close(fd);
- /* Delete invalid entry from playlist. */
- playlist_delete(NULL, playlist_index);
+ /* Skip invalid entry from playlist. */
+ playlist_skip_entry(NULL, peek_offset);
goto peek_again;
}
}
diff --git a/apps/playlist.c b/apps/playlist.c
index 70df8113e0..91eacb7c03 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -99,10 +99,10 @@
/*
Each playlist index has a flag associated with it which identifies what
- type of track it is. These flags are stored in the 3 high order bits of
+ type of track it is. These flags are stored in the 4 high order bits of
the index.
- NOTE: This limits the playlist file size to a max of 512M.
+ NOTE: This limits the playlist file size to a max of 256M.
Bits 31-30:
00 = Playlist track
@@ -112,8 +112,11 @@
Bit 29:
0 = Added track
1 = Queued track
+ Bit 28:
+ 0 = Track entry is valid
+ 1 = Track does not exist on disk and should be skipped
*/
-#define PLAYLIST_SEEK_MASK 0x1FFFFFFF
+#define PLAYLIST_SEEK_MASK 0x07FFFFFF
#define PLAYLIST_INSERT_TYPE_MASK 0xC0000000
#define PLAYLIST_QUEUE_MASK 0x20000000
@@ -122,6 +125,7 @@
#define PLAYLIST_INSERT_TYPE_APPEND 0xC0000000
#define PLAYLIST_QUEUED 0x20000000
+#define PLAYLIST_SKIPPED 0x10000000
#define PLAYLIST_DISPLAY_COUNT 10
@@ -828,6 +832,72 @@ static int sort_playlist(struct playlist_info* playlist, bool start_current,
return 0;
}
+/* Marks the index of the track to be skipped that is "steps" away from
+ * current playing track.
+ */
+void playlist_skip_entry(struct playlist_info *playlist, int steps)
+{
+ int index;
+
+ if (playlist == NULL)
+ playlist = &current_playlist;
+
+ index = rotate_index(playlist, playlist->index);
+ index += steps;
+ if (index < 0 || index >= playlist->amount)
+ return ;
+
+ index = (index+playlist->first_index) % playlist->amount;
+ playlist->indices[index] |= PLAYLIST_SKIPPED;
+}
+
+/* Calculate how many steps we have to really step when skipping entries
+ * marked as bad.
+ */
+static int calculate_step_count(const struct playlist_info *playlist, int steps)
+{
+ int i, count, direction;
+ int index;
+ int stepped_count = 0;
+
+ if (steps < 0)
+ {
+ direction = -1;
+ count = -steps;
+ }
+ else
+ {
+ direction = 1;
+ count = steps;
+ }
+
+ index = playlist->index;
+ i = 0;
+ while (i < count)
+ {
+ index += direction;
+ /* Boundary check */
+ if (index < 0)
+ index += playlist->amount;
+ if (index >= playlist->amount)
+ index -= playlist->amount;
+
+ /* Check if we found a bad entry. */
+ if (playlist->indices[index] & PLAYLIST_SKIPPED)
+ {
+ steps += direction;
+ /* Are all entries bad? */
+ if (stepped_count++ > playlist->amount)
+ break ;
+ }
+ else
+ i++;
+ }
+
+ return steps;
+}
+
+
/*
* returns the index of the track that is "steps" away from current playing
* track.
@@ -848,6 +918,7 @@ static int get_next_index(const struct playlist_info* playlist, int steps,
(!global_settings.playlist_shuffle || playlist->amount <= 1))
repeat_mode = REPEAT_ALL;
+ steps = calculate_step_count(playlist, steps);
switch (repeat_mode)
{
case REPEAT_SHUFFLE:
@@ -856,7 +927,6 @@ static int get_next_index(const struct playlist_info* playlist, int steps,
case REPEAT_OFF:
{
current_index = rotate_index(playlist, current_index);
-
next_index = current_index+steps;
if ((next_index < 0) || (next_index >= playlist->amount))
next_index = -1;
@@ -904,6 +974,10 @@ static int get_next_index(const struct playlist_info* playlist, int steps,
}
}
+ /* No luck if the whole playlist was bad. */
+ if (playlist->indices[next_index] & PLAYLIST_SKIPPED)
+ return -1;
+
return next_index;
}
@@ -2652,8 +2726,12 @@ int playlist_get_track_info(struct playlist_info* playlist, int index,
info->attr |= PLAYLIST_ATTR_QUEUED;
else
info->attr |= PLAYLIST_ATTR_INSERTED;
+
}
+ if (playlist->indices[index] & PLAYLIST_SKIPPED)
+ info->attr |= PLAYLIST_ATTR_SKIPPED;
+
info->index = index;
info->display_index = rotate_index(playlist, index) + 1;
diff --git a/apps/playlist.h b/apps/playlist.h
index eee8bf5945..1937c48a12 100644
--- a/apps/playlist.h
+++ b/apps/playlist.h
@@ -58,6 +58,7 @@ struct playlist_info
#define PLAYLIST_ATTR_QUEUED 0x01
#define PLAYLIST_ATTR_INSERTED 0x02
+#define PLAYLIST_ATTR_SKIPPED 0x04
#define DEFAULT_DYNAMIC_PLAYLIST_NAME "/dynamic.m3u"
@@ -99,6 +100,7 @@ int playlist_insert_directory(struct playlist_info* playlist,
bool recurse);
int playlist_insert_playlist(struct playlist_info* playlist, char *filename,
int position, bool queue);
+void playlist_skip_entry(struct playlist_info *playlist, int steps);
int playlist_delete(struct playlist_info* playlist, int index);
int playlist_move(struct playlist_info* playlist, int index, int new_index);
int playlist_randomise(struct playlist_info* playlist, unsigned int seed,
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c
index b7a042733e..70c1cf8995 100644
--- a/apps/playlist_viewer.c
+++ b/apps/playlist_viewer.c
@@ -112,6 +112,7 @@ struct playlist_entry {
int index; /* Playlist index */
int display_index; /* Display index */
bool queued; /* Is track queued? */
+ bool skipped; /* Is track marked as bad? */
};
static struct playlist_viewer_info viewer;
@@ -381,6 +382,7 @@ static int load_entry(int index, int pos, char* p, int size)
tracks[pos].index = info.index;
tracks[pos].display_index = info.display_index;
tracks[pos].queued = info.attr & PLAYLIST_ATTR_QUEUED;
+ tracks[pos].skipped = info.attr & PLAYLIST_ATTR_SKIPPED;
result = len;
}
@@ -424,14 +426,18 @@ static void format_name(char* dest, const char* src)
static void format_line(const struct playlist_entry* track, char* str, int len)
{
char name[MAX_PATH];
+ char *skipped = "";
format_name(name, track->name);
+ if (track->skipped)
+ skipped = "(ERR) ";
+
if (global_settings.playlist_viewer_indices)
/* Display playlist index */
- snprintf(str, len, "%d. %s", track->display_index, name);
+ snprintf(str, len, "%d. %s%s", track->display_index, skipped, name);
else
- snprintf(str, len, "%s", name);
+ snprintf(str, len, "%s%s", skipped, name);
}