summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/cuesheet.c54
-rw-r--r--apps/cuesheet.h11
-rw-r--r--apps/gui/gwps-common.c16
-rw-r--r--apps/gui/gwps.c26
-rw-r--r--apps/main.c4
-rw-r--r--apps/menus/playback_menu.c2
-rw-r--r--apps/metadata.c7
-rw-r--r--apps/metadata.h2
-rw-r--r--apps/mpeg.c54
-rw-r--r--apps/onplay.c8
-rw-r--r--apps/playback.c42
11 files changed, 122 insertions, 104 deletions
diff --git a/apps/cuesheet.c b/apps/cuesheet.c
index fa1d93f334..aaa2670a40 100644
--- a/apps/cuesheet.c
+++ b/apps/cuesheet.c
@@ -43,33 +43,6 @@
43 43
44#define CUE_DIR ROCKBOX_DIR "/cue" 44#define CUE_DIR ROCKBOX_DIR "/cue"
45 45
46struct cuesheet *curr_cue;
47
48#if CONFIG_CODEC != SWCODEC
49/* special trickery because the hwcodec playback engine is in firmware/ */
50static bool cuesheet_handler(const char *filename)
51{
52 return cuesheet_is_enabled() && look_for_cuesheet_file(filename, NULL);
53}
54#endif
55
56void cuesheet_init(void)
57{
58 if (global_settings.cuesheet) {
59 curr_cue = (struct cuesheet *)buffer_alloc(sizeof(struct cuesheet));
60#if CONFIG_CODEC != SWCODEC
61 audio_set_cuesheet_callback(cuesheet_handler);
62#endif
63 } else {
64 curr_cue = NULL;
65 }
66}
67
68bool cuesheet_is_enabled(void)
69{
70 return (curr_cue != NULL);
71}
72
73bool look_for_cuesheet_file(const char *trackpath, char *found_cue_path) 46bool look_for_cuesheet_file(const char *trackpath, char *found_cue_path)
74{ 47{
75 /* DEBUGF("look for cue file\n"); */ 48 /* DEBUGF("look for cue file\n"); */
@@ -134,7 +107,6 @@ bool parse_cuesheet(char *file, struct cuesheet *cue)
134 char *s; 107 char *s;
135 bool utf8 = false; 108 bool utf8 = false;
136 109
137 DEBUGF("cue parse\n");
138 int fd = open_utf8(file,O_RDONLY); 110 int fd = open_utf8(file,O_RDONLY);
139 if (fd < 0) 111 if (fd < 0)
140 { 112 {
@@ -293,12 +265,8 @@ void browse_cuesheet(struct cuesheet *cue)
293 gui_synclist_set_nb_items(&lists, 2*cue->track_count); 265 gui_synclist_set_nb_items(&lists, 2*cue->track_count);
294 gui_synclist_set_title(&lists, title, 0); 266 gui_synclist_set_title(&lists, title, 0);
295 267
296 if (id3 && *id3->path && strcmp(id3->path, "No file!"))
297 {
298 look_for_cuesheet_file(id3->path, cuepath);
299 }
300 268
301 if (id3 && id3->cuesheet_type && !strcmp(cue->path, cuepath)) 269 if (id3)
302 { 270 {
303 gui_synclist_select_item(&lists, 271 gui_synclist_select_item(&lists,
304 2*cue_find_current_track(cue, id3->elapsed)); 272 2*cue_find_current_track(cue, id3->elapsed));
@@ -317,7 +285,7 @@ void browse_cuesheet(struct cuesheet *cue)
317 if (id3 && *id3->path && strcmp(id3->path, "No file!")) 285 if (id3 && *id3->path && strcmp(id3->path, "No file!"))
318 { 286 {
319 look_for_cuesheet_file(id3->path, cuepath); 287 look_for_cuesheet_file(id3->path, cuepath);
320 if (id3->cuesheet_type && !strcmp(cue->path, cuepath)) 288 if (id3->cuesheet && !strcmp(cue->path, cuepath))
321 { 289 {
322 sel = gui_synclist_get_sel_pos(&lists); 290 sel = gui_synclist_get_sel_pos(&lists);
323 seek(cue->tracks[sel/2].offset); 291 seek(cue->tracks[sel/2].offset);
@@ -351,8 +319,9 @@ bool display_cuesheet_content(char* filename)
351 */ 319 */
352bool curr_cuesheet_skip(int direction, unsigned long curr_pos) 320bool curr_cuesheet_skip(int direction, unsigned long curr_pos)
353{ 321{
322 struct cuesheet *curr_cue = audio_current_track()->cuesheet;
354 int track = cue_find_current_track(curr_cue, curr_pos); 323 int track = cue_find_current_track(curr_cue, curr_pos);
355 324
356 if (direction >= 0 && track == curr_cue->track_count - 1) 325 if (direction >= 0 && track == curr_cue->track_count - 1)
357 { 326 {
358 /* we want to get out of the cuesheet */ 327 /* we want to get out of the cuesheet */
@@ -406,6 +375,7 @@ static inline void draw_veritcal_line_mark(struct screen * screen,
406void cue_draw_markers(struct screen *screen, unsigned long tracklen, 375void cue_draw_markers(struct screen *screen, unsigned long tracklen,
407 int x1, int x2, int y, int h) 376 int x1, int x2, int y, int h)
408{ 377{
378 struct cuesheet *curr_cue = audio_current_track()->cuesheet;
409 int i,xi; 379 int i,xi;
410 int w = x2 - x1; 380 int w = x2 - x1;
411 for (i=1; i < curr_cue->track_count; i++) 381 for (i=1; i < curr_cue->track_count; i++)
@@ -415,3 +385,17 @@ void cue_draw_markers(struct screen *screen, unsigned long tracklen,
415 } 385 }
416} 386}
417#endif 387#endif
388
389bool cuesheet_subtrack_changed(struct mp3entry *id3)
390{
391 struct cuesheet *cue = id3->cuesheet;
392 if (cue && (id3->elapsed < cue->curr_track->offset
393 || (cue->curr_track_idx < cue->track_count - 1
394 && id3->elapsed >= (cue->curr_track+1)->offset)))
395 {
396 cue_find_current_track(cue, id3->elapsed);
397 cue_spoof_id3(cue, id3);
398 return true;
399 }
400 return false;
401}
diff --git a/apps/cuesheet.h b/apps/cuesheet.h
index 41ee9be397..22ad92fdd3 100644
--- a/apps/cuesheet.h
+++ b/apps/cuesheet.h
@@ -52,14 +52,6 @@ struct cuesheet {
52 struct cue_track_info *curr_track; 52 struct cue_track_info *curr_track;
53}; 53};
54 54
55extern struct cuesheet *curr_cue;
56
57/* returns true if cuesheet support is initialised */
58bool cuesheet_is_enabled(void);
59
60/* allocates the cuesheet buffer */
61void cuesheet_init(void);
62
63/* looks if there is a cuesheet file that has a name matching "trackpath" */ 55/* looks if there is a cuesheet file that has a name matching "trackpath" */
64bool look_for_cuesheet_file(const char *trackpath, char *found_cue_path); 56bool look_for_cuesheet_file(const char *trackpath, char *found_cue_path);
65 57
@@ -90,4 +82,7 @@ void cue_draw_markers(struct screen *screen, unsigned long tracklen,
90 int x1, int x2, int y, int h); 82 int x1, int x2, int y, int h);
91#endif 83#endif
92 84
85/* check if the subtrack has changed */
86bool cuesheet_subtrack_changed(struct mp3entry *id3);
87
93#endif 88#endif
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index c0923a9ab5..dd6ac02d85 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -355,18 +355,8 @@ bool gui_wps_update(struct gui_wps *gwps)
355{ 355{
356 struct mp3entry *id3 = gwps->state->id3; 356 struct mp3entry *id3 = gwps->state->id3;
357 bool retval; 357 bool retval;
358 if (cuesheet_is_enabled() && id3->cuesheet_type 358 gwps->state->do_full_update = gwps->state->do_full_update ||
359 && (id3->elapsed < curr_cue->curr_track->offset 359 cuesheet_subtrack_changed(id3);
360 || (curr_cue->curr_track_idx < curr_cue->track_count - 1
361 && id3->elapsed >= (curr_cue->curr_track+1)->offset)))
362 {
363 /* We've changed tracks within the cuesheet :
364 we need to update the ID3 info and refresh the WPS */
365 gwps->state->do_full_update = true;
366 cue_find_current_track(curr_cue, id3->elapsed);
367 cue_spoof_id3(curr_cue, id3);
368 }
369
370 retval = gui_wps_redraw(gwps, 0, 360 retval = gui_wps_redraw(gwps, 0,
371 gwps->state->do_full_update ? 361 gwps->state->do_full_update ?
372 WPS_REFRESH_ALL : WPS_REFRESH_NON_STATIC); 362 WPS_REFRESH_ALL : WPS_REFRESH_NON_STATIC);
@@ -421,7 +411,7 @@ static void draw_progressbar(struct gui_wps *gwps,
421 pb->x, pb->x + pb->width, y, pb->height); 411 pb->x, pb->x + pb->width, y, pb->height);
422#endif 412#endif
423 413
424 if ( cuesheet_is_enabled() && state->id3->cuesheet_type ) 414 if (state->id3->cuesheet)
425 cue_draw_markers(display, state->id3->length, 415 cue_draw_markers(display, state->id3->length,
426 pb->x, pb->x + pb->width, y+1, pb->height-2); 416 pb->x, pb->x + pb->width, y+1, pb->height-2);
427} 417}
diff --git a/apps/gui/gwps.c b/apps/gui/gwps.c
index 9eea925220..eb1437c910 100644
--- a/apps/gui/gwps.c
+++ b/apps/gui/gwps.c
@@ -148,7 +148,7 @@ static void prev_track(unsigned long skip_thresh)
148 } 148 }
149 else 149 else
150 { 150 {
151 if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type) 151 if (wps_state.id3->cuesheet)
152 { 152 {
153 curr_cuesheet_skip(-1, wps_state.id3->elapsed); 153 curr_cuesheet_skip(-1, wps_state.id3->elapsed);
154 return; 154 return;
@@ -173,7 +173,7 @@ static void prev_track(unsigned long skip_thresh)
173static void next_track(void) 173static void next_track(void)
174{ 174{
175 /* take care of if we're playing a cuesheet */ 175 /* take care of if we're playing a cuesheet */
176 if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type) 176 if (wps_state.id3->cuesheet)
177 { 177 {
178 if (curr_cuesheet_skip(1, wps_state.id3->elapsed)) 178 if (curr_cuesheet_skip(1, wps_state.id3->elapsed))
179 { 179 {
@@ -557,7 +557,7 @@ long gui_wps_show(void)
557 break; 557 break;
558 if (current_tick -last_right < HZ) 558 if (current_tick -last_right < HZ)
559 { 559 {
560 if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type) 560 if (wps_state.id3->cuesheet)
561 { 561 {
562 audio_next(); 562 audio_next();
563 } 563 }
@@ -577,7 +577,7 @@ long gui_wps_show(void)
577 break; 577 break;
578 if (current_tick -last_left < HZ) 578 if (current_tick -last_left < HZ)
579 { 579 {
580 if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type) 580 if (wps_state.id3->cuesheet)
581 { 581 {
582 if (!wps_state.paused) 582 if (!wps_state.paused)
583#if (CONFIG_CODEC == SWCODEC) 583#if (CONFIG_CODEC == SWCODEC)
@@ -870,22 +870,10 @@ static void track_changed_callback(void *param)
870{ 870{
871 wps_state.id3 = (struct mp3entry*)param; 871 wps_state.id3 = (struct mp3entry*)param;
872 wps_state.nid3 = audio_next_track(); 872 wps_state.nid3 = audio_next_track();
873 873 if (wps_state.id3->cuesheet)
874 if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type
875 && strcmp(wps_state.id3->path, curr_cue->audio_filename))
876 { 874 {
877 /* the current cuesheet isn't the right one any more */ 875 cue_find_current_track(wps_state.id3->cuesheet, wps_state.id3->elapsed);
878 /* We need to parse the new cuesheet */ 876 cue_spoof_id3(wps_state.id3->cuesheet, wps_state.id3);
879 char cuepath[MAX_PATH];
880
881 if (look_for_cuesheet_file(wps_state.id3->path, cuepath) &&
882 parse_cuesheet(cuepath, curr_cue))
883 {
884 wps_state.id3->cuesheet_type = 1;
885 strcpy(curr_cue->audio_filename, wps_state.id3->path);
886 }
887
888 cue_spoof_id3(curr_cue, wps_state.id3);
889 } 877 }
890 wps_state.do_full_update = true; 878 wps_state.do_full_update = true;
891} 879}
diff --git a/apps/main.c b/apps/main.c
index a7c8bef6c0..929c946334 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -110,8 +110,6 @@
110#include "m5636.h" 110#include "m5636.h"
111#endif 111#endif
112 112
113#include "cuesheet.h"
114
115#ifdef SIMULATOR 113#ifdef SIMULATOR
116#include "sim_tasks.h" 114#include "sim_tasks.h"
117#include "system-sdl.h" 115#include "system-sdl.h"
@@ -336,7 +334,6 @@ static void init(void)
336#endif /* CONFIG_CODEC != SWCODEC */ 334#endif /* CONFIG_CODEC != SWCODEC */
337 335
338 scrobbler_init(); 336 scrobbler_init();
339 cuesheet_init();
340#if CONFIG_CODEC == SWCODEC 337#if CONFIG_CODEC == SWCODEC
341 tdspeed_init(); 338 tdspeed_init();
342#endif /* CONFIG_CODEC == SWCODEC */ 339#endif /* CONFIG_CODEC == SWCODEC */
@@ -552,7 +549,6 @@ static void init(void)
552 tree_mem_init(); 549 tree_mem_init();
553 filetype_init(); 550 filetype_init();
554 scrobbler_init(); 551 scrobbler_init();
555 cuesheet_init();
556#if CONFIG_CODEC == SWCODEC 552#if CONFIG_CODEC == SWCODEC
557 tdspeed_init(); 553 tdspeed_init();
558#endif /* CONFIG_CODEC == SWCODEC */ 554#endif /* CONFIG_CODEC == SWCODEC */
diff --git a/apps/menus/playback_menu.c b/apps/menus/playback_menu.c
index 28e8601282..1e8670ebea 100644
--- a/apps/menus/playback_menu.c
+++ b/apps/menus/playback_menu.c
@@ -157,7 +157,7 @@ static int cuesheet_callback(int action,const struct menu_item_ex *this_item)
157 switch (action) 157 switch (action)
158 { 158 {
159 case ACTION_EXIT_MENUITEM: /* on exit */ 159 case ACTION_EXIT_MENUITEM: /* on exit */
160 if (!cuesheet_is_enabled() && global_settings.cuesheet) 160 if (global_settings.cuesheet)
161 splash(HZ*2, ID2P(LANG_PLEASE_REBOOT)); 161 splash(HZ*2, ID2P(LANG_PLEASE_REBOOT));
162 break; 162 break;
163 } 163 }
diff --git a/apps/metadata.c b/apps/metadata.c
index b995e11d95..a0409a83ac 100644
--- a/apps/metadata.c
+++ b/apps/metadata.c
@@ -394,13 +394,6 @@ bool get_metadata(struct mp3entry* id3, int fd, const char* trackname)
394 } 394 }
395 395
396 /* We have successfully read the metadata from the file */ 396 /* We have successfully read the metadata from the file */
397
398#ifndef __PCTOOL__
399 if (cuesheet_is_enabled() && look_for_cuesheet_file(trackname, NULL))
400 {
401 id3->cuesheet_type = 1;
402 }
403#endif
404 397
405 lseek(fd, 0, SEEK_SET); 398 lseek(fd, 0, SEEK_SET);
406 strlcpy(id3->path, trackname, sizeof(id3->path)); 399 strlcpy(id3->path, trackname, sizeof(id3->path));
diff --git a/apps/metadata.h b/apps/metadata.h
index 6c0201781a..f3b50c947d 100644
--- a/apps/metadata.h
+++ b/apps/metadata.h
@@ -239,7 +239,7 @@ struct mp3entry {
239#endif 239#endif
240 240
241 /* Cuesheet support */ 241 /* Cuesheet support */
242 int cuesheet_type; /* 0: none, 1: external, 2: embedded */ 242 struct cuesheet *cuesheet;
243 243
244 /* Musicbrainz Track ID */ 244 /* Musicbrainz Track ID */
245 char* mb_track_id; 245 char* mb_track_id;
diff --git a/apps/mpeg.c b/apps/mpeg.c
index 0e1217b5c8..5db0272752 100644
--- a/apps/mpeg.c
+++ b/apps/mpeg.c
@@ -40,6 +40,8 @@
40#include "sound.h" 40#include "sound.h"
41#include "bitswap.h" 41#include "bitswap.h"
42#include "appevents.h" 42#include "appevents.h"
43#include "cuesheet.h"
44#include "settings.h"
43#ifndef SIMULATOR 45#ifndef SIMULATOR
44#include "i2c.h" 46#include "i2c.h"
45#include "mas.h" 47#include "mas.h"
@@ -116,8 +118,9 @@ static int track_read_idx = 0;
116static int track_write_idx = 0; 118static int track_write_idx = 0;
117#endif /* !SIMULATOR */ 119#endif /* !SIMULATOR */
118 120
119/* Cuesheet callback */ 121/* Cuesheet support */
120static bool (*cuesheet_callback)(const char *filename) = NULL; 122static struct cuesheet *curr_cuesheet = NULL;
123static bool checked_for_cuesheet = false;
121 124
122static const char mpeg_thread_name[] = "mpeg"; 125static const char mpeg_thread_name[] = "mpeg";
123static unsigned int mpeg_errno; 126static unsigned int mpeg_errno;
@@ -265,6 +268,7 @@ static void remove_current_tag(void)
265 { 268 {
266 /* First move the index, so nobody tries to access the tag */ 269 /* First move the index, so nobody tries to access the tag */
267 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK; 270 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
271 checked_for_cuesheet = false;
268 debug_tags(); 272 debug_tags();
269 } 273 }
270 else 274 else
@@ -470,11 +474,6 @@ unsigned long mpeg_get_last_header(void)
470#endif /* !SIMULATOR */ 474#endif /* !SIMULATOR */
471} 475}
472 476
473void audio_set_cuesheet_callback(bool (*handler)(const char *filename))
474{
475 cuesheet_callback = handler;
476}
477
478#ifndef SIMULATOR 477#ifndef SIMULATOR
479/* Send callback events to notify about removing old tracks. */ 478/* Send callback events to notify about removing old tracks. */
480static void generate_unbuffer_events(void) 479static void generate_unbuffer_events(void)
@@ -878,9 +877,6 @@ static struct trackdata *add_track_to_tag_list(const char *filename)
878 if (track->id3.album) 877 if (track->id3.album)
879 lcd_getstringsize(track->id3.album, NULL, NULL); 878 lcd_getstringsize(track->id3.album, NULL, NULL);
880#endif 879#endif
881 if (cuesheet_callback)
882 if (cuesheet_callback(filename))
883 track->id3.cuesheet_type = 1;
884 880
885 /* if this track is the next track then let the UI know it can get it */ 881 /* if this track is the next track then let the UI know it can get it */
886 send_nid3_event = (track_write_idx == track_read_idx + 1); 882 send_nid3_event = (track_write_idx == track_read_idx + 1);
@@ -2047,10 +2043,28 @@ static void mpeg_thread(void)
2047struct mp3entry* audio_current_track() 2043struct mp3entry* audio_current_track()
2048{ 2044{
2049#ifdef SIMULATOR 2045#ifdef SIMULATOR
2050 return &taginfo; 2046 struct mp3entry *id3 = &taginfo;
2051#else /* !SIMULATOR */ 2047#else /* !SIMULATOR */
2052 if(num_tracks_in_memory()) 2048 if(num_tracks_in_memory())
2053 return &get_trackdata(0)->id3; 2049 {
2050 struct mp3entry *id3 = &get_trackdata(0)->id3;
2051#endif
2052 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
2053 {
2054 checked_for_cuesheet = true; /* only check once per track */
2055 char cuepath[MAX_PATH];
2056
2057 if (look_for_cuesheet_file(id3->path, cuepath) &&
2058 parse_cuesheet(cuepath, curr_cuesheet))
2059 {
2060 strcpy(curr_cuesheet->audio_filename, id3->path);
2061 id3->cuesheet = curr_cuesheet;
2062 cue_spoof_id3(curr_cuesheet, id3);
2063 }
2064 }
2065 return id3;
2066#ifndef SIMULATOR
2067 }
2054 else 2068 else
2055 return NULL; 2069 return NULL;
2056#endif /* !SIMULATOR */ 2070#endif /* !SIMULATOR */
@@ -2819,6 +2833,19 @@ static void mpeg_thread(void)
2819 { 2833 {
2820 id3->elapsed+=1000; 2834 id3->elapsed+=1000;
2821 id3->offset+=1000; 2835 id3->offset+=1000;
2836 if (id3->cuesheet)
2837 {
2838 struct cuesheet *cue = id3->cuesheet;
2839 unsigned elapsed = id3->elapsed;
2840 if (elapsed < cue->curr_track->offset ||
2841 (cue->curr_track_idx < cue->track_count-1 &&
2842 elapsed >= (cue->curr_track+1)->offset))
2843 {
2844 cue_find_current_track(id3->cuesheet, id3->elapsed);
2845 cue_spoof_id3(id3->cuesheet, id3);
2846 send_event(PLAYBACK_EVENT_CUESHEET_TRACK_CHANGE, id3);
2847 }
2848 }
2822 } 2849 }
2823 if (id3->elapsed>=id3->length) 2850 if (id3->elapsed>=id3->length)
2824 audio_next(); 2851 audio_next();
@@ -2831,6 +2858,9 @@ static void mpeg_thread(void)
2831void audio_init(void) 2858void audio_init(void)
2832{ 2859{
2833 mpeg_errno = 0; 2860 mpeg_errno = 0;
2861 /* cuesheet support */
2862 if (global_settings.cuesheet)
2863 curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet));
2834 2864
2835#ifndef SIMULATOR 2865#ifndef SIMULATOR
2836 audiobuflen = audiobufend - audiobuf; 2866 audiobuflen = audiobufend - audiobuf;
diff --git a/apps/onplay.c b/apps/onplay.c
index 9f38b32fb4..ad71f7302e 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -967,9 +967,9 @@ MENUITEM_FUNCTION(rating_item, 0, ID2P(LANG_MENU_SET_RATING),
967static bool view_cue(void) 967static bool view_cue(void)
968{ 968{
969 struct mp3entry* id3 = audio_current_track(); 969 struct mp3entry* id3 = audio_current_track();
970 if(id3 && cuesheet_is_enabled() && id3->cuesheet_type) 970 if(id3 && id3->cuesheet)
971 { 971 {
972 browse_cuesheet(curr_cue); 972 browse_cuesheet(id3->cuesheet);
973 } 973 }
974 return false; 974 return false;
975} 975}
@@ -981,8 +981,8 @@ static int view_cue_item_callback(int action,
981 switch (action) 981 switch (action)
982 { 982 {
983 case ACTION_REQUEST_MENUITEM: 983 case ACTION_REQUEST_MENUITEM:
984 if (!selected_file || !cuesheet_is_enabled() 984 if (!selected_file
985 || !id3 || !id3->cuesheet_type) 985 || !id3 || !id3->cuesheet)
986 return ACTION_EXIT_MENUITEM; 986 return ACTION_EXIT_MENUITEM;
987 break; 987 break;
988 } 988 }
diff --git a/apps/playback.c b/apps/playback.c
index cee89d3bbb..7bd3f252ae 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -210,6 +210,9 @@ static struct mp3entry *thistrack_id3, /* the currently playing track */
210 * next track otherwise */ 210 * next track otherwise */
211static struct mp3entry unbuffered_id3; /* the id3 for the first unbuffered track */ 211static struct mp3entry unbuffered_id3; /* the id3 for the first unbuffered track */
212 212
213/* for cuesheet support */
214static struct cuesheet *curr_cue = NULL;
215
213/* Track info structure about songs in the file buffer (A/C-) */ 216/* Track info structure about songs in the file buffer (A/C-) */
214struct track_info { 217struct track_info {
215 int audio_hid; /* The ID for the track's buffer handle */ 218 int audio_hid; /* The ID for the track's buffer handle */
@@ -218,6 +221,7 @@ struct track_info {
218#ifdef HAVE_ALBUMART 221#ifdef HAVE_ALBUMART
219 int aa_hid; /* The ID for the track's album art handle */ 222 int aa_hid; /* The ID for the track's album art handle */
220#endif 223#endif
224 int cuesheet_hid; /* The ID for the track's parsed cueesheet handle */
221 225
222 size_t filesize; /* File total length */ 226 size_t filesize; /* File total length */
223 227
@@ -384,6 +388,13 @@ static bool clear_track_info(struct track_info *track)
384 } 388 }
385#endif 389#endif
386 390
391 if (track->cuesheet_hid >= 0) {
392 if (bufclose(track->cuesheet_hid))
393 track->cuesheet_hid = -1;
394 else
395 return false;
396 }
397
387 track->filesize = 0; 398 track->filesize = 0;
388 track->taginfo_ready = false; 399 track->taginfo_ready = false;
389 400
@@ -566,6 +577,12 @@ struct mp3entry* audio_current_track(void)
566 if (cur_idx == track_ridx && *thistrack_id3->path) 577 if (cur_idx == track_ridx && *thistrack_id3->path)
567 { 578 {
568 /* The usual case */ 579 /* The usual case */
580 if (tracks[cur_idx].cuesheet_hid >= 0)
581 {
582 bufread(tracks[cur_idx].cuesheet_hid, sizeof(struct cuesheet), curr_cue);
583 thistrack_id3->cuesheet = curr_cue;
584 cue_spoof_id3(thistrack_id3->cuesheet, thistrack_id3);
585 }
569 return thistrack_id3; 586 return thistrack_id3;
570 } 587 }
571 else if (automatic_skip && offset == -1 && *othertrack_id3->path) 588 else if (automatic_skip && offset == -1 && *othertrack_id3->path)
@@ -574,6 +591,12 @@ struct mp3entry* audio_current_track(void)
574 but the audio being played is still the same (now previous) track. 591 but the audio being played is still the same (now previous) track.
575 othertrack_id3.elapsed is being updated in an ISR by 592 othertrack_id3.elapsed is being updated in an ISR by
576 codec_pcmbuf_position_callback */ 593 codec_pcmbuf_position_callback */
594 if (tracks[cur_idx].cuesheet_hid >= 0)
595 {
596 bufread(tracks[cur_idx].cuesheet_hid, sizeof(struct cuesheet), curr_cue);
597 othertrack_id3->cuesheet = curr_cue;
598 cue_spoof_id3(othertrack_id3->cuesheet, othertrack_id3);
599 }
577 return othertrack_id3; 600 return othertrack_id3;
578 } 601 }
579 602
@@ -1826,7 +1849,21 @@ static void audio_finish_load_track(void)
1826 1849
1827 return; 1850 return;
1828 } 1851 }
1852 /* Try to load a cuesheet for the track */
1853 if (curr_cue)
1854 {
1855 char cuepath[MAX_PATH];
1829 1856
1857 struct cuesheet temp_cue;
1858
1859 if (look_for_cuesheet_file(track_id3->path, cuepath) &&
1860 parse_cuesheet(cuepath, &temp_cue))
1861 {
1862 strcpy(temp_cue.audio_filename, track_id3->path);
1863 tracks[track_widx].cuesheet_hid =
1864 bufalloc(&temp_cue, sizeof(struct cuesheet), TYPE_CUESHEET);
1865 }
1866 }
1830#ifdef HAVE_ALBUMART 1867#ifdef HAVE_ALBUMART
1831 if (tracks[track_widx].aa_hid < 0 && gui_sync_wps_uses_albumart()) 1868 if (tracks[track_widx].aa_hid < 0 && gui_sync_wps_uses_albumart())
1832 { 1869 {
@@ -2602,6 +2639,10 @@ void audio_init(void)
2602 thistrack_id3 = &mp3entry_buf[0]; 2639 thistrack_id3 = &mp3entry_buf[0];
2603 othertrack_id3 = &mp3entry_buf[1]; 2640 othertrack_id3 = &mp3entry_buf[1];
2604 2641
2642 /* cuesheet support */
2643 if (global_settings.cuesheet)
2644 curr_cue = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet));
2645
2605 /* initialize the buffer */ 2646 /* initialize the buffer */
2606 filebuf = audiobuf; 2647 filebuf = audiobuf;
2607 2648
@@ -2648,6 +2689,7 @@ void audio_init(void)
2648#ifdef HAVE_ALBUMART 2689#ifdef HAVE_ALBUMART
2649 tracks[i].aa_hid = -1; 2690 tracks[i].aa_hid = -1;
2650#endif 2691#endif
2692 tracks[i].cuesheet_hid = -1;
2651 } 2693 }
2652 2694
2653 add_event(BUFFER_EVENT_REBUFFER, false, buffering_handle_rebuffer_callback); 2695 add_event(BUFFER_EVENT_REBUFFER, false, buffering_handle_rebuffer_callback);