1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Miika Pekkarinen 2005-10-21 06:40:45 +00:00
parent ddad7197ed
commit c52f7f1b5e
5 changed files with 113 additions and 30 deletions

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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,

View file

@ -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);
}