summaryrefslogtreecommitdiff
path: root/apps/playlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/playlist.c')
-rw-r--r--apps/playlist.c340
1 files changed, 286 insertions, 54 deletions
diff --git a/apps/playlist.c b/apps/playlist.c
index 38eca09fc9..0a99cb91f4 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -21,7 +21,7 @@
21#include <stdlib.h> 21#include <stdlib.h>
22#include <string.h> 22#include <string.h>
23#include "playlist.h" 23#include "playlist.h"
24#include <file.h> 24#include "file.h"
25#include "sprintf.h" 25#include "sprintf.h"
26#include "debug.h" 26#include "debug.h"
27#include "mpeg.h" 27#include "mpeg.h"
@@ -39,6 +39,7 @@
39 39
40static struct playlist_info playlist; 40static struct playlist_info playlist;
41 41
42#define QUEUE_FILE ROCKBOX_DIR "/.queue_file"
42#define PLAYLIST_BUFFER_SIZE (AVERAGE_FILENAME_LENGTH*MAX_FILES_IN_DIR) 43#define PLAYLIST_BUFFER_SIZE (AVERAGE_FILENAME_LENGTH*MAX_FILES_IN_DIR)
43 44
44static unsigned char playlist_buffer[PLAYLIST_BUFFER_SIZE]; 45static unsigned char playlist_buffer[PLAYLIST_BUFFER_SIZE];
@@ -46,64 +47,153 @@ static int playlist_end_pos = 0;
46 47
47static char now_playing[MAX_PATH+1]; 48static char now_playing[MAX_PATH+1];
48 49
49void playlist_clear(void) 50/*
51 * remove any files and indices associated with the playlist
52 */
53static void empty_playlist(bool queue_resume)
50{ 54{
51 playlist_end_pos = 0; 55 int fd;
52 playlist_buffer[0] = 0; 56
57 playlist.filename[0] = '\0';
58 playlist.index = 0;
59 playlist.queue_index = 0;
60 playlist.last_queue_index = 0;
61 playlist.amount = 0;
62 playlist.num_queued = 0;
63 playlist.start_queue = 0;
64
65 if (!queue_resume)
66 {
67 /* start with fresh queue file when starting new playlist */
68 remove(QUEUE_FILE);
69 fd = creat(QUEUE_FILE, 0);
70 if (fd > 0)
71 close(fd);
72 }
53} 73}
54 74
55int playlist_add(char *filename) 75/* update queue list after resume */
76static void add_indices_to_queuelist(int seek)
56{ 77{
57 int len = strlen(filename); 78 int nread;
79 int fd = -1;
80 int i = seek;
81 int count = 0;
82 bool store_index;
83 char buf[MAX_PATH];
58 84
59 if(len+2 > PLAYLIST_BUFFER_SIZE - playlist_end_pos) 85 unsigned char *p = buf;
60 return -1;
61 86
62 strcpy(&playlist_buffer[playlist_end_pos], filename); 87 fd = open(QUEUE_FILE, O_RDONLY);
63 playlist_end_pos += len; 88 if(fd < 0)
64 playlist_buffer[playlist_end_pos++] = '\n'; 89 return;
65 playlist_buffer[playlist_end_pos] = '\0'; 90
66 return 0; 91 nread = lseek(fd, seek, SEEK_SET);
92 if (nread < 0)
93 return;
94
95 store_index = true;
96
97 while(1)
98 {
99 nread = read(fd, buf, MAX_PATH);
100 if(nread <= 0)
101 break;
102
103 p = buf;
104
105 for(count=0; count < nread; count++,p++) {
106 if(*p == '\n')
107 store_index = true;
108 else if(store_index)
109 {
110 store_index = false;
111
112 playlist.queue_indices[playlist.last_queue_index] = i+count;
113 playlist.last_queue_index =
114 (playlist.last_queue_index + 1) % MAX_QUEUED_FILES;
115 playlist.num_queued++;
116 }
117 }
118
119 i += count;
120 }
67} 121}
68 122
69static int get_next_index(int steps) 123static int get_next_index(int steps, bool *queue)
70{ 124{
71 int current_index = playlist.index; 125 int current_index = playlist.index;
72 int next_index = -1; 126 int next_index = -1;
73 127
128 if (global_settings.repeat_mode == REPEAT_ONE)
129 steps = 0;
130 else if (steps >= 0)
131 steps -= playlist.start_queue;
132
133 if (steps >= 0 && playlist.num_queued > 0 &&
134 playlist.num_queued - steps > 0)
135 *queue = true;
136 else
137 {
138 *queue = false;
139 if (playlist.num_queued)
140 {
141 if (steps >= 0)
142 steps -= (playlist.num_queued - 1);
143 else if (!playlist.start_queue)
144 steps += 1;
145 }
146 }
147
74 switch (global_settings.repeat_mode) 148 switch (global_settings.repeat_mode)
75 { 149 {
76 case REPEAT_OFF: 150 case REPEAT_OFF:
77 if (current_index < playlist.first_index) 151 if (*queue)
78 current_index += playlist.amount; 152 next_index = (playlist.queue_index+steps) % MAX_QUEUED_FILES;
79 current_index -= playlist.first_index;
80
81 next_index = current_index+steps;
82 if ((next_index < 0) || (next_index >= playlist.amount))
83 next_index = -1;
84 else 153 else
85 next_index = (next_index+playlist.first_index)%playlist.amount; 154 {
155 if (current_index < playlist.first_index)
156 current_index += playlist.amount;
157 current_index -= playlist.first_index;
158
159 next_index = current_index+steps;
160 if ((next_index < 0) || (next_index >= playlist.amount))
161 next_index = -1;
162 else
163 next_index = (next_index+playlist.first_index) %
164 playlist.amount;
165 }
86 break; 166 break;
87 167
88 case REPEAT_ONE: 168 case REPEAT_ONE:
89 next_index = current_index; 169 if (*queue && !playlist.start_queue)
170 next_index = playlist.queue_index;
171 else
172 {
173 next_index = current_index;
174 *queue = false;
175 }
90 break; 176 break;
91 177
92 case REPEAT_ALL: 178 case REPEAT_ALL:
93 default: 179 default:
94 next_index = (current_index+steps) % playlist.amount; 180 if (*queue)
95 while (next_index < 0) 181 next_index = (playlist.queue_index+steps) % MAX_QUEUED_FILES;
96 next_index += playlist.amount; 182 else
183 {
184 next_index = (current_index+steps) % playlist.amount;
185 while (next_index < 0)
186 next_index += playlist.amount;
187 }
97 break; 188 break;
98 } 189 }
99 190
100 return next_index; 191 return next_index;
101} 192}
102 193
103/* the mpeg thread might ask us */
104int playlist_amount(void) 194int playlist_amount(void)
105{ 195{
106 return playlist.amount; 196 return playlist.amount + playlist.num_queued;
107} 197}
108 198
109int playlist_first_index(void) 199int playlist_first_index(void)
@@ -111,6 +201,36 @@ int playlist_first_index(void)
111 return playlist.first_index; 201 return playlist.first_index;
112} 202}
113 203
204int playlist_get_resume_info(int *resume_index, int *queue_resume,
205 int *queue_resume_index)
206{
207 int result = 0;
208
209 *resume_index = playlist.index;
210
211 if (playlist.num_queued > 0)
212 {
213 if (global_settings.save_queue_resume)
214 {
215 *queue_resume_index =
216 playlist.queue_indices[playlist.queue_index];
217 if (playlist.start_queue)
218 *queue_resume = QUEUE_BEGIN_PLAYLIST;
219 else
220 *queue_resume = QUEUE_BEGIN_QUEUE;
221 }
222 else if (!playlist.start_queue)
223 {
224 *queue_resume = QUEUE_OFF;
225 result = -1;
226 }
227 }
228 else
229 *queue_resume = QUEUE_OFF;
230
231 return result;
232}
233
114char *playlist_name(char *buf, int buf_size) 234char *playlist_name(char *buf, int buf_size)
115{ 235{
116 char *sep; 236 char *sep;
@@ -128,11 +248,101 @@ char *playlist_name(char *buf, int buf_size)
128 return buf; 248 return buf;
129} 249}
130 250
251void playlist_clear(void)
252{
253 playlist_end_pos = 0;
254 playlist_buffer[0] = 0;
255}
256
257int playlist_add(char *filename)
258{
259 int len = strlen(filename);
260
261 if(len+2 > PLAYLIST_BUFFER_SIZE - playlist_end_pos)
262 return -1;
263
264 strcpy(&playlist_buffer[playlist_end_pos], filename);
265 playlist_end_pos += len;
266 playlist_buffer[playlist_end_pos++] = '\n';
267 playlist_buffer[playlist_end_pos] = '\0';
268 return 0;
269}
270
271/* Add track to queue file */
272int queue_add(char *filename)
273{
274 int fd, seek, result;
275 int len = strlen(filename);
276
277 if(playlist.num_queued >= MAX_QUEUED_FILES)
278 return -1;
279
280 fd = open(QUEUE_FILE, O_WRONLY);
281 if (fd < 0)
282 return -1;
283
284 seek = lseek(fd, 0, SEEK_END);
285 if (seek < 0)
286 {
287 close(fd);
288 return -1;
289 }
290
291 filename[len] = '\n';
292 result = write(fd, filename, len+1);
293 if (result < 0)
294 {
295 close(fd);
296 return -1;
297 }
298 filename[len] = '\0';
299
300 close(fd);
301
302 if (playlist.num_queued <= 0)
303 playlist.start_queue = 1;
304
305 playlist.queue_indices[playlist.last_queue_index] = seek;
306 playlist.last_queue_index =
307 (playlist.last_queue_index + 1) % MAX_QUEUED_FILES;
308 playlist.num_queued++;
309
310 mpeg_flush_and_reload_tracks();
311
312 return playlist.num_queued;
313}
314
131int playlist_next(int steps) 315int playlist_next(int steps)
132{ 316{
133 playlist.index = get_next_index(steps); 317 bool queue;
318 int index = get_next_index(steps, &queue);
134 319
135 return playlist.index; 320 if (queue)
321 {
322 int queue_diff = index - playlist.queue_index;
323 if (queue_diff < 0)
324 queue_diff += MAX_QUEUED_FILES;
325
326 playlist.num_queued -= queue_diff;
327 playlist.queue_index = index;
328 playlist.start_queue = 0;
329 }
330 else
331 {
332 playlist.index = index;
333 if (playlist.num_queued > 0 && !playlist.start_queue)
334 {
335 if (steps >= 0)
336 {
337 playlist.queue_index = playlist.last_queue_index;
338 playlist.num_queued = 0;
339 }
340 else
341 playlist.start_queue = true;
342 }
343 }
344
345 return index;
136} 346}
137 347
138char* playlist_peek(int steps) 348char* playlist_peek(int steps)
@@ -145,24 +355,19 @@ char* playlist_peek(int steps)
145 char dir_buf[MAX_PATH+1]; 355 char dir_buf[MAX_PATH+1];
146 char *dir_end; 356 char *dir_end;
147 int index; 357 int index;
358 bool queue;
148 359
149 index = get_next_index(steps); 360 index = get_next_index(steps, &queue);
150 if (index >= 0) 361 if (index < 0)
151 seek = playlist.indices[index];
152 else
153 return NULL; 362 return NULL;
154 363
155 if(playlist.in_ram) 364 if (queue)
156 { 365 {
157 buf = playlist_buffer + seek; 366 seek = playlist.queue_indices[index];
158 max = playlist_end_pos - seek; 367 fd = open(QUEUE_FILE, O_RDONLY);
159 }
160 else
161 {
162 fd = open(playlist.filename, O_RDONLY);
163 if(-1 != fd) 368 if(-1 != fd)
164 { 369 {
165 buf = playlist_buffer; 370 buf = dir_buf;
166 lseek(fd, seek, SEEK_SET); 371 lseek(fd, seek, SEEK_SET);
167 max = read(fd, buf, MAX_PATH); 372 max = read(fd, buf, MAX_PATH);
168 close(fd); 373 close(fd);
@@ -170,6 +375,29 @@ char* playlist_peek(int steps)
170 else 375 else
171 return NULL; 376 return NULL;
172 } 377 }
378 else
379 {
380 seek = playlist.indices[index];
381
382 if(playlist.in_ram)
383 {
384 buf = playlist_buffer + seek;
385 max = playlist_end_pos - seek;
386 }
387 else
388 {
389 fd = open(playlist.filename, O_RDONLY);
390 if(-1 != fd)
391 {
392 buf = playlist_buffer;
393 lseek(fd, seek, SEEK_SET);
394 max = read(fd, buf, MAX_PATH);
395 close(fd);
396 }
397 else
398 return NULL;
399 }
400 }
173 401
174 /* Zero-terminate the file name */ 402 /* Zero-terminate the file name */
175 seek=0; 403 seek=0;
@@ -260,11 +488,13 @@ int play_list(char *dir, /* "current directory" */
260 playlist AFTER the shuffle */ 488 playlist AFTER the shuffle */
261 int start_offset, /* offset in the file */ 489 int start_offset, /* offset in the file */
262 int random_seed, /* used for shuffling */ 490 int random_seed, /* used for shuffling */
263 int first_index ) /* first index of playlist */ 491 int first_index, /* first index of playlist */
492 int queue_resume, /* resume queue list? */
493 int queue_resume_index ) /* queue list seek pos */
264{ 494{
265 char *sep=""; 495 char *sep="";
266 int dirlen; 496 int dirlen;
267 empty_playlist(); 497 empty_playlist(queue_resume);
268 498
269 playlist.index = start_index; 499 playlist.index = start_index;
270 playlist.first_index = first_index; 500 playlist.first_index = first_index;
@@ -343,6 +573,18 @@ int play_list(char *dir, /* "current directory" */
343 } 573 }
344 } 574 }
345 575
576 /* update the queue indices */
577 if (queue_resume)
578 {
579 add_indices_to_queuelist(queue_resume_index);
580
581 if (queue_resume == QUEUE_BEGIN_PLAYLIST)
582 {
583 playlist.start_queue = 1;
584 playlist.index++; /* so we begin at the correct track */
585 }
586 }
587
346 if(!playlist.in_ram) { 588 if(!playlist.in_ram) {
347 lcd_puts(0,0,str(LANG_PLAYLIST_PLAY)); 589 lcd_puts(0,0,str(LANG_PLAYLIST_PLAY));
348 status_draw(); 590 status_draw();
@@ -355,16 +597,6 @@ int play_list(char *dir, /* "current directory" */
355} 597}
356 598
357/* 599/*
358 * remove any filename and indices associated with the playlist
359 */
360void empty_playlist(void)
361{
362 playlist.filename[0] = '\0';
363 playlist.index = 0;
364 playlist.amount = 0;
365}
366
367/*
368 * calculate track offsets within a playlist file 600 * calculate track offsets within a playlist file
369 */ 601 */
370void add_indices_to_playlist(void) 602void add_indices_to_playlist(void)