diff options
| author | Hardeep Sidhu <dyp@pobox.com> | 2003-12-09 08:18:03 +0000 |
|---|---|---|
| committer | Hardeep Sidhu <dyp@pobox.com> | 2003-12-09 08:18:03 +0000 |
| commit | 58bafee963dc9171a15d9540fe622705590da6ff (patch) | |
| tree | 1eb81504aaa3799ef8acf4999ceccc48c04f2900 | |
| parent | 166dc1743712a30ef2042be503cb888f93648b3f (diff) | |
| download | rockbox-58bafee963dc9171a15d9540fe622705590da6ff.zip rockbox-58bafee963dc9171a15d9540fe622705590da6ff.tar.gz rockbox-58bafee963dc9171a15d9540fe622705590da6ff.tar.bz2 rockbox-58bafee963dc9171a15d9540fe622705590da6ff.tar.xz | |
Don't write playlist shuffle settings immediately to disk. Instead, save them in global settings and only flush to disk when the playlist is modified \(e.g. insert,delete\). As part of the changes the resume index was changed from an int to a short to give an extra 2 bytes in RTC ram to be used for another playlist index.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4121 a1c6a512-1295-4272-9138-f99709370657
| -rw-r--r-- | apps/playlist.c | 186 | ||||
| -rw-r--r-- | apps/playlist.h | 7 | ||||
| -rw-r--r-- | apps/settings.c | 20 | ||||
| -rw-r--r-- | apps/settings.h | 5 |
4 files changed, 157 insertions, 61 deletions
diff --git a/apps/playlist.c b/apps/playlist.c index ff6ef0e..f834a3d 100644 --- a/apps/playlist.c +++ b/apps/playlist.c @@ -93,14 +93,14 @@ static struct playlist_info playlist; #define PLAYLIST_CONTROL_FILE ROCKBOX_DIR "/.playlist_control" -#define PLAYLIST_CONTROL_FILE_VERSION 1 +#define PLAYLIST_CONTROL_FILE_VERSION 2 /* 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 the index. - NOTE: This limits the playlist file size to a max of 512K. + NOTE: This limits the playlist file size to a max of 512M. Bits 31-30: 00 = Playlist track @@ -145,6 +145,7 @@ static int format_track_path(char *dest, char *src, int buf_length, int max, char *dir); static void display_playlist_count(int count, char *fmt); static void display_buffer_full(void); +static int flush_pending_control(void); /* * remove any files and indices associated with the playlist @@ -170,6 +171,7 @@ static void empty_playlist(bool resume) playlist.first_index = 0; playlist.amount = 0; playlist.last_insert_pos = -1; + playlist.shuffle_flush = false; if (!resume) { @@ -180,6 +182,10 @@ static void empty_playlist(bool resume) fd = creat(PLAYLIST_CONTROL_FILE, 0000200); if (fd >= 0) close(fd); + + /* Reset resume settings */ + global_settings.resume_first_index = 0; + global_settings.resume_seed = -1; } } @@ -357,8 +363,16 @@ static int add_track_to_playlist(char *filename, int position, bool queue, if (playlist.amount > 0 && insert_position <= playlist.first_index && position != PLAYLIST_PREPEND) + { playlist.first_index++; + if (seek_pos < 0) + { + global_settings.resume_first_index = playlist.first_index; + settings_save(); + } + } + if (insert_position < playlist.last_insert_pos || (insert_position == playlist.last_insert_pos && position < 0)) playlist.last_insert_pos++; @@ -367,6 +381,9 @@ static int add_track_to_playlist(char *filename, int position, bool queue, { int result = -1; + if (flush_pending_control() < 0) + return -1; + mutex_lock(&playlist.control_mutex); if (lseek(playlist.control_fd, 0, SEEK_END) >= 0) @@ -525,8 +542,16 @@ static int remove_track_from_playlist(int position, bool write) playlist.index--; if (position < playlist.first_index) + { playlist.first_index--; + if (write) + { + global_settings.resume_first_index = playlist.first_index; + settings_save(); + } + } + if (position <= playlist.last_insert_pos) playlist.last_insert_pos--; @@ -534,6 +559,9 @@ static int remove_track_from_playlist(int position, bool write) { int result = -1; + if (flush_pending_control() < 0) + return -1; + mutex_lock(&playlist.control_mutex); if (lseek(playlist.control_fd, 0, SEEK_END) >= 0) @@ -568,6 +596,10 @@ static int randomise_playlist(unsigned int seed, bool start_current, bool write) int store; unsigned int current = playlist.indices[playlist.index]; + /* seed 0 is used to identify sorted playlist for resume purposes */ + if (seed == 0) + seed = 1; + /* seed with the given seed */ srand(seed); @@ -589,29 +621,13 @@ static int randomise_playlist(unsigned int seed, bool start_current, bool write) /* indices have been moved so last insert position is no longer valid */ playlist.last_insert_pos = -1; - if (write && playlist.control_fd >= 0) + if (write) { - int result = -1; - - mutex_lock(&playlist.control_mutex); - - if (lseek(playlist.control_fd, 0, SEEK_END) >= 0) - { - if (fprintf(playlist.control_fd, "S:%d:%d\n", seed, - playlist.first_index) > 0) - { - fsync(playlist.control_fd); - result = 0; - } - } - - mutex_unlock(&playlist.control_mutex); - - if (result < 0) - { - splash(HZ*2, 0, true, str(LANG_PLAYLIST_CONTROL_UPDATE_ERROR)); - return result; - } + /* Don't write to disk immediately. Instead, save in settings and + only flush if playlist is modified (insertion/deletion) */ + playlist.shuffle_flush = true; + global_settings.resume_seed = seed; + settings_save(); } return 0; @@ -637,27 +653,11 @@ static int sort_playlist(bool start_current, bool write) if (write && playlist.control_fd >= 0) { - int result = -1; - - mutex_lock(&playlist.control_mutex); - - if (lseek(playlist.control_fd, 0, SEEK_END) >= 0) - { - if (fprintf(playlist.control_fd, "U:%d\n", playlist.first_index) > - 0) - { - fsync(playlist.control_fd); - result = 0; - } - } - - mutex_unlock(&playlist.control_mutex); - - if (result < 0) - { - splash(HZ*2, 0, true, str(LANG_PLAYLIST_CONTROL_UPDATE_ERROR)); - return result; - } + /* Don't write to disk immediately. Instead, save in settings and + only flush if playlist is modified (insertion/deletion) */ + playlist.shuffle_flush = true; + global_settings.resume_seed = 0; + settings_save(); } return 0; @@ -745,7 +745,9 @@ static void find_and_set_playlist_index(unsigned int seek) { if (playlist.indices[i] == seek) { - playlist.index = playlist.first_index = i; + playlist.index = global_settings.resume_first_index = + playlist.first_index = i; + settings_save(); break; } } @@ -941,6 +943,56 @@ static void display_buffer_full(void) } /* + * Flush any pending control commands to disk. Called when playlist is being + * modified. Returns 0 on success and -1 on failure. + */ +static int flush_pending_control(void) +{ + int result = 0; + + if (playlist.shuffle_flush && global_settings.resume_seed >= 0) + { + /* pending shuffle */ + mutex_lock(&playlist.control_mutex); + + if (lseek(playlist.control_fd, 0, SEEK_END) >= 0) + { + if (global_settings.resume_seed == 0) + result = fprintf(playlist.control_fd, "U:%d\n", + playlist.first_index); + else + result = fprintf(playlist.control_fd, "S:%d:%d\n", + global_settings.resume_seed, playlist.first_index); + + if (result > 0) + { + fsync(playlist.control_fd); + + playlist.shuffle_flush = false; + global_settings.resume_seed = -1; + settings_save(); + + result = 0; + } + else + result = -1; + } + else + result = -1; + + mutex_unlock(&playlist.control_mutex); + + if (result < 0) + { + splash(HZ*2, 0, true, str(LANG_PLAYLIST_CONTROL_UPDATE_ERROR)); + return result; + } + } + + return result; +} + +/* * Initialize playlist entries at startup */ void playlist_init(void) @@ -1008,6 +1060,7 @@ int playlist_resume(void) int nread; int total_read = 0; bool first = true; + bool sorted = true; enum { resume_playlist, @@ -1089,11 +1142,7 @@ int playlist_resume(void) version = atoi(str1); if (version != PLAYLIST_CONTROL_FILE_VERSION) - { - result = -1; - exit_loop = true; - break; - } + return -1; update_playlist_filename(str2, str3); @@ -1177,12 +1226,19 @@ int playlist_resume(void) break; } + if (!sorted) + { + /* Always sort list before shuffling */ + sort_playlist(false, false); + } + seed = atoi(str1); playlist.first_index = atoi(str2); if (randomise_playlist(seed, false, false) < 0) return -1; + sorted = false; break; } case resume_unshuffle: @@ -1200,6 +1256,7 @@ int playlist_resume(void) if (sort_playlist(false, false) < 0) return -1; + sorted = true; break; } case resume_reset: @@ -1334,7 +1391,26 @@ int playlist_resume(void) /* Terminate on EOF */ if(nread <= 0) + { + if (global_settings.resume_seed >= 0) + { + /* Apply shuffle command saved in settings */ + if (global_settings.resume_seed == 0) + sort_playlist(false, true); + else + { + if (!sorted) + sort_playlist(false, false); + + randomise_playlist(global_settings.resume_seed, false, + true); + } + + playlist.first_index = global_settings.resume_first_index; + } + break; + } } return 0; @@ -1557,7 +1633,8 @@ int playlist_shuffle(int random_seed, int start_index) { /* store the seek position before the shuffle */ seek_pos = playlist.indices[start_index]; - playlist.index = playlist.first_index = start_index; + playlist.index = global_settings.resume_first_index = + playlist.first_index = start_index; start_current = true; } @@ -1565,6 +1642,9 @@ int playlist_shuffle(int random_seed, int start_index) randomise_playlist(random_seed, start_current, true); + /* Flush shuffle command to disk */ + flush_pending_control(); + return playlist.index; } @@ -1734,7 +1814,7 @@ int playlist_next(int steps) /* Get resume info for current playing song. If return value is -1 then settings shouldn't be saved. */ -int playlist_get_resume_info(int *resume_index) +int playlist_get_resume_info(short *resume_index) { *resume_index = playlist.index; diff --git a/apps/playlist.h b/apps/playlist.h index 0b30e7a..45ecba5 100644 --- a/apps/playlist.h +++ b/apps/playlist.h @@ -39,10 +39,11 @@ struct playlist_info char *buffer; /* buffer for in-ram playlists */ int buffer_size; /* size of buffer */ int buffer_end_pos; /* last position where buffer was written */ - int index; /* index of current playing track */ - int first_index; /* index of first song in playlist */ + short index; /* index of current playing track */ + short first_index; /* index of first song in playlist */ int amount; /* number of tracks in the index */ int last_insert_pos; /* last position we inserted a track */ + bool shuffle_flush; /* Does shuffle value need to be flushed? */ struct mutex control_mutex; /* mutex for control file access */ }; @@ -62,7 +63,7 @@ int playlist_start(int start_index, int offset); bool playlist_check(int steps); char *playlist_peek(int steps); int playlist_next(int steps); -int playlist_get_resume_info(int *resume_index); +int playlist_get_resume_info(short *resume_index); int playlist_get_display_index(void); int playlist_amount(void); char *playlist_name(char *buf, int buf_size); diff --git a/apps/settings.c b/apps/settings.c index 6a7fe97..3c56257 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -97,13 +97,14 @@ offset abs 0x0f 0x23 <volume type, battery type, timeformat, scroll speed> 0x10 0x24 <ff/rewind min step, acceleration rate> 0x11 0x25 <AVC, channel config> -0x12 0x26 <(int) Resume playlist index, or -1 if no playlist resume> +0x12 0x26 <(short) Resume playlist index, or -1 if no playlist resume> +0x14 0x28 <(short) Resume playlist first index> 0x16 0x2a <(int) Byte offset into resume file> 0x1a 0x2e <time until disk spindown> 0x1b 0x2f <browse current, play selected, recursive dir insert> 0x1c 0x30 <peak meter hold timeout (bit 0-4), rec_editable (bit 7)> -0x1d 0x31 <unused> +0x1d 0x31 <(int) Resume shuffle seed, or -1 if no shuffle> 0x21 0x35 <repeat mode (bit 0-1), rec. channels (bit 2), mic gain (bit 4-7)> 0x22 0x36 <rec. quality (bit 0-2), source (bit 3-4), frequency (bit 5-7)> @@ -347,7 +348,8 @@ int settings_save( void ) ((global_settings.avc & 0x03) | ((global_settings.channel_config & 0x07) << 2)); - memcpy(&config_block[0x12], &global_settings.resume_index, 4); + memcpy(&config_block[0x12], &global_settings.resume_index, 2); + memcpy(&config_block[0x14], &global_settings.resume_first_index, 2); memcpy(&config_block[0x16], &global_settings.resume_offset, 4); DEBUGF( "+Resume index %X offset %X\n", global_settings.resume_index, @@ -362,6 +364,8 @@ int settings_save( void ) config_block[0x1c] = (unsigned char)global_settings.peak_meter_hold | (global_settings.rec_editable?0x80:0); + memcpy(&config_block[0x1d], &global_settings.resume_seed, 4); + config_block[0x21] = (unsigned char) ((global_settings.repeat_mode & 3) | ((global_settings.rec_channels & 1) << 2) | @@ -636,7 +640,10 @@ void settings_load(void) } if (config_block[0x12] != 0xFF) - memcpy(&global_settings.resume_index, &config_block[0x12], 4); + memcpy(&global_settings.resume_index, &config_block[0x12], 2); + + if (config_block[0x14] != 0xFF) + memcpy(&global_settings.resume_first_index, &config_block[0x14], 2); if (config_block[0x16] != 0xFF) memcpy(&global_settings.resume_offset, &config_block[0x16], 4); @@ -657,6 +664,9 @@ void settings_load(void) (config_block[0x1c] & 0x80)?true:false; } + if (config_block[0x1d] != 0xFF) + memcpy(&global_settings.resume_seed, &config_block[0x1d], 4); + if (config_block[0x21] != 0xFF) { global_settings.repeat_mode = config_block[0x21] & 3; @@ -1468,7 +1478,9 @@ void settings_reset(void) { global_settings.ff_rewind_min_step = DEFAULT_FF_REWIND_MIN_STEP; global_settings.ff_rewind_accel = DEFAULT_FF_REWIND_ACCEL_SETTING; global_settings.resume_index = -1; + global_settings.resume_first_index = 0; global_settings.resume_offset = -1; + global_settings.resume_seed = -1; global_settings.disk_spindown = 5; global_settings.disk_poweroff = false; global_settings.buffer_margin = 0; diff --git a/apps/settings.h b/apps/settings.h index c0e7854..b96f4c6 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -104,8 +104,11 @@ struct user_settings /* resume settings */ int resume; /* resume option: 0=off, 1=ask, 2=on */ - int resume_index; /* index in playlist (-1 for no active resume) */ + short resume_index; /* index in playlist (-1 for no active resume) */ + short resume_first_index; /* index of first track in playlist */ int resume_offset; /* byte offset in mp3 file */ + int resume_seed; /* shuffle seed (-1=no resume shuffle 0=sorted + >0=shuffled) */ unsigned char font_file[MAX_FILENAME+1]; /* last font */ unsigned char wps_file[MAX_FILENAME+1]; /* last wps */ |