summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 @@
#define CUE_DIR ROCKBOX_DIR "/cue"
-struct cuesheet *curr_cue;
-
-#if CONFIG_CODEC != SWCODEC
-/* special trickery because the hwcodec playback engine is in firmware/ */
-static bool cuesheet_handler(const char *filename)
-{
- return cuesheet_is_enabled() && look_for_cuesheet_file(filename, NULL);
-}
-#endif
-
-void cuesheet_init(void)
-{
- if (global_settings.cuesheet) {
- curr_cue = (struct cuesheet *)buffer_alloc(sizeof(struct cuesheet));
-#if CONFIG_CODEC != SWCODEC
- audio_set_cuesheet_callback(cuesheet_handler);
-#endif
- } else {
- curr_cue = NULL;
- }
-}
-
-bool cuesheet_is_enabled(void)
-{
- return (curr_cue != NULL);
-}
-
bool look_for_cuesheet_file(const char *trackpath, char *found_cue_path)
{
/* DEBUGF("look for cue file\n"); */
@@ -134,7 +107,6 @@ bool parse_cuesheet(char *file, struct cuesheet *cue)
char *s;
bool utf8 = false;
- DEBUGF("cue parse\n");
int fd = open_utf8(file,O_RDONLY);
if (fd < 0)
{
@@ -293,12 +265,8 @@ void browse_cuesheet(struct cuesheet *cue)
gui_synclist_set_nb_items(&lists, 2*cue->track_count);
gui_synclist_set_title(&lists, title, 0);
- if (id3 && *id3->path && strcmp(id3->path, "No file!"))
- {
- look_for_cuesheet_file(id3->path, cuepath);
- }
- if (id3 && id3->cuesheet_type && !strcmp(cue->path, cuepath))
+ if (id3)
{
gui_synclist_select_item(&lists,
2*cue_find_current_track(cue, id3->elapsed));
@@ -317,7 +285,7 @@ void browse_cuesheet(struct cuesheet *cue)
if (id3 && *id3->path && strcmp(id3->path, "No file!"))
{
look_for_cuesheet_file(id3->path, cuepath);
- if (id3->cuesheet_type && !strcmp(cue->path, cuepath))
+ if (id3->cuesheet && !strcmp(cue->path, cuepath))
{
sel = gui_synclist_get_sel_pos(&lists);
seek(cue->tracks[sel/2].offset);
@@ -351,8 +319,9 @@ bool display_cuesheet_content(char* filename)
*/
bool curr_cuesheet_skip(int direction, unsigned long curr_pos)
{
+ struct cuesheet *curr_cue = audio_current_track()->cuesheet;
int track = cue_find_current_track(curr_cue, curr_pos);
-
+
if (direction >= 0 && track == curr_cue->track_count - 1)
{
/* we want to get out of the cuesheet */
@@ -406,6 +375,7 @@ static inline void draw_veritcal_line_mark(struct screen * screen,
void cue_draw_markers(struct screen *screen, unsigned long tracklen,
int x1, int x2, int y, int h)
{
+ struct cuesheet *curr_cue = audio_current_track()->cuesheet;
int i,xi;
int w = x2 - x1;
for (i=1; i < curr_cue->track_count; i++)
@@ -415,3 +385,17 @@ void cue_draw_markers(struct screen *screen, unsigned long tracklen,
}
}
#endif
+
+bool cuesheet_subtrack_changed(struct mp3entry *id3)
+{
+ struct cuesheet *cue = id3->cuesheet;
+ if (cue && (id3->elapsed < cue->curr_track->offset
+ || (cue->curr_track_idx < cue->track_count - 1
+ && id3->elapsed >= (cue->curr_track+1)->offset)))
+ {
+ cue_find_current_track(cue, id3->elapsed);
+ cue_spoof_id3(cue, id3);
+ return true;
+ }
+ return false;
+}
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 {
struct cue_track_info *curr_track;
};
-extern struct cuesheet *curr_cue;
-
-/* returns true if cuesheet support is initialised */
-bool cuesheet_is_enabled(void);
-
-/* allocates the cuesheet buffer */
-void cuesheet_init(void);
-
/* looks if there is a cuesheet file that has a name matching "trackpath" */
bool look_for_cuesheet_file(const char *trackpath, char *found_cue_path);
@@ -90,4 +82,7 @@ void cue_draw_markers(struct screen *screen, unsigned long tracklen,
int x1, int x2, int y, int h);
#endif
+/* check if the subtrack has changed */
+bool cuesheet_subtrack_changed(struct mp3entry *id3);
+
#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)
{
struct mp3entry *id3 = gwps->state->id3;
bool retval;
- if (cuesheet_is_enabled() && id3->cuesheet_type
- && (id3->elapsed < curr_cue->curr_track->offset
- || (curr_cue->curr_track_idx < curr_cue->track_count - 1
- && id3->elapsed >= (curr_cue->curr_track+1)->offset)))
- {
- /* We've changed tracks within the cuesheet :
- we need to update the ID3 info and refresh the WPS */
- gwps->state->do_full_update = true;
- cue_find_current_track(curr_cue, id3->elapsed);
- cue_spoof_id3(curr_cue, id3);
- }
-
+ gwps->state->do_full_update = gwps->state->do_full_update ||
+ cuesheet_subtrack_changed(id3);
retval = gui_wps_redraw(gwps, 0,
gwps->state->do_full_update ?
WPS_REFRESH_ALL : WPS_REFRESH_NON_STATIC);
@@ -421,7 +411,7 @@ static void draw_progressbar(struct gui_wps *gwps,
pb->x, pb->x + pb->width, y, pb->height);
#endif
- if ( cuesheet_is_enabled() && state->id3->cuesheet_type )
+ if (state->id3->cuesheet)
cue_draw_markers(display, state->id3->length,
pb->x, pb->x + pb->width, y+1, pb->height-2);
}
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)
}
else
{
- if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
+ if (wps_state.id3->cuesheet)
{
curr_cuesheet_skip(-1, wps_state.id3->elapsed);
return;
@@ -173,7 +173,7 @@ static void prev_track(unsigned long skip_thresh)
static void next_track(void)
{
/* take care of if we're playing a cuesheet */
- if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
+ if (wps_state.id3->cuesheet)
{
if (curr_cuesheet_skip(1, wps_state.id3->elapsed))
{
@@ -557,7 +557,7 @@ long gui_wps_show(void)
break;
if (current_tick -last_right < HZ)
{
- if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
+ if (wps_state.id3->cuesheet)
{
audio_next();
}
@@ -577,7 +577,7 @@ long gui_wps_show(void)
break;
if (current_tick -last_left < HZ)
{
- if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
+ if (wps_state.id3->cuesheet)
{
if (!wps_state.paused)
#if (CONFIG_CODEC == SWCODEC)
@@ -870,22 +870,10 @@ static void track_changed_callback(void *param)
{
wps_state.id3 = (struct mp3entry*)param;
wps_state.nid3 = audio_next_track();
-
- if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type
- && strcmp(wps_state.id3->path, curr_cue->audio_filename))
+ if (wps_state.id3->cuesheet)
{
- /* the current cuesheet isn't the right one any more */
- /* We need to parse the new cuesheet */
- char cuepath[MAX_PATH];
-
- if (look_for_cuesheet_file(wps_state.id3->path, cuepath) &&
- parse_cuesheet(cuepath, curr_cue))
- {
- wps_state.id3->cuesheet_type = 1;
- strcpy(curr_cue->audio_filename, wps_state.id3->path);
- }
-
- cue_spoof_id3(curr_cue, wps_state.id3);
+ cue_find_current_track(wps_state.id3->cuesheet, wps_state.id3->elapsed);
+ cue_spoof_id3(wps_state.id3->cuesheet, wps_state.id3);
}
wps_state.do_full_update = true;
}
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 @@
#include "m5636.h"
#endif
-#include "cuesheet.h"
-
#ifdef SIMULATOR
#include "sim_tasks.h"
#include "system-sdl.h"
@@ -336,7 +334,6 @@ static void init(void)
#endif /* CONFIG_CODEC != SWCODEC */
scrobbler_init();
- cuesheet_init();
#if CONFIG_CODEC == SWCODEC
tdspeed_init();
#endif /* CONFIG_CODEC == SWCODEC */
@@ -552,7 +549,6 @@ static void init(void)
tree_mem_init();
filetype_init();
scrobbler_init();
- cuesheet_init();
#if CONFIG_CODEC == SWCODEC
tdspeed_init();
#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)
switch (action)
{
case ACTION_EXIT_MENUITEM: /* on exit */
- if (!cuesheet_is_enabled() && global_settings.cuesheet)
+ if (global_settings.cuesheet)
splash(HZ*2, ID2P(LANG_PLEASE_REBOOT));
break;
}
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)
}
/* We have successfully read the metadata from the file */
-
-#ifndef __PCTOOL__
- if (cuesheet_is_enabled() && look_for_cuesheet_file(trackname, NULL))
- {
- id3->cuesheet_type = 1;
- }
-#endif
lseek(fd, 0, SEEK_SET);
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 {
#endif
/* Cuesheet support */
- int cuesheet_type; /* 0: none, 1: external, 2: embedded */
+ struct cuesheet *cuesheet;
/* Musicbrainz Track ID */
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 @@
#include "sound.h"
#include "bitswap.h"
#include "appevents.h"
+#include "cuesheet.h"
+#include "settings.h"
#ifndef SIMULATOR
#include "i2c.h"
#include "mas.h"
@@ -116,8 +118,9 @@ static int track_read_idx = 0;
static int track_write_idx = 0;
#endif /* !SIMULATOR */
-/* Cuesheet callback */
-static bool (*cuesheet_callback)(const char *filename) = NULL;
+/* Cuesheet support */
+static struct cuesheet *curr_cuesheet = NULL;
+static bool checked_for_cuesheet = false;
static const char mpeg_thread_name[] = "mpeg";
static unsigned int mpeg_errno;
@@ -265,6 +268,7 @@ static void remove_current_tag(void)
{
/* First move the index, so nobody tries to access the tag */
track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
+ checked_for_cuesheet = false;
debug_tags();
}
else
@@ -470,11 +474,6 @@ unsigned long mpeg_get_last_header(void)
#endif /* !SIMULATOR */
}
-void audio_set_cuesheet_callback(bool (*handler)(const char *filename))
-{
- cuesheet_callback = handler;
-}
-
#ifndef SIMULATOR
/* Send callback events to notify about removing old tracks. */
static void generate_unbuffer_events(void)
@@ -878,9 +877,6 @@ static struct trackdata *add_track_to_tag_list(const char *filename)
if (track->id3.album)
lcd_getstringsize(track->id3.album, NULL, NULL);
#endif
- if (cuesheet_callback)
- if (cuesheet_callback(filename))
- track->id3.cuesheet_type = 1;
/* if this track is the next track then let the UI know it can get it */
send_nid3_event = (track_write_idx == track_read_idx + 1);
@@ -2047,10 +2043,28 @@ static void mpeg_thread(void)
struct mp3entry* audio_current_track()
{
#ifdef SIMULATOR
- return &taginfo;
+ struct mp3entry *id3 = &taginfo;
#else /* !SIMULATOR */
if(num_tracks_in_memory())
- return &get_trackdata(0)->id3;
+ {
+ struct mp3entry *id3 = &get_trackdata(0)->id3;
+#endif
+ if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
+ {
+ checked_for_cuesheet = true; /* only check once per track */
+ char cuepath[MAX_PATH];
+
+ if (look_for_cuesheet_file(id3->path, cuepath) &&
+ parse_cuesheet(cuepath, curr_cuesheet))
+ {
+ strcpy(curr_cuesheet->audio_filename, id3->path);
+ id3->cuesheet = curr_cuesheet;
+ cue_spoof_id3(curr_cuesheet, id3);
+ }
+ }
+ return id3;
+#ifndef SIMULATOR
+ }
else
return NULL;
#endif /* !SIMULATOR */
@@ -2819,6 +2833,19 @@ static void mpeg_thread(void)
{
id3->elapsed+=1000;
id3->offset+=1000;
+ if (id3->cuesheet)
+ {
+ struct cuesheet *cue = id3->cuesheet;
+ unsigned elapsed = id3->elapsed;
+ if (elapsed < cue->curr_track->offset ||
+ (cue->curr_track_idx < cue->track_count-1 &&
+ elapsed >= (cue->curr_track+1)->offset))
+ {
+ cue_find_current_track(id3->cuesheet, id3->elapsed);
+ cue_spoof_id3(id3->cuesheet, id3);
+ send_event(PLAYBACK_EVENT_CUESHEET_TRACK_CHANGE, id3);
+ }
+ }
}
if (id3->elapsed>=id3->length)
audio_next();
@@ -2831,6 +2858,9 @@ static void mpeg_thread(void)
void audio_init(void)
{
mpeg_errno = 0;
+ /* cuesheet support */
+ if (global_settings.cuesheet)
+ curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet));
#ifndef SIMULATOR
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),
static bool view_cue(void)
{
struct mp3entry* id3 = audio_current_track();
- if(id3 && cuesheet_is_enabled() && id3->cuesheet_type)
+ if(id3 && id3->cuesheet)
{
- browse_cuesheet(curr_cue);
+ browse_cuesheet(id3->cuesheet);
}
return false;
}
@@ -981,8 +981,8 @@ static int view_cue_item_callback(int action,
switch (action)
{
case ACTION_REQUEST_MENUITEM:
- if (!selected_file || !cuesheet_is_enabled()
- || !id3 || !id3->cuesheet_type)
+ if (!selected_file
+ || !id3 || !id3->cuesheet)
return ACTION_EXIT_MENUITEM;
break;
}
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 */
* next track otherwise */
static struct mp3entry unbuffered_id3; /* the id3 for the first unbuffered track */
+/* for cuesheet support */
+static struct cuesheet *curr_cue = NULL;
+
/* Track info structure about songs in the file buffer (A/C-) */
struct track_info {
int audio_hid; /* The ID for the track's buffer handle */
@@ -218,6 +221,7 @@ struct track_info {
#ifdef HAVE_ALBUMART
int aa_hid; /* The ID for the track's album art handle */
#endif
+ int cuesheet_hid; /* The ID for the track's parsed cueesheet handle */
size_t filesize; /* File total length */
@@ -384,6 +388,13 @@ static bool clear_track_info(struct track_info *track)
}
#endif
+ if (track->cuesheet_hid >= 0) {
+ if (bufclose(track->cuesheet_hid))
+ track->cuesheet_hid = -1;
+ else
+ return false;
+ }
+
track->filesize = 0;
track->taginfo_ready = false;
@@ -566,6 +577,12 @@ struct mp3entry* audio_current_track(void)
if (cur_idx == track_ridx && *thistrack_id3->path)
{
/* The usual case */
+ if (tracks[cur_idx].cuesheet_hid >= 0)
+ {
+ bufread(tracks[cur_idx].cuesheet_hid, sizeof(struct cuesheet), curr_cue);
+ thistrack_id3->cuesheet = curr_cue;
+ cue_spoof_id3(thistrack_id3->cuesheet, thistrack_id3);
+ }
return thistrack_id3;
}
else if (automatic_skip && offset == -1 && *othertrack_id3->path)
@@ -574,6 +591,12 @@ struct mp3entry* audio_current_track(void)
but the audio being played is still the same (now previous) track.
othertrack_id3.elapsed is being updated in an ISR by
codec_pcmbuf_position_callback */
+ if (tracks[cur_idx].cuesheet_hid >= 0)
+ {
+ bufread(tracks[cur_idx].cuesheet_hid, sizeof(struct cuesheet), curr_cue);
+ othertrack_id3->cuesheet = curr_cue;
+ cue_spoof_id3(othertrack_id3->cuesheet, othertrack_id3);
+ }
return othertrack_id3;
}
@@ -1826,7 +1849,21 @@ static void audio_finish_load_track(void)
return;
}
+ /* Try to load a cuesheet for the track */
+ if (curr_cue)
+ {
+ char cuepath[MAX_PATH];
+ struct cuesheet temp_cue;
+
+ if (look_for_cuesheet_file(track_id3->path, cuepath) &&
+ parse_cuesheet(cuepath, &temp_cue))
+ {
+ strcpy(temp_cue.audio_filename, track_id3->path);
+ tracks[track_widx].cuesheet_hid =
+ bufalloc(&temp_cue, sizeof(struct cuesheet), TYPE_CUESHEET);
+ }
+ }
#ifdef HAVE_ALBUMART
if (tracks[track_widx].aa_hid < 0 && gui_sync_wps_uses_albumart())
{
@@ -2602,6 +2639,10 @@ void audio_init(void)
thistrack_id3 = &mp3entry_buf[0];
othertrack_id3 = &mp3entry_buf[1];
+ /* cuesheet support */
+ if (global_settings.cuesheet)
+ curr_cue = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet));
+
/* initialize the buffer */
filebuf = audiobuf;
@@ -2648,6 +2689,7 @@ void audio_init(void)
#ifdef HAVE_ALBUMART
tracks[i].aa_hid = -1;
#endif
+ tracks[i].cuesheet_hid = -1;
}
add_event(BUFFER_EVENT_REBUFFER, false, buffering_handle_rebuffer_callback);