summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2005-08-21 23:01:12 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2005-08-21 23:01:12 +0000
commit0ad617cbf0cc85dde241345194b76b590df567a8 (patch)
tree65931c5a10788981b17f08bca1ba83151bee2855 /firmware
parent658c8451ead9e7d07478c903c430af9c7799f324 (diff)
downloadrockbox-0ad617cbf0cc85dde241345194b76b590df567a8.tar.gz
rockbox-0ad617cbf0cc85dde241345194b76b590df567a8.zip
Patch #1105616 by Ray Lambert - A-B Repeat for Archos studio/recorder, still not 100% complete, but I wanted to commit it before the 2.5 feature freeze
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7380 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/audio.h40
-rw-r--r--firmware/export/config-fmrecorder.h2
-rw-r--r--firmware/export/config-player.h2
-rw-r--r--firmware/export/config-recorder.h2
-rw-r--r--firmware/export/config-recorderv2.h2
-rw-r--r--firmware/mpeg.c68
6 files changed, 108 insertions, 8 deletions
diff --git a/firmware/export/audio.h b/firmware/export/audio.h
index 17de7f077d..67ed052f2b 100644
--- a/firmware/export/audio.h
+++ b/firmware/export/audio.h
@@ -79,4 +79,44 @@ int audio_get_file_pos(void);
void audio_beep(int duration);
void audio_init_playback(void);
+/***********************************************************************/
+/* audio event handling */
+
+/* subscribe to one or more audio event(s) by OR'ing together the desired */
+/* event IDs (defined below); a handler is called with a solitary event ID */
+/* (so switch() is okay) and possibly some useful data (depending on the */
+/* event); a handler must return one of the return codes defined below */
+
+typedef int (*AUDIO_EVENT_HANDLER)(unsigned short event, unsigned long data);
+
+void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask);
+
+/***********************************************************************/
+/* handler return codes */
+
+#define AUDIO_EVENT_RC_IGNORED 200
+ /* indicates that no action was taken or the event was not recognized */
+
+#define AUDIO_EVENT_RC_HANDLED 201
+ /* indicates that the event was handled and some action was taken which renders
+ the original event invalid; USE WITH CARE!; this return code aborts all further
+ processing of the given event */
+
+/***********************************************************************/
+/* audio event IDs */
+
+#define AUDIO_EVENT_POS_REPORT (1<<0)
+ /* sends a periodic song position report to handlers; a report is sent on
+ each kernal tick; the number of ticks per second is defined by HZ; on each
+ report the current song position is passed in 'data'; if a handler takes an
+ action that changes the song or the song position it must return
+ AUDIO_EVENT_RC_HANDLED which suppresses the event for any remaining handlers */
+
+#define AUDIO_EVENT_END_OF_TRACK (1<<1)
+ /* generated when the end of the currently playing track is reached; no
+ data is passed; if the handler implements some alternate end-of-track
+ processing it should return AUDIO_EVENT_RC_HANDLED which suppresses the
+ event for any remaining handlers as well as the normal end-of-track
+ processing */
+
#endif
diff --git a/firmware/export/config-fmrecorder.h b/firmware/export/config-fmrecorder.h
index 40ba404a82..c53388984f 100644
--- a/firmware/export/config-fmrecorder.h
+++ b/firmware/export/config-fmrecorder.h
@@ -24,6 +24,8 @@
/* Define this if you have an FM Radio */
#define CONFIG_TUNER S1A0903X01
+#define AB_REPEAT_ENABLE 1
+
#ifndef SIMULATOR
/* Define this if you have a MAS3587F */
diff --git a/firmware/export/config-player.h b/firmware/export/config-player.h
index 57fd7d8d92..70858a1636 100644
--- a/firmware/export/config-player.h
+++ b/firmware/export/config-player.h
@@ -12,6 +12,8 @@
/* The number of bytes reserved for loadable plugins */
#define PLUGIN_BUFFER_SIZE 0x8000
+#define AB_REPEAT_ENABLE 1
+
#ifndef SIMULATOR
/* Define this if you have a SH7034 */
diff --git a/firmware/export/config-recorder.h b/firmware/export/config-recorder.h
index bab6cd17c0..51cdb79321 100644
--- a/firmware/export/config-recorder.h
+++ b/firmware/export/config-recorder.h
@@ -18,6 +18,8 @@
/* The number of bytes reserved for loadable plugins */
#define PLUGIN_BUFFER_SIZE 0x8000
+#define AB_REPEAT_ENABLE 1
+
#ifndef SIMULATOR
/* Define this if you have a MAS3587F */
diff --git a/firmware/export/config-recorderv2.h b/firmware/export/config-recorderv2.h
index 058495e894..b2d6d01669 100644
--- a/firmware/export/config-recorderv2.h
+++ b/firmware/export/config-recorderv2.h
@@ -21,6 +21,8 @@
/* The number of bytes reserved for loadable plugins */
#define PLUGIN_BUFFER_SIZE 0x8000
+#define AB_REPEAT_ENABLE 1
+
#ifndef SIMULATOR
/* Define this if you have a SH7034 */
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 575ba29fe3..721a4acbcc 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -280,6 +280,52 @@ static struct trackdata *get_trackdata(int offset)
}
#endif /* !SIMULATOR */
+/***********************************************************************/
+/* audio event handling */
+
+#define MAX_EVENT_HANDLERS 10
+struct event_handlers_table
+{
+ AUDIO_EVENT_HANDLER handler;
+ unsigned short mask;
+};
+static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
+static int event_handlers_count = 0;
+
+void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
+{
+ if (event_handlers_count < MAX_EVENT_HANDLERS)
+ {
+ event_handlers[event_handlers_count].handler = handler;
+ event_handlers[event_handlers_count].mask = mask;
+ event_handlers_count++;
+ }
+}
+
+/* dispatch calls each handler in the order registered and returns after some
+ handler actually handles the event (the event is assumed to no longer be valid
+ after this, due to the handler changing some condition); returns true if someone
+ handled the event, which is expected to cause the caller to skip its own handling
+ of the event */
+#ifndef SIMULATOR
+static bool audio_dispatch_event(unsigned short event, unsigned long data)
+{
+ int i = 0;
+ for(i=0; i < event_handlers_count; i++)
+ {
+ if ( event_handlers[i].mask & event )
+ {
+ int rc = event_handlers[i].handler(event, data);
+ if ( rc == AUDIO_EVENT_RC_HANDLED )
+ return true;
+ }
+ }
+ return false;
+}
+#endif
+
+/***********************************************************************/
+
static void set_elapsed(struct mp3entry* id3)
{
if ( id3->vbr ) {
@@ -730,9 +776,10 @@ void rec_tick(void)
void playback_tick(void)
{
- get_trackdata(0)->id3.elapsed +=
- (current_tick - last_dma_tick) * 1000 / HZ;
+ struct trackdata *ptd = get_trackdata(0);
+ ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
last_dma_tick = current_tick;
+ audio_dispatch_event(AUDIO_EVENT_POS_REPORT, (unsigned long)ptd->id3.elapsed);
}
static void reset_mp3_buffer(void)
@@ -762,8 +809,11 @@ static void transfer_end(unsigned char** ppbuf, int* psize)
{
if (audiobuf_read == get_trackdata(track_offset)->mempos)
{
- queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
- track_offset++;
+ if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
+ {
+ queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
+ track_offset++;
+ }
}
}
@@ -823,10 +873,12 @@ static void transfer_end(unsigned char** ppbuf, int* psize)
}
else
{
- DEBUGF("No more MP3 data. Stopping.\n");
-
- queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
- playing = false;
+ if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
+ {
+ DEBUGF("No more MP3 data. Stopping.\n");
+ queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
+ playing = false;
+ }
}
*psize = 0; /* no more transfer */
}