Index: applimits.h =================================================================== RCS file: /cvsroot/rockbox/apps/applimits.h,v retrieving revision 1.1 diff -u -b -r1.1 applimits.h --- applimits.h 15 Aug 2002 12:28:51 -0000 1.1 +++ applimits.h 29 Aug 2002 23:30:46 -0000 @@ -23,5 +23,6 @@ #define AVERAGE_FILENAME_LENGTH 40 #define MAX_DIR_LEVELS 10 #define MAX_PLAYLIST_SIZE 10000 +#define MAX_PLAYLIST_FILES 20 #endif Index: playlist.c =================================================================== RCS file: /cvsroot/rockbox/apps/playlist.c,v retrieving revision 1.44 diff -u -b -r1.44 playlist.c --- playlist.c 28 Aug 2002 09:22:44 -0000 1.44 +++ playlist.c 29 Aug 2002 23:30:46 -0000 @@ -7,7 +7,7 @@ * \/ \/ \/ \/ \/ * $Id: playlist.c,v 1.44 2002/08/28 09:22:44 bagder Exp $ * - * Copyright (C) 2002 by wavey@wavey.org + * Copyright (C) 2002 by wavey@wavey.org, john@pybus.org * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. @@ -39,20 +39,82 @@ #define PLAYLIST_BUFFER_SIZE (AVERAGE_FILENAME_LENGTH*MAX_FILES_IN_DIR) +static struct playlist_file pl_files[MAX_PLAYLIST_FILES]; + unsigned char playlist_buffer[PLAYLIST_BUFFER_SIZE]; static int playlist_end_pos = 0; +static int playlist_end_file = 0; + char now_playing[MAX_PATH+1]; + +#define INDICES_SHIFT 20 +#define INDICES_MASK (~(~0 << INDICES_SHIFT)) + +#define GET_PL_FILE_INDEX( ind ) ( playlist.indices[ind] >> INDICES_SHIFT ) + +#define GET_PL_INDEX( ind ) ( playlist.indices[ind] & INDICES_MASK ) + +/* + * Clear all playlist data. + */ void playlist_clear(void) { playlist_end_pos = 0; playlist_buffer[0] = 0; + playlist_end_file = 0; + playlist.index = 0; + playlist.amount = 0; } -int playlist_add(char *filename) +/* + * Initialise a new playlist_file with the directory to add playlist + * entries from. + */ +int playlist_newdir(char *dir) +{ + struct playlist_file *pl_file; + int dirlen; + char *sep=""; + + /* Allocate space for playlist_file information*/ + if (playlist_end_file >= MAX_PLAYLIST_FILES) + return -1; + pl_file = &pl_files[playlist_end_file++]; + playlist_end_pos += sizeof(struct playlist_file); + + if ( playlist_end_pos >= PLAYLIST_BUFFER_SIZE ) + return -1; + + pl_file->in_ram = true; + + dirlen = strlen(dir); + + /* If the dir does not end in trailing slash, we use a separator. + Otherwise we don't. */ + if('/' != dir[dirlen-1]) { + sep="/"; + dirlen++; + } + + pl_file->dirlen = dirlen; + + snprintf(pl_file->filename, sizeof(pl_file->filename), + "%s%s", dir, sep); + + /* return pl_file index to use in playlist_add() */ + return playlist_end_file - 1; +} + +/* + * Add a file to an in-RAM playlist. Needs the index of + * a playlist_file with the files directory. + */ +int playlist_add_file(char *filename, int pl_dir) { int len = strlen(filename); + int pos = playlist_end_pos; if(len+2 > PLAYLIST_BUFFER_SIZE - playlist_end_pos) return -1; @@ -61,6 +123,17 @@ playlist_end_pos += len; playlist_buffer[playlist_end_pos++] = '\n'; playlist_buffer[playlist_end_pos] = '\0'; + + /* add index */ + if ( playlist.amount < MAX_PLAYLIST_SIZE ) { + int to_store = pos | ( (pl_dir) << INDICES_SHIFT ); + + playlist.indices[ playlist.amount ] = to_store; + playlist.amount++; + } else { + return -1; + } + return 0; } @@ -84,8 +157,10 @@ int i; char *buf; char dir_buf[MAX_PATH+1]; + char f_buf[MAX_PATH+1]; char *dir_end; int index; + struct playlist_file *pl_file; if(abs(steps) > playlist.amount) /* prevent madness when all files are empty/bad */ @@ -98,19 +173,21 @@ else index = 0; } - seek = playlist.indices[index]; + seek = GET_PL_INDEX(index); - if(playlist.in_ram) + pl_file = &pl_files[GET_PL_FILE_INDEX(index)]; + + if(pl_file->in_ram) { buf = playlist_buffer + seek; max = playlist_end_pos - seek; } else { - fd = open(playlist.filename, O_RDONLY); + fd = open(pl_file->filename, O_RDONLY); if(-1 != fd) { - buf = playlist_buffer; + buf = f_buf; lseek(fd, seek, SEEK_SET); max = read(fd, buf, MAX_PATH); close(fd); @@ -123,6 +200,7 @@ seek=0; while((buf[seek] != '\n') && (buf[seek] != '\r') && + (buf[seek] != 0 ) && (seek < max)) seek++; @@ -143,8 +221,8 @@ return now_playing; } else { - strncpy(dir_buf, playlist.filename, playlist.dirlen-1); - dir_buf[playlist.dirlen-1] = 0; + strncpy(dir_buf, pl_file->filename, pl_file->dirlen - 1); + dir_buf[pl_file->dirlen - 1] = 0; /* handle dos style drive letter */ if ( ':' == buf[1] ) { @@ -179,46 +257,29 @@ } } -/* - * This function is called to start playback of a given playlist. This - * playlist may be stored in RAM (when using full-dir playback). - * - * Return: the new index (possibly different due to shuffle) - */ -int play_list(char *dir, /* "current directory" */ - char *file, /* playlist */ - int start_index, /* index in the playlist */ - bool shuffled_index, /* if TRUE the specified index is for the - playlist AFTER the shuffle */ - int start_offset, /* offset in the file */ - int random_seed ) /* used for shuffling */ +void load_playlist(char *dir, /* "current directory" */ + char *file, /* playlist file */ + bool show_prog ) { char *sep=""; int dirlen; - empty_playlist(); - - playlist.index = start_index; - -#ifdef HAVE_LCD_BITMAP - if(global_settings.statusbar) - lcd_setmargins(0, STATUSBAR_HEIGHT); - else - lcd_setmargins(0, 0); -#endif + struct playlist_file *pl_file; - /* If file is NULL, the list is in RAM */ - if(file) { + if (show_prog) { lcd_clear_display(); lcd_puts(0,0,"Loading..."); status_draw(); lcd_update(); - playlist.in_ram = false; - } else { - /* Assign a dummy filename */ - file = ""; - playlist.in_ram = true; } + /* Allocate space for playlist_file information*/ + if (playlist_end_file >= MAX_PLAYLIST_FILES) + return; + pl_file = &pl_files[playlist_end_file++]; + playlist_end_pos += sizeof(struct playlist_file); + + pl_file->in_ram = false; + dirlen = strlen(dir); /* If the dir does not end in trailing slash, we use a separator. @@ -228,27 +289,50 @@ dirlen++; } - playlist.dirlen = dirlen; + pl_file->dirlen = dirlen; - snprintf(playlist.filename, sizeof(playlist.filename), + snprintf(pl_file->filename, sizeof(pl_file->filename), "%s%s%s", dir, sep, file); /* add track indices to playlist data structure */ - add_indices_to_playlist(); + add_indices_to_playlist(playlist_end_file - 1, show_prog); +} + +/* + * This function is called to start playback of a given playlist. This + * playlist may be stored in RAM (when using full-dir playback). + * + * Return: the new index (possibly different due to shuffle) + */ +int play_list(int start_index, /* index in the playlist */ + bool shuffled_index, /* if TRUE the specified index is for the + playlist AFTER the shuffle */ + int start_offset, /* offset in the file */ + int random_seed ) /* used for shuffling */ +{ + bool show_prog = true; + + playlist.index = start_index; + +#ifdef HAVE_LCD_BITMAP + if(global_settings.statusbar) + lcd_setmargins(0, STATUSBAR_HEIGHT); + else + lcd_setmargins(0, 0); +#endif if(global_settings.playlist_shuffle) { - if(!playlist.in_ram) { + int i; + /* store the seek position before the shuffle */ + int seek_pos = playlist.indices[start_index]; + + if(show_prog) { + lcd_clear_display(); lcd_puts(0,0,"Shuffling..."); status_draw(); lcd_update(); - randomise_playlist( random_seed ); } - else { - int i; - - /* store the seek position before the shuffle */ - int seek_pos = playlist.indices[start_index]; /* now shuffle around the indices */ randomise_playlist( random_seed ); @@ -256,10 +340,9 @@ if(!shuffled_index) { /* The given index was for the unshuffled list, so we need to figure out the index AFTER the shuffle has been made. - We scan for the seek position we remmber from before. */ - + We scan for the seek position we remember from before. */ for(i=0; i< playlist.amount; i++) { - if(seek_pos == playlist.indices[i]) { + if(seek_pos == playlist.indices[i] ) { /* here's the start song! yiepee! */ playlist.index = i; break; /* now stop searching */ @@ -270,13 +353,13 @@ instead */ } } - } - if(!playlist.in_ram) { + if(show_prog) { lcd_puts(0,0,"Playing... "); status_draw(); lcd_update(); } + /* also make the first song get playing */ mpeg_play(start_offset); @@ -284,19 +367,11 @@ } /* - * remove any filename and indices associated with the playlist - */ -void empty_playlist(void) -{ - playlist.filename[0] = '\0'; - playlist.index = 0; - playlist.amount = 0; -} - -/* * calculate track offsets within a playlist file + * No longer deals with in-RAM playlists, they're + * are indexed as they're added. */ -void add_indices_to_playlist(void) +void add_indices_to_playlist(int pl_file_indx, bool show_prog) { int nread; int fd = -1; @@ -305,29 +380,24 @@ int count = 0; int next_tick = current_tick + HZ; - unsigned char *p = playlist_buffer; + unsigned char *p = &playlist_buffer[playlist_end_pos]; char line[16]; - if(!playlist.in_ram) { - fd = open(playlist.filename, O_RDONLY); + if (playlist_end_pos >= PLAYLIST_BUFFER_SIZE) + return; /* no buffer space */ + + fd = open(pl_files[pl_file_indx].filename, O_RDONLY); if(-1 == fd) return; /* failure */ - } store_index = 1; while(1) { - if(playlist.in_ram) { - nread = playlist_end_pos; - } else { - nread = read(fd, playlist_buffer, PLAYLIST_BUFFER_SIZE); + nread = read(fd, p, PLAYLIST_BUFFER_SIZE - playlist_end_pos); /* Terminate on EOF */ if(nread <= 0) break; - } - - p = playlist_buffer; for(count=0; count < nread; count++,p++) { @@ -345,12 +415,11 @@ } else if(store_index) { - + int to_store = (i + count) | ( pl_file_indx << INDICES_SHIFT ); /* Store a new entry */ - playlist.indices[ playlist.amount ] = i+count; + playlist.indices[ playlist.amount ] = to_store ; playlist.amount++; if ( playlist.amount >= MAX_PLAYLIST_SIZE ) { - if(!playlist.in_ram) close(fd); lcd_clear_display(); @@ -365,8 +434,7 @@ store_index = 0; /* Update the screen if it takes very long */ - if(!playlist.in_ram) { - if ( current_tick >= next_tick ) { + if ( show_prog && current_tick >= next_tick ) { next_tick = current_tick + HZ; snprintf(line, sizeof line, "%d files", playlist.amount); @@ -376,20 +444,19 @@ } } } - } i+= count; - if(playlist.in_ram) - break; } - if(!playlist.in_ram) { + snprintf(line, sizeof line, "%d files", playlist.amount); + if ( show_prog ) { lcd_puts(0,1,line); status_draw(); lcd_update(); - close(fd); } + + close(fd); } /* Index: playlist.h =================================================================== RCS file: /cvsroot/rockbox/apps/playlist.h,v retrieving revision 1.16 diff -u -b -r1.16 playlist.h --- playlist.h 28 Aug 2002 09:22:44 -0000 1.16 +++ playlist.h 29 Aug 2002 23:30:46 -0000 @@ -26,29 +26,36 @@ /* playlist data */ -struct playlist_info +struct playlist_file { char filename[MAX_PATH]; /* path name of m3u playlist on disk */ + /* directory if in-RAM list */ int dirlen; /* Length of the path to the playlist file */ + bool in_ram; /* True if the playlist is RAM-based */ +}; + +struct playlist_info +{ int indices[MAX_PLAYLIST_SIZE]; /* array of indices */ + struct playlist_file *pl_files[MAX_PLAYLIST_FILES]; int index; /* index of *NEXT* track to play */ int seed; /* random seed */ int amount; /* number of tracks in the index */ - bool in_ram; /* True if the playlist is RAM-based */ }; extern struct playlist_info playlist; extern bool playlist_shuffle; -int play_list(char *dir, char *file, int start_index, - bool shuffled_index, int start_offset, int random_seed ); +int play_list(int start_index, bool shuffled_index, + int start_offset, int random_seed); char* playlist_peek(int steps); int playlist_next(int steps); void randomise_playlist( unsigned int seed ); void sort_playlist(bool start_current); -void empty_playlist(void); -void add_indices_to_playlist(void); +int playlist_newdir(char *dir); +void add_indices_to_playlist(int pl_file_indx, bool show_prog); void playlist_clear(void); -int playlist_add(char *filename); +int playlist_add_file(char *filename, int pl_dir); +void load_playlist(char *dir, char *file, bool show_prog); #endif /* __PLAYLIST_H__ */ Index: tree.c =================================================================== RCS file: /cvsroot/rockbox/apps/tree.c,v retrieving revision 1.104 diff -u -b -r1.104 tree.c --- tree.c 28 Aug 2002 14:03:55 -0000 1.104 +++ tree.c 29 Aug 2002 23:30:47 -0000 @@ -41,6 +41,7 @@ #include "debug.h" #include "ata.h" + #ifdef HAVE_LCD_BITMAP #include "icons.h" #endif @@ -116,27 +117,32 @@ #define TREE_ATTR_M3U 0x80 /* unused by FAT attributes */ #define TREE_ATTR_MPA 0x40 /* unused by FAT attributes */ -static int build_playlist(int start_index) +static int build_playlist(char* dir, int start_index) { int i; int start=start_index; + int pl_file_idx; playlist_clear(); + pl_file_idx = playlist_newdir(dir); + + if (pl_file_idx >= 0) { /* successfully created new directory entry*/ for(i = 0;i < filesindir;i++) { if(dircache[i].attr & TREE_ATTR_MPA) { DEBUGF("Adding %s\n", dircache[i].name); - playlist_add(dircache[i].name); + playlist_add_file(dircache[i].name, pl_file_idx); } else { - /* Adjust the start index when se skip non-MP3 entries */ + /* Adjust the start index when we skip non-MP3 entries */ if(i < start) start_index--; } } + } return start_index; } @@ -365,9 +371,10 @@ slash = strrchr(global_settings.resume_file,'/'); if (slash) { *slash=0; - play_list(global_settings.resume_file, - slash+1, - global_settings.resume_index, + playlist_clear(); + load_playlist(global_settings.resume_file, + slash+1, true); + play_list(global_settings.resume_index, true, /* the index is AFTER shuffle */ global_settings.resume_offset, global_settings.resume_seed ); @@ -383,9 +390,9 @@ if (!ask_resume()) return; - play_list("/", - global_settings.resume_file, - global_settings.resume_index, + playlist_clear(); + load_playlist("/", global_settings.resume_file, true); + play_list(global_settings.resume_index, true, global_settings.resume_offset, global_settings.resume_seed ); @@ -397,10 +404,9 @@ if (showdir(global_settings.resume_file, 0) < 0 ) return; - build_playlist(global_settings.resume_index); - play_list(global_settings.resume_file, - NULL, - global_settings.resume_index, + build_playlist(global_settings.resume_file, + global_settings.resume_index); + play_list(global_settings.resume_index, true, global_settings.resume_offset, global_settings.resume_seed); @@ -524,10 +530,11 @@ MAX_PATH, "%s/%s", currdir, dircache[dircursor+start].name); - play_list(currdir, + playlist_clear(); + load_playlist(currdir, dircache[dircursor+start].name, - 0, - false, + true); + play_list(0, false, 0, seed ); start_index = 0; } @@ -535,12 +542,12 @@ if ( global_settings.resume ) strncpy(global_settings.resume_file, currdir, MAX_PATH); - start_index = build_playlist(dircursor+start); + start_index = build_playlist(currdir, + dircursor+start); /* it is important that we get back the index in - the (shuffled) list and stor that */ - start_index = play_list(currdir, NULL, - start_index, false, 0, seed); + the (shuffled) list and store that */ + start_index = play_list(start_index, false, 0, seed); } else break;