summaryrefslogtreecommitdiff
path: root/firmware/mpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r--firmware/mpeg.c68
1 files changed, 60 insertions, 8 deletions
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)
280} 280}
281#endif /* !SIMULATOR */ 281#endif /* !SIMULATOR */
282 282
283/***********************************************************************/
284/* audio event handling */
285
286#define MAX_EVENT_HANDLERS 10
287struct event_handlers_table
288{
289 AUDIO_EVENT_HANDLER handler;
290 unsigned short mask;
291};
292static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
293static int event_handlers_count = 0;
294
295void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
296{
297 if (event_handlers_count < MAX_EVENT_HANDLERS)
298 {
299 event_handlers[event_handlers_count].handler = handler;
300 event_handlers[event_handlers_count].mask = mask;
301 event_handlers_count++;
302 }
303}
304
305/* dispatch calls each handler in the order registered and returns after some
306 handler actually handles the event (the event is assumed to no longer be valid
307 after this, due to the handler changing some condition); returns true if someone
308 handled the event, which is expected to cause the caller to skip its own handling
309 of the event */
310#ifndef SIMULATOR
311static bool audio_dispatch_event(unsigned short event, unsigned long data)
312{
313 int i = 0;
314 for(i=0; i < event_handlers_count; i++)
315 {
316 if ( event_handlers[i].mask & event )
317 {
318 int rc = event_handlers[i].handler(event, data);
319 if ( rc == AUDIO_EVENT_RC_HANDLED )
320 return true;
321 }
322 }
323 return false;
324}
325#endif
326
327/***********************************************************************/
328
283static void set_elapsed(struct mp3entry* id3) 329static void set_elapsed(struct mp3entry* id3)
284{ 330{
285 if ( id3->vbr ) { 331 if ( id3->vbr ) {
@@ -730,9 +776,10 @@ void rec_tick(void)
730 776
731void playback_tick(void) 777void playback_tick(void)
732{ 778{
733 get_trackdata(0)->id3.elapsed += 779 struct trackdata *ptd = get_trackdata(0);
734 (current_tick - last_dma_tick) * 1000 / HZ; 780 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
735 last_dma_tick = current_tick; 781 last_dma_tick = current_tick;
782 audio_dispatch_event(AUDIO_EVENT_POS_REPORT, (unsigned long)ptd->id3.elapsed);
736} 783}
737 784
738static void reset_mp3_buffer(void) 785static void reset_mp3_buffer(void)
@@ -762,8 +809,11 @@ static void transfer_end(unsigned char** ppbuf, int* psize)
762 { 809 {
763 if (audiobuf_read == get_trackdata(track_offset)->mempos) 810 if (audiobuf_read == get_trackdata(track_offset)->mempos)
764 { 811 {
765 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0); 812 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
766 track_offset++; 813 {
814 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
815 track_offset++;
816 }
767 } 817 }
768 } 818 }
769 819
@@ -823,10 +873,12 @@ static void transfer_end(unsigned char** ppbuf, int* psize)
823 } 873 }
824 else 874 else
825 { 875 {
826 DEBUGF("No more MP3 data. Stopping.\n"); 876 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
827 877 {
828 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0); 878 DEBUGF("No more MP3 data. Stopping.\n");
829 playing = false; 879 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
880 playing = false;
881 }
830 } 882 }
831 *psize = 0; /* no more transfer */ 883 *psize = 0; /* no more transfer */
832 } 884 }