summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2008-03-16 13:55:16 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2008-03-16 13:55:16 +0000
commit19c6e66c1353993659ee007a6c1792a6b0b7ba13 (patch)
tree1dd7f88282b2e543fb5b22458fcb2f3bf1c7eb80 /firmware
parent478ba0afa11061a620e44cd9cc60debd955b1b33 (diff)
downloadrockbox-19c6e66c1353993659ee007a6c1792a6b0b7ba13.tar.gz
rockbox-19c6e66c1353993659ee007a6c1792a6b0b7ba13.zip
Implement the playback event handling as a system-wide multi-purpose event system. Unified mpeg.c and playback.c audio event handling. Converted ata_idle_notify to use the new event handling system also.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16682 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/ata_idle_notify.c61
-rw-r--r--firmware/events.c88
-rw-r--r--firmware/export/ata_idle_notify.h10
-rw-r--r--firmware/export/events.h51
-rw-r--r--firmware/export/mpeg.h1
-rw-r--r--firmware/mpeg.c41
7 files changed, 161 insertions, 92 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index b5906d4648..ea8ce46cca 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1,4 +1,5 @@
1ata_idle_notify.c 1ata_idle_notify.c
2events.c
2backlight.c 3backlight.c
3buffer.c 4buffer.c
4id3.c 5id3.c
diff --git a/firmware/ata_idle_notify.c b/firmware/ata_idle_notify.c
index 1fc6605ac6..a97c3538da 100644
--- a/firmware/ata_idle_notify.c
+++ b/firmware/ata_idle_notify.c
@@ -23,60 +23,31 @@
23#include "kernel.h" 23#include "kernel.h"
24#include "string.h" 24#include "string.h"
25 25
26#if USING_ATA_CALLBACK 26void register_ata_idle_func(ata_idle_notify function)
27static ata_idle_notify ata_idle_notify_funcs[MAX_ATA_CALLBACKS];
28static int ata_callback_count = 0;
29#endif
30
31
32bool register_ata_idle_func(ata_idle_notify function)
33{ 27{
34#if USING_ATA_CALLBACK 28#if USING_ATA_CALLBACK
35 int i; 29 add_event(DISK_EVENT_SPINUP, function);
36 if (ata_callback_count >= MAX_ATA_CALLBACKS)
37 return false;
38 for (i=0; i<MAX_ATA_CALLBACKS; i++)
39 {
40 if (ata_idle_notify_funcs[i] == NULL)
41 {
42 ata_idle_notify_funcs[i] = function;
43 ata_callback_count++;
44 return true;
45 }
46 else if (ata_idle_notify_funcs[i] == function)
47 return true;
48 }
49 return false;
50#else 30#else
51 function(); /* just call the function now */ 31 function(); /* just call the function now */
52/* this _may_ cause problems later if the calling function 32/* this _may_ cause problems later if the calling function
53 sets a variable expecting the callback to unset it, because 33 sets a variable expecting the callback to unset it, because
54 the callback will be run before this function exits, so before the var is set */ 34 the callback will be run before this function exits, so before the var is set */
55 return true;
56#endif 35#endif
57} 36}
58 37
59#if USING_ATA_CALLBACK 38#if USING_ATA_CALLBACK
60void unregister_ata_idle_func(ata_idle_notify func, bool run) 39void unregister_ata_idle_func(ata_idle_notify func, bool run)
61{ 40{
62 int i; 41 remove_event(DISK_EVENT_SPINUP, func);
63 for (i=0; i<MAX_ATA_CALLBACKS; i++) 42
64 { 43 if (run)
65 if (ata_idle_notify_funcs[i] == func) 44 func();
66 {
67 ata_idle_notify_funcs[i] = NULL;
68 ata_callback_count--;
69 if (run) func();
70 }
71 }
72 return;
73} 45}
74 46
75bool call_ata_idle_notifys(bool force) 47bool call_ata_idle_notifys(bool force)
76{ 48{
77 int i;
78 static int lock_until = 0; 49 static int lock_until = 0;
79 ata_idle_notify function; 50
80 if (!force) 51 if (!force)
81 { 52 {
82 if (TIME_BEFORE(current_tick,lock_until) ) 53 if (TIME_BEFORE(current_tick,lock_until) )
@@ -84,22 +55,8 @@ bool call_ata_idle_notifys(bool force)
84 } 55 }
85 lock_until = current_tick + 30*HZ; 56 lock_until = current_tick + 30*HZ;
86 57
87 for (i = 0; i < MAX_ATA_CALLBACKS; i++) 58 send_event(DISK_EVENT_SPINUP, true, NULL);
88 { 59
89 if (ata_idle_notify_funcs[i])
90 {
91 function = ata_idle_notify_funcs[i];
92 ata_idle_notify_funcs[i] = NULL;
93 function();
94 ata_callback_count--;
95 }
96 }
97 return true; 60 return true;
98} 61}
99
100void ata_idle_notify_init(void)
101{
102 ata_callback_count = 0;
103 memset(ata_idle_notify_funcs, 0, sizeof(ata_idle_notify_funcs));
104}
105#endif 62#endif
diff --git a/firmware/events.c b/firmware/events.c
new file mode 100644
index 0000000000..eaf2e5c352
--- /dev/null
+++ b/firmware/events.c
@@ -0,0 +1,88 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Miika Pekkarinen
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <stdio.h>
21#include "events.h"
22#include "panic.h"
23
24struct sysevent {
25 unsigned short id;
26 void (*callback)(void *data);
27};
28
29struct sysevent events[MAX_SYS_EVENTS];
30
31bool add_event(unsigned short id, void (*handler))
32{
33 int i;
34
35 /* Chcek if the event already exists. */
36 for (i = 0; i < MAX_SYS_EVENTS; i++)
37 {
38 if (events[i].callback == handler && events[i].id == id)
39 return false;
40 }
41
42 /* Try to find a free slot. */
43 for (i = 0; i < MAX_SYS_EVENTS; i++)
44 {
45 if (events[i].callback == NULL)
46 {
47 events[i].id = id;
48 events[i].callback = handler;
49 return true;
50 }
51 }
52
53 panicf("event line full");
54 return false;
55}
56
57void remove_event(unsigned short id, void (*handler))
58{
59 int i;
60
61 for (i = 0; i < MAX_SYS_EVENTS; i++)
62 {
63 if (events[i].id == id && events[i].callback == handler)
64 {
65 events[i].callback = NULL;
66 return;
67 }
68 }
69
70 panicf("event not found");
71}
72
73void send_event(unsigned short id, bool oneshot, void *data)
74{
75 int i;
76
77 for (i = 0; i < MAX_SYS_EVENTS; i++)
78 {
79 if (events[i].id == id && events[i].callback != NULL)
80 {
81 events[i].callback(data);
82
83 if (oneshot)
84 events[i].callback = NULL;
85 }
86 }
87}
88
diff --git a/firmware/export/ata_idle_notify.h b/firmware/export/ata_idle_notify.h
index ee825c967e..1dda3e196a 100644
--- a/firmware/export/ata_idle_notify.h
+++ b/firmware/export/ata_idle_notify.h
@@ -19,7 +19,9 @@
19#ifndef __ATACALLBACK_H__ 19#ifndef __ATACALLBACK_H__
20#define __ATACALLBACK_H__ 20#define __ATACALLBACK_H__
21 21
22
22#include <stdbool.h> 23#include <stdbool.h>
24#include "events.h"
23 25
24#if 0 26#if 0
25 NOTE: ata_idle_nofity usage notes.. 27 NOTE: ata_idle_nofity usage notes..
@@ -34,15 +36,17 @@
34 5) Dont Panic! 36 5) Dont Panic!
35#endif 37#endif
36 38
39enum {
40 DISK_EVENT_SPINUP = (EVENT_CLASS_DISK|1),
41};
42
37#define USING_ATA_CALLBACK !defined(SIMULATOR) \ 43#define USING_ATA_CALLBACK !defined(SIMULATOR) \
38 && !defined(HAVE_FLASH_DISK) 44 && !defined(HAVE_FLASH_DISK)
39 45
40#define MAX_ATA_CALLBACKS 5
41typedef bool (*ata_idle_notify)(void); 46typedef bool (*ata_idle_notify)(void);
42 47
43extern bool register_ata_idle_func(ata_idle_notify function); 48extern void register_ata_idle_func(ata_idle_notify function);
44#if USING_ATA_CALLBACK 49#if USING_ATA_CALLBACK
45extern void ata_idle_notify_init(void);
46extern void unregister_ata_idle_func(ata_idle_notify function, bool run); 50extern void unregister_ata_idle_func(ata_idle_notify function, bool run);
47extern bool call_ata_idle_notifys(bool force); 51extern bool call_ata_idle_notifys(bool force);
48#else 52#else
diff --git a/firmware/export/events.h b/firmware/export/events.h
new file mode 100644
index 0000000000..b27b5dee4c
--- /dev/null
+++ b/firmware/export/events.h
@@ -0,0 +1,51 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Miika Pekkarinen
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _EVENTS_H
21#define _EVENTS_H
22
23#include <stdbool.h>
24
25#define MAX_SYS_EVENTS 10
26
27/**
28 * High nibble = Event class definition
29 * Low nibble = Event ID
30 */
31
32#define EVENT_CLASS_DISK 0x0100
33#define EVENT_CLASS_PLAYBACK 0x0200
34
35/**
36 * Because same playback events are used in mpeg.c and playback.c, define
37 * them here to prevent cluttering and ifdefs.
38 */
39enum {
40 PLAYBACK_EVENT_TRACK_BUFFER = (EVENT_CLASS_PLAYBACK|1),
41 PLAYBACK_EVENT_TRACK_FINISH,
42 PLAYBACK_EVENT_TRACK_CHANGE,
43};
44
45
46bool add_event(unsigned short id, void (*handler));
47void remove_event(unsigned short id, void (*handler));
48void send_event(unsigned short id, bool oneshot, void *data);
49
50#endif
51
diff --git a/firmware/export/mpeg.h b/firmware/export/mpeg.h
index 3e36c44ac5..0a9d62cdf0 100644
--- a/firmware/export/mpeg.h
+++ b/firmware/export/mpeg.h
@@ -21,6 +21,7 @@
21 21
22#include <stdbool.h> 22#include <stdbool.h>
23#include "id3.h" 23#include "id3.h"
24#include "events.h"
24 25
25#define MPEG_SWAP_CHUNKSIZE 0x2000 26#define MPEG_SWAP_CHUNKSIZE 0x2000
26#define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we 27#define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 693e2df480..9023c304d2 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -100,7 +100,6 @@ struct trackdata
100 struct mp3entry id3; 100 struct mp3entry id3;
101 int mempos; 101 int mempos;
102 int load_ahead_index; 102 int load_ahead_index;
103 bool event_sent;
104}; 103};
105 104
106static struct trackdata trackdata[MAX_TRACK_ENTRIES]; 105static struct trackdata trackdata[MAX_TRACK_ENTRIES];
@@ -116,11 +115,6 @@ static int track_read_idx = 0;
116static int track_write_idx = 0; 115static int track_write_idx = 0;
117#endif /* !SIMULATOR */ 116#endif /* !SIMULATOR */
118 117
119/* Callback function to call when current track has really changed. */
120void (*track_changed_callback)(struct mp3entry *id3) = NULL;
121void (*track_buffer_callback)(struct mp3entry *id3) = NULL;
122void (*track_unbuffer_callback)(struct mp3entry *id3) = NULL;
123
124/* Cuesheet callback */ 118/* Cuesheet callback */
125static bool (*cuesheet_callback)(const char *filename) = NULL; 119static bool (*cuesheet_callback)(const char *filename) = NULL;
126 120
@@ -475,21 +469,6 @@ unsigned long mpeg_get_last_header(void)
475#endif /* !SIMULATOR */ 469#endif /* !SIMULATOR */
476} 470}
477 471
478void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3))
479{
480 track_buffer_callback = handler;
481}
482
483void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3))
484{
485 track_unbuffer_callback = handler;
486}
487
488void audio_set_track_changed_event(void (*handler)(struct mp3entry *id3))
489{
490 track_changed_callback = handler;
491}
492
493void audio_set_cuesheet_callback(bool (*handler)(const char *filename)) 472void audio_set_cuesheet_callback(bool (*handler)(const char *filename))
494{ 473{
495 cuesheet_callback = handler; 474 cuesheet_callback = handler;
@@ -506,12 +485,7 @@ static void generate_unbuffer_events(void)
506 for (i = 0; i < numentries; i++) 485 for (i = 0; i < numentries; i++)
507 { 486 {
508 /* Send an event to notify that track has finished. */ 487 /* Send an event to notify that track has finished. */
509 if (trackdata[cur_idx].event_sent) 488 send_event(PLAYBACK_EVENT_TRACK_FINISH, false, &trackdata[cur_idx].id3);
510 {
511 if (track_unbuffer_callback)
512 track_unbuffer_callback(&trackdata[cur_idx].id3);
513 trackdata[cur_idx].event_sent = false;
514 }
515 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK; 489 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
516 } 490 }
517} 491}
@@ -525,12 +499,7 @@ static void generate_postbuffer_events(void)
525 499
526 for (i = 0; i < numentries; i++) 500 for (i = 0; i < numentries; i++)
527 { 501 {
528 if (!trackdata[cur_idx].event_sent) 502 send_event(PLAYBACK_EVENT_TRACK_BUFFER, false, &trackdata[cur_idx].id3);
529 {
530 if (track_buffer_callback)
531 track_buffer_callback(&trackdata[cur_idx].id3);
532 trackdata[cur_idx].event_sent = true;
533 }
534 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK; 503 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
535 } 504 }
536} 505}
@@ -1080,8 +1049,7 @@ static void track_change(void)
1080 if (num_tracks_in_memory() > 0) 1049 if (num_tracks_in_memory() > 0)
1081 { 1050 {
1082 remove_current_tag(); 1051 remove_current_tag();
1083 if (track_changed_callback) 1052 send_event(PLAYBACK_EVENT_TRACK_CHANGE, false, audio_current_track());
1084 track_changed_callback(audio_current_track());
1085 update_playlist(); 1053 update_playlist();
1086 } 1054 }
1087 1055
@@ -1134,8 +1102,7 @@ static void start_playback_if_ready(void)
1134 if (play_pending_track_change) 1102 if (play_pending_track_change)
1135 { 1103 {
1136 play_pending_track_change = false; 1104 play_pending_track_change = false;
1137 if(track_changed_callback) 1105 send_event(PLAYBACK_EVENT_TRACK_CHANGE, false, audio_current_track());
1138 track_changed_callback(audio_current_track());
1139 } 1106 }
1140 play_pending = false; 1107 play_pending = false;
1141 } 1108 }