summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/cuesheet.c104
-rw-r--r--apps/cuesheet.h2
2 files changed, 80 insertions, 26 deletions
diff --git a/apps/cuesheet.c b/apps/cuesheet.c
index 73dd19fdab..52b8c5703b 100644
--- a/apps/cuesheet.c
+++ b/apps/cuesheet.c
@@ -42,30 +42,20 @@
42 42
43#define CUE_DIR ROCKBOX_DIR "/cue" 43#define CUE_DIR ROCKBOX_DIR "/cue"
44 44
45bool look_for_cuesheet_file(struct mp3entry *track_id3, struct cuesheet_file *cue_file) 45static bool search_for_cuesheet(const char *path, struct cuesheet_file *cue_file)
46{ 46{
47 /* DEBUGF("look for cue file\n"); */
48 size_t len; 47 size_t len;
49 char cuepath[MAX_PATH]; 48 char cuepath[MAX_PATH];
50 char *dot, *slash, *slash_cuepath; 49 char *dot, *slash, *slash_cuepath;
51 50
52 if (track_id3->has_embedded_cuesheet)
53 {
54 cue_file->pos = track_id3->embedded_cuesheet.pos;
55 cue_file->size = track_id3->embedded_cuesheet.size;
56 cue_file->encoding = track_id3->embedded_cuesheet.encoding;
57 strlcpy(cue_file->path, track_id3->path, MAX_PATH);
58 return true;
59 }
60
61 cue_file->pos = 0; 51 cue_file->pos = 0;
62 cue_file->size = 0; 52 cue_file->size = 0;
63 cue_file->path[0] = '\0'; 53 cue_file->path[0] = '\0';
64 slash = strrchr(track_id3->path, '/'); 54 slash = strrchr(path, '/');
65 if (!slash) 55 if (!slash)
66 return false; 56 return false;
67 len = strlcpy(cuepath, track_id3->path, MAX_PATH); 57 len = strlcpy(cuepath, path, MAX_PATH);
68 slash_cuepath = &cuepath[slash - track_id3->path]; 58 slash_cuepath = &cuepath[slash - path];
69 dot = strrchr(slash_cuepath, '.'); 59 dot = strrchr(slash_cuepath, '.');
70 if (dot) 60 if (dot)
71 strlcpy(dot, ".cue", MAX_PATH - (dot-cuepath)); 61 strlcpy(dot, ".cue", MAX_PATH - (dot-cuepath));
@@ -82,7 +72,7 @@ bool look_for_cuesheet_file(struct mp3entry *track_id3, struct cuesheet_file *cu
82skip: 72skip:
83 if ((len+4) >= MAX_PATH) 73 if ((len+4) >= MAX_PATH)
84 return false; 74 return false;
85 strlcpy(cuepath, track_id3->path, MAX_PATH); 75 strlcpy(cuepath, path, MAX_PATH);
86 strlcat(cuepath, ".cue", MAX_PATH); 76 strlcat(cuepath, ".cue", MAX_PATH);
87 if (!file_exists(cuepath)) 77 if (!file_exists(cuepath))
88 return false; 78 return false;
@@ -93,6 +83,21 @@ skip:
93 return true; 83 return true;
94} 84}
95 85
86bool look_for_cuesheet_file(struct mp3entry *track_id3, struct cuesheet_file *cue_file)
87{
88 /* DEBUGF("look for cue file\n"); */
89 if (track_id3->has_embedded_cuesheet)
90 {
91 cue_file->pos = track_id3->embedded_cuesheet.pos;
92 cue_file->size = track_id3->embedded_cuesheet.size;
93 cue_file->encoding = track_id3->embedded_cuesheet.encoding;
94 strlcpy(cue_file->path, track_id3->path, MAX_PATH);
95 return true;
96 }
97
98 return search_for_cuesheet(track_id3->path, cue_file);
99}
100
96static char *get_string(const char *line) 101static char *get_string(const char *line)
97{ 102{
98 char *start, *end; 103 char *start, *end;
@@ -169,6 +174,9 @@ bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue)
169 strcpy(cue->path, cue_file->path); 174 strcpy(cue->path, cue_file->path);
170 cue->curr_track = cue->tracks; 175 cue->curr_track = cue->tracks;
171 176
177 if (is_embedded)
178 strcpy(cue->file, cue->path);
179
172 while ((line_len = read_line(fd, line, read_bytes)) > 0 180 while ((line_len = read_line(fd, line, read_bytes)) > 0
173 && cue->track_count < MAX_TRACKS ) 181 && cue->track_count < MAX_TRACKS )
174 { 182 {
@@ -208,13 +216,17 @@ bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue)
208 } 216 }
209 else if (!strncmp(s, "TITLE", 5) 217 else if (!strncmp(s, "TITLE", 5)
210 || !strncmp(s, "PERFORMER", 9) 218 || !strncmp(s, "PERFORMER", 9)
211 || !strncmp(s, "SONGWRITER", 10)) 219 || !strncmp(s, "SONGWRITER", 10)
220 || !strncmp(s, "FILE", 4))
212 { 221 {
213 char *dest = NULL; 222 char *dest = NULL;
214 char *string = get_string(s); 223 char *string = get_string(s);
215 if (!string) 224 if (!string)
216 break; 225 break;
217 226
227 size_t count = MAX_NAME*3 + 1;
228 size_t count8859 = MAX_NAME;
229
218 switch (*s) 230 switch (*s)
219 { 231 {
220 case 'T': /* TITLE */ 232 case 'T': /* TITLE */
@@ -231,6 +243,15 @@ bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue)
231 dest = (cue->track_count <= 0) ? cue->songwriter : 243 dest = (cue->track_count <= 0) ? cue->songwriter :
232 cue->tracks[cue->track_count-1].songwriter; 244 cue->tracks[cue->track_count-1].songwriter;
233 break; 245 break;
246
247 case 'F': /* FILE */
248 if (is_embedded || cue->track_count > 0)
249 break;
250
251 dest = cue->file;
252 count = MAX_PATH;
253 count8859 = MAX_PATH/3;
254 break;
234 } 255 }
235 256
236 if (dest) 257 if (dest)
@@ -238,12 +259,12 @@ bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue)
238 if (char_enc == CHAR_ENC_ISO_8859_1) 259 if (char_enc == CHAR_ENC_ISO_8859_1)
239 { 260 {
240 dest = iso_decode(string, dest, -1, 261 dest = iso_decode(string, dest, -1,
241 MIN(strlen(string), MAX_NAME)); 262 MIN(strlen(string), count8859));
242 *dest = '\0'; 263 *dest = '\0';
243 } 264 }
244 else 265 else
245 { 266 {
246 strlcpy(dest, string, MAX_NAME*3 + 1); 267 strlcpy(dest, string, count);
247 } 268 }
248 } 269 }
249 } 270 }
@@ -258,6 +279,16 @@ bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue)
258 } 279 }
259 close(fd); 280 close(fd);
260 281
282 /* If just a filename, add path information from cuesheet path */
283 if (*cue->file && !strrchr(cue->file, '/'))
284 {
285 strcpy(line, cue->file);
286 strcpy(cue->file, cue->path);
287 char *slash = strrchr(cue->file, '/');
288 if (!slash++) slash = cue->file;
289 strlcpy(slash, line, MAX_PATH - (slash - cue->file));
290 }
291
261 /* If some songs don't have performer info, we copy the cuesheet performer */ 292 /* If some songs don't have performer info, we copy the cuesheet performer */
262 int i; 293 int i;
263 for (i = 0; i < cue->track_count; i++) 294 for (i = 0; i < cue->track_count; i++)
@@ -329,7 +360,6 @@ void browse_cuesheet(struct cuesheet *cue)
329 struct gui_synclist lists; 360 struct gui_synclist lists;
330 int action; 361 int action;
331 bool done = false; 362 bool done = false;
332 int sel;
333 char title[MAX_PATH]; 363 char title[MAX_PATH];
334 struct cuesheet_file cue_file; 364 struct cuesheet_file cue_file;
335 struct mp3entry *id3 = audio_current_track(); 365 struct mp3entry *id3 = audio_current_track();
@@ -355,17 +385,41 @@ void browse_cuesheet(struct cuesheet *cue)
355 switch (action) 385 switch (action)
356 { 386 {
357 case ACTION_STD_OK: 387 case ACTION_STD_OK:
388 {
389 bool startit = true;
390 unsigned long elapsed =
391 cue->tracks[gui_synclist_get_sel_pos(&lists)/2].offset;
392
358 id3 = audio_current_track(); 393 id3 = audio_current_track();
359 if (id3 && *id3->path && strcmp(id3->path, "No file!")) 394 if (id3 && *id3->path)
360 { 395 {
361 look_for_cuesheet_file(id3, &cue_file); 396 look_for_cuesheet_file(id3, &cue_file);
362 if (id3->cuesheet && !strcmp(cue->path, cue_file.path)) 397 if (!strcmp(cue->path, cue_file.path))
363 { 398 startit = false;
364 sel = gui_synclist_get_sel_pos(&lists); 399 }
365 seek(cue->tracks[sel/2].offset); 400
366 } 401 if (!startit)
402 startit = !seek(elapsed);
403
404 if (!startit || !*cue->file)
405 break;
406
407 /* check that this cue is the same one that would be found by
408 a search from playback */
409 char file[MAX_PATH];
410 strlcpy(file, cue->file, MAX_PATH);
411
412 if (!strcmp(cue->path, file) || /* if embedded */
413 (search_for_cuesheet(file, &cue_file) &&
414 !strcmp(cue->path, cue_file.path)))
415 {
416 char *fname = strrsplt(file, '/');
417 char *dirname = fname <= file + 1 ? "/" : file;
418 bookmark_play(dirname, 0, elapsed, 0, current_tick, fname);
367 } 419 }
368 break; 420 break;
421 } /* ACTION_STD_OK */
422
369 case ACTION_STD_CANCEL: 423 case ACTION_STD_CANCEL:
370 done = true; 424 done = true;
371 } 425 }
diff --git a/apps/cuesheet.h b/apps/cuesheet.h
index 31841dacf6..0b9503a9bb 100644
--- a/apps/cuesheet.h
+++ b/apps/cuesheet.h
@@ -39,7 +39,7 @@ struct cue_track_info {
39 39
40struct cuesheet { 40struct cuesheet {
41 char path[MAX_PATH]; 41 char path[MAX_PATH];
42 42 char file[MAX_PATH];
43 char title[MAX_NAME*3+1]; 43 char title[MAX_NAME*3+1];
44 char performer[MAX_NAME*3+1]; 44 char performer[MAX_NAME*3+1];
45 char songwriter[MAX_NAME*3+1]; 45 char songwriter[MAX_NAME*3+1];