diff --git a/apps/playlist.c b/apps/playlist.c index 3dbbc9ea2d..68cf3b9e3d 100644 --- a/apps/playlist.c +++ b/apps/playlist.c @@ -415,6 +415,8 @@ void randomise_playlist( unsigned int seed ) playlist.indices[candidate] = playlist.indices[count]; playlist.indices[count] = store; } + + mpeg_flush_and_reload_tracks(); } static int compare(const void* p1, const void* p2) @@ -451,6 +453,8 @@ void sort_playlist(bool start_current) } } } + + mpeg_flush_and_reload_tracks(); } /* ----------------------------------------------------------------- diff --git a/firmware/mpeg.c b/firmware/mpeg.c index f5f8227fb9..365099129e 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c @@ -50,6 +50,7 @@ extern void bitswap(unsigned short *data, int length); #define MPEG_NEXT 5 #define MPEG_PREV 6 #define MPEG_FF_REWIND 7 +#define MPEG_FLUSH_RELOAD 8 #define MPEG_NEED_DATA 100 #define MPEG_SWAP_DATA 101 #define MPEG_TRACK_CHANGE 102 @@ -662,11 +663,15 @@ static int add_track_to_tag_list(char *filename) /* If next_track is true, opens the next track, if false, opens prev track */ static int new_file(int steps) { + int start = num_tracks_in_memory() - 1; + + if (start < 0) + start = 0; + do { char *trackname; - int index; - trackname = playlist_peek( steps ); + trackname = playlist_peek( start + steps ); if ( !trackname ) return -1; @@ -690,13 +695,11 @@ static int new_file(int steps) } else { - index = playlist_next(steps); - /* skip past id3v2 tag (to an even byte) */ lseek(mpeg_file, id3tags[new_tag_idx]->id3.id3v2len & ~1, SEEK_SET); - id3tags[new_tag_idx]->id3.index = index; + id3tags[new_tag_idx]->id3.index = steps; id3tags[new_tag_idx]->id3.offset = 0; } } @@ -717,6 +720,14 @@ static void stop_playing(void) remove_all_tags(); } +static void update_playlist(void) +{ + int index; + + index = playlist_next(id3tags[tag_read_idx]->id3.index); + id3tags[tag_read_idx]->id3.index = index; +} + static void track_change(void) { DEBUGF("Track change\n"); @@ -728,6 +739,8 @@ static void track_change(void) remove_current_tag(); current_track_counter++; + + update_playlist(); } static void mpeg_thread(void) @@ -876,7 +889,7 @@ static void mpeg_thread(void) else { reset_mp3_buffer(); remove_all_tags(); - + /* Open the next file */ if (mpeg_file >= 0) close(mpeg_file); @@ -894,6 +907,7 @@ static void mpeg_thread(void) play_pending = true; current_track_counter++; + update_playlist(); } } break; @@ -926,6 +940,7 @@ static void mpeg_thread(void) play_pending = true; current_track_counter++; + update_playlist(); } break; } @@ -1069,6 +1084,38 @@ static void mpeg_thread(void) break; } + case MPEG_FLUSH_RELOAD: { + int numtracks = num_tracks_in_memory(); + bool reload_track = false; + + if (numtracks > 1) + { + /* Reload songs */ + int next = (tag_read_idx+1) & MAX_ID3_TAGS_MASK; + + /* Reset the buffer */ + mp3buf_write = mp3buf_swapwrite = id3tags[next]->mempos; + + close(mpeg_file); + remove_all_non_current_tags(); + mpeg_file = -1; + reload_track = true; + } + else if (numtracks == 1 && mpeg_file < 0) + { + reload_track = true; + } + + if(reload_track && new_file(1) >= 0) + { + /* Tell ourselves that we want more data */ + queue_post(&mpeg_queue, MPEG_NEED_DATA, 0); + filling = true; + } + + break; + } + case MPEG_SWAP_DATA: free_space_left = mp3buf_write - mp3buf_swapwrite; @@ -1442,6 +1489,13 @@ void mpeg_ff_rewind(int change) #endif } +void mpeg_flush_and_reload_tracks(void) +{ +#ifndef SIMULATOR + queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, NULL); +#endif +} + bool mpeg_is_playing(void) { return is_playing; diff --git a/firmware/mpeg.h b/firmware/mpeg.h index 9565e34b42..f1451227d0 100644 --- a/firmware/mpeg.h +++ b/firmware/mpeg.h @@ -29,6 +29,7 @@ void mpeg_resume(void); void mpeg_next(void); void mpeg_prev(void); void mpeg_ff_rewind(int change); +void mpeg_flush_and_reload_tracks(void); bool mpeg_is_playing(void); void mpeg_sound_set(int setting, int value); int mpeg_sound_min(int setting);