diff options
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r-- | firmware/mpeg.c | 68 |
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 | ||
287 | struct event_handlers_table | ||
288 | { | ||
289 | AUDIO_EVENT_HANDLER handler; | ||
290 | unsigned short mask; | ||
291 | }; | ||
292 | static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS]; | ||
293 | static int event_handlers_count = 0; | ||
294 | |||
295 | void 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 | ||
311 | static 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 | |||
283 | static void set_elapsed(struct mp3entry* id3) | 329 | static 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 | ||
731 | void playback_tick(void) | 777 | void 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 | ||
738 | static void reset_mp3_buffer(void) | 785 | static 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 | } |