summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2002-08-06 13:09:48 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2002-08-06 13:09:48 +0000
commitd8cc2850342ef7c6386c4347b7fb55d204847f91 (patch)
tree616d0f63db553d194cf01b0d64dc3d28b954e446 /apps
parentaba19c95b7723babef2a39ce9364cad60f09be3e (diff)
downloadrockbox-d8cc2850342ef7c6386c4347b7fb55d204847f91.tar.gz
rockbox-d8cc2850342ef7c6386c4347b7fb55d204847f91.zip
RAM-based playlists added
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1559 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/playlist.c300
-rw-r--r--apps/playlist.h16
2 files changed, 198 insertions, 118 deletions
diff --git a/apps/playlist.c b/apps/playlist.c
index fdd88a17bc..465470c069 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -33,157 +33,224 @@
33 33
34playlist_info_t playlist; 34playlist_info_t playlist;
35 35
36#define PLAYLIST_BUFFER_SIZE (MAX_PATH*200)
37
38unsigned char playlist_buffer[PLAYLIST_BUFFER_SIZE];
39static int playlist_end_pos = 0;
40
36char now_playing[MAX_PATH+1]; 41char now_playing[MAX_PATH+1];
37 42
38char* playlist_next(int steps, char *dirname) 43void playlist_clear(void)
44{
45 playlist_end_pos = 0;
46 playlist_buffer[0] = 0;
47}
48
49int playlist_add(char *filename)
50{
51 int len = strlen(filename);
52
53 if(len+2 > PLAYLIST_BUFFER_SIZE - playlist_end_pos)
54 return -1;
55
56 strcpy(&playlist_buffer[playlist_end_pos], filename);
57 playlist_end_pos += len;
58 playlist_buffer[playlist_end_pos++] = '\n';
59 playlist_buffer[playlist_end_pos] = '\0';
60 return 0;
61}
62
63char* playlist_next(int steps)
39{ 64{
40 int seek; 65 int seek;
41 int max; 66 int max;
42 int fd; 67 int fd;
43 int i; 68 int i;
44 char buf[MAX_PATH+1]; 69 char *buf;
45 char dir_buf[MAX_PATH+1]; 70 char dir_buf[MAX_PATH+1];
46 char *dir_end; 71 char *dir_end;
47 72
48 playlist.index = (playlist.index+steps) % playlist.amount; 73 playlist.index = (playlist.index+steps) % playlist.amount;
49 seek = playlist.indices[playlist.index]; 74 seek = playlist.indices[playlist.index];
50 75
51 fd = open(playlist.filename, O_RDONLY); 76 if(playlist.in_ram)
52 if(-1 != fd) { 77 {
53 lseek(fd, seek, SEEK_SET); 78 buf = playlist_buffer + seek;
54 max = read(fd, buf, sizeof(buf)-1); 79 max = playlist_end_pos - seek;
55 close(fd); 80 }
56 81 else
57 /* Zero-terminate the file name */ 82 {
58 seek=0; 83 fd = open(playlist.filename, O_RDONLY);
59 while((buf[seek] != '\n') && 84 if(-1 != fd)
60 (buf[seek] != '\r') && 85 {
61 (seek < max)) 86 buf = playlist_buffer;
87 lseek(fd, seek, SEEK_SET);
88 max = read(fd, buf, MAX_PATH);
89 close(fd);
90 }
91 else
92 return NULL;
93 }
94
95
96 /* Zero-terminate the file name */
97 seek=0;
98 while((buf[seek] != '\n') &&
99 (buf[seek] != '\r') &&
100 (seek < max))
62 seek++; 101 seek++;
63 102
64 /* Now work back killing white space */ 103 /* Now work back killing white space */
65 while((buf[seek-1] == ' ') || 104 while((buf[seek-1] == ' ') ||
66 (buf[seek-1] == '\t')) 105 (buf[seek-1] == '\t'))
67 seek--; 106 seek--;
68 107
69 buf[seek]=0; 108 buf[seek]=0;
70 109
71 /* replace backslashes with forward slashes */ 110 /* replace backslashes with forward slashes */
72 for ( i=0; i<seek; i++ ) 111 for ( i=0; i<seek; i++ )
73 if ( buf[i] == '\\' ) 112 if ( buf[i] == '\\' )
74 buf[i] = '/'; 113 buf[i] = '/';
75 114
76 if('/' == buf[0]) { 115 if('/' == buf[0]) {
77 strcpy(now_playing, &buf[0]); 116 strcpy(now_playing, &buf[0]);
78 return now_playing; 117 return now_playing;
79 } 118 }
80 else { 119 else {
81 /* handle dos style drive letter */ 120 strncpy(dir_buf, playlist.filename, playlist.dirlen);
82 if ( ':' == buf[1] ) { 121 dir_buf[playlist.dirlen] = 0;
83 strcpy(now_playing, &buf[2]); 122
84 return now_playing; 123 /* handle dos style drive letter */
85 } 124 if ( ':' == buf[1] ) {
86 else if ( '.' == buf[0] && '.' == buf[1] && '/' == buf[2] ) { 125 strcpy(now_playing, &buf[2]);
87 /* handle relative paths */ 126 return now_playing;
88 seek=3; 127 }
89 while(buf[seek] == '.' && 128 else if ( '.' == buf[0] && '.' == buf[1] && '/' == buf[2] ) {
90 buf[seek+1] == '.' && 129 /* handle relative paths */
91 buf[seek+2] == '/') 130 seek=3;
92 seek += 3; 131 while(buf[seek] == '.' &&
93 strcpy(dir_buf, dirname); 132 buf[seek+1] == '.' &&
94 for (i=0; i<seek/3; i++) { 133 buf[seek+2] == '/')
95 dir_end = strrchr(dir_buf, '/'); 134 seek += 3;
96 if (dir_end) 135 for (i=0; i<seek/3; i++) {
97 *dir_end = '\0'; 136 dir_end = strrchr(dir_buf, '/');
98 else 137 if (dir_end)
99 break; 138 *dir_end = '\0';
100 } 139 else
101 snprintf(now_playing, MAX_PATH+1, "%s/%s", dir_buf, &buf[seek]); 140 break;
102 return now_playing; 141 }
103 } 142 snprintf(now_playing, MAX_PATH+1, "%s/%s", dir_buf, &buf[seek]);
104 else if ( '.' == buf[0] && '/' == buf[1] ) { 143 return now_playing;
105 snprintf(now_playing, MAX_PATH+1, "%s/%s", dirname, &buf[2]); 144 }
106 return now_playing; 145 else if ( '.' == buf[0] && '/' == buf[1] ) {
107 } 146 snprintf(now_playing, MAX_PATH+1, "%s/%s", dir_buf, &buf[2]);
108 else { 147 return now_playing;
109 snprintf(now_playing, MAX_PATH+1, "%s/%s", dirname, buf); 148 }
110 return now_playing; 149 else {
111 } 150 snprintf(now_playing, MAX_PATH+1, "%s/%s", dir_buf, buf);
112 } 151 return now_playing;
152 }
113 } 153 }
114 else
115 return NULL;
116} 154}
117 155
118void play_list(char *dir, char *file) 156void play_list(char *dir, char *file)
119{ 157{
120 char *sep=""; 158 char *sep="";
159 int dirlen;
121 160
122 lcd_clear_display(); 161 empty_playlist();
123 lcd_puts(0,0,"Loading..."); 162
124 lcd_update(); 163 /* If file is NULL, the list is in RAM */
125 empty_playlist(&playlist); 164 if(file) {
165 lcd_clear_display();
166 lcd_puts(0,0,"Loading...");
167 lcd_update();
168 playlist.in_ram = false;
169 } else {
170 /* Assign a dummy filename */
171 file = "";
172 playlist.in_ram = true;
173 }
126 174
127 /* If the dir does not end in trailing new line, we use a separator. 175 dirlen = strlen(dir);
176
177 /* If the dir does not end in trailing slash, we use a separator.
128 Otherwise we don't. */ 178 Otherwise we don't. */
129 if('/' != dir[strlen(dir)-1]) 179 if('/' != dir[dirlen-1]) {
130 sep="/"; 180 sep="/";
181 dirlen++;
182 }
183
184 playlist.dirlen = dirlen;
131 185
132 snprintf(playlist.filename, sizeof(playlist.filename), 186 snprintf(playlist.filename, sizeof(playlist.filename),
133 "%s%s%s", 187 "%s%s%s",
134 dir, sep, file); 188 dir, sep, file);
135 189
136 /* add track indices to playlist data structure */ 190 /* add track indices to playlist data structure */
137 add_indices_to_playlist(&playlist); 191 add_indices_to_playlist();
138 192
139 if(global_settings.playlist_shuffle) { 193 if(global_settings.playlist_shuffle) {
140 lcd_puts(0,0,"Shuffling..."); 194 if(!playlist.in_ram) {
141 lcd_update(); 195 lcd_puts(0,0,"Shuffling...");
142 randomise_playlist( &playlist, current_tick ); 196 lcd_update();
197 }
198 randomise_playlist( current_tick );
143 } 199 }
144 200
145 lcd_puts(0,0,"Playing... "); 201 if(!playlist.in_ram) {
146 lcd_update(); 202 lcd_puts(0,0,"Playing... ");
203 lcd_update();
204 }
147 /* also make the first song get playing */ 205 /* also make the first song get playing */
148 mpeg_play(playlist_next(0, dir)); 206 mpeg_play(playlist_next(0));
149 sleep(HZ);
150} 207}
151 208
152/* 209/*
153 * remove any filename and indices associated with the playlist 210 * remove any filename and indices associated with the playlist
154 */ 211 */
155void empty_playlist( playlist_info_t *playlist ) 212void empty_playlist(void)
156{ 213{
157 playlist->filename[0] = '\0'; 214 playlist.filename[0] = '\0';
158 playlist->index = 0; 215 playlist.index = 0;
159 playlist->amount = 0; 216 playlist.amount = 0;
160} 217}
161 218
162/* 219/*
163 * calculate track offsets within a playlist file 220 * calculate track offsets within a playlist file
164 */ 221 */
165void add_indices_to_playlist( playlist_info_t *playlist ) 222void add_indices_to_playlist(void)
166{ 223{
167 int nread; 224 int nread;
168 int fd; 225 int fd = -1;
169 int i = 0; 226 int i = 0;
170 int store_index = 0; 227 int store_index = 0;
171 int count = 0; 228 int count = 0;
172 int next_tick = current_tick + HZ; 229 int next_tick = current_tick + HZ;
173 230
174 unsigned char *p; 231 unsigned char *p = playlist_buffer;
175 unsigned char buf[512];
176 char line[16]; 232 char line[16];
177 233
178 fd = open(playlist->filename, O_RDONLY); 234 if(!playlist.in_ram) {
179 if(-1 == fd) 235 fd = open(playlist.filename, O_RDONLY);
180 return; /* failure */ 236 if(-1 == fd)
237 return; /* failure */
238 }
181 239
182 store_index = 1; 240 store_index = 1;
183 241
184 while((nread = read(fd, &buf, sizeof(buf))) != 0) 242 while(1)
185 { 243 {
186 p = buf; 244 if(playlist.in_ram) {
245 nread = playlist_end_pos;
246 } else {
247 nread = read(fd, playlist_buffer, PLAYLIST_BUFFER_SIZE);
248 /* Terminate on EOF */
249 if(nread <= 0)
250 break;
251 }
252
253 p = playlist_buffer;
187 254
188 for(count=0; count < nread; count++,p++) { 255 for(count=0; count < nread; count++,p++) {
189 256
@@ -203,36 +270,45 @@ void add_indices_to_playlist( playlist_info_t *playlist )
203 { 270 {
204 271
205 /* Store a new entry */ 272 /* Store a new entry */
206 playlist->indices[ playlist->amount ] = i+count; 273 playlist.indices[ playlist.amount ] = i+count;
207 playlist->amount++; 274 playlist.amount++;
208 if ( playlist->amount >= MAX_PLAYLIST_SIZE ) { 275 if ( playlist.amount >= MAX_PLAYLIST_SIZE ) {
209 close(fd); 276 if(!playlist.in_ram)
277 close(fd);
210 return; 278 return;
211 } 279 }
212 280
213 store_index = 0; 281 store_index = 0;
214 if ( current_tick >= next_tick ) { 282 /* Update the screen if it takes very long */
215 next_tick = current_tick + HZ; 283 if(!playlist.in_ram) {
216 snprintf(line, sizeof line, "%d files", playlist->amount); 284 if ( current_tick >= next_tick ) {
217 lcd_puts(0,1,line); 285 next_tick = current_tick + HZ;
218 lcd_update(); 286 snprintf(line, sizeof line, "%d files",
287 playlist.amount);
288 lcd_puts(0,1,line);
289 lcd_update();
290 }
219 } 291 }
220 } 292 }
221 } 293 }
222 294
223 i+= count; 295 i+= count;
224 }
225 snprintf(line, sizeof line, "%d files", playlist->amount);
226 lcd_puts(0,1,line);
227 lcd_update();
228 296
229 close(fd); 297 if(playlist.in_ram)
298 break;
299 }
300 if(!playlist.in_ram) {
301 snprintf(line, sizeof line, "%d files", playlist.amount);
302 lcd_puts(0,1,line);
303 lcd_update();
304 close(fd);
305 }
230} 306}
231 307
232/* 308/*
233 * randomly rearrange the array of indices for the playlist 309 * randomly rearrange the array of indices for the playlist
234 */ 310 */
235void randomise_playlist( playlist_info_t *playlist, unsigned int seed ) 311void randomise_playlist( unsigned int seed )
236{ 312{
237 int count; 313 int count;
238 int candidate; 314 int candidate;
@@ -242,15 +318,15 @@ void randomise_playlist( playlist_info_t *playlist, unsigned int seed )
242 srand( seed ); 318 srand( seed );
243 319
244 /* randomise entire indices list */ 320 /* randomise entire indices list */
245 for(count = playlist->amount - 1; count >= 0; count--) 321 for(count = playlist.amount - 1; count >= 0; count--)
246 { 322 {
247 /* the rand is from 0 to RAND_MAX, so adjust to our value range */ 323 /* the rand is from 0 to RAND_MAX, so adjust to our value range */
248 candidate = rand() % (count + 1); 324 candidate = rand() % (count + 1);
249 325
250 /* now swap the values at the 'count' and 'candidate' positions */ 326 /* now swap the values at the 'count' and 'candidate' positions */
251 store = playlist->indices[candidate]; 327 store = playlist.indices[candidate];
252 playlist->indices[candidate] = playlist->indices[count]; 328 playlist.indices[candidate] = playlist.indices[count];
253 playlist->indices[count] = store; 329 playlist.indices[count] = store;
254 } 330 }
255} 331}
256 332
@@ -265,11 +341,11 @@ static int compare(const void* p1, const void* p2)
265/* 341/*
266 * sort the array of indices for the playlist 342 * sort the array of indices for the playlist
267 */ 343 */
268void sort_playlist( playlist_info_t *playlist ) 344void sort_playlist(void)
269{ 345{
270 if (playlist->amount > 0) 346 if (playlist.amount > 0)
271 { 347 {
272 qsort(&playlist->indices, playlist->amount, sizeof(playlist->indices[0]), compare); 348 qsort(&playlist.indices, playlist.amount, sizeof(playlist.indices[0]), compare);
273 } 349 }
274} 350}
275 351
diff --git a/apps/playlist.h b/apps/playlist.h
index 3d37c5da5f..a218209857 100644
--- a/apps/playlist.h
+++ b/apps/playlist.h
@@ -29,20 +29,24 @@
29typedef struct 29typedef struct
30{ 30{
31 char filename[MAX_PATH]; /* path name of m3u playlist on disk */ 31 char filename[MAX_PATH]; /* path name of m3u playlist on disk */
32 int dirlen; /* Length of the path to the playlist file */
32 int indices[MAX_PLAYLIST_SIZE]; /* array of indices */ 33 int indices[MAX_PLAYLIST_SIZE]; /* array of indices */
33 int index; /* index of *NEXT* track to play */ 34 int index; /* index of *NEXT* track to play */
34 int seed; /* random seed */ 35 int seed; /* random seed */
35 int amount; /* number of tracks in the index */ 36 int amount; /* number of tracks in the index */
37 bool in_ram; /* True if the playlist is RAM-based */
36} playlist_info_t; 38} playlist_info_t;
37 39
38extern playlist_info_t playlist; 40//extern playlist_info_t playlist;
39extern bool playlist_shuffle; 41extern bool playlist_shuffle;
40 42
41void play_list(char *dir, char *file); 43void play_list(char *dir, char *file);
42char* playlist_next(int steps, char *dirname); 44char* playlist_next(int steps);
43void randomise_playlist( playlist_info_t *playlist, unsigned int seed ); 45void randomise_playlist( unsigned int seed );
44void sort_playlist( playlist_info_t *playlist ); 46void sort_playlist(void);
45void empty_playlist( playlist_info_t *playlist ); 47void empty_playlist(void);
46void add_indices_to_playlist( playlist_info_t *playlist ); 48void add_indices_to_playlist(void);
49void playlist_clear(void);
50int playlist_add(char *filename);
47 51
48#endif /* __PLAYLIST_H__ */ 52#endif /* __PLAYLIST_H__ */