diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2008-03-16 13:55:16 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2008-03-16 13:55:16 +0000 |
commit | 19c6e66c1353993659ee007a6c1792a6b0b7ba13 (patch) | |
tree | 1dd7f88282b2e543fb5b22458fcb2f3bf1c7eb80 /firmware | |
parent | 478ba0afa11061a620e44cd9cc60debd955b1b33 (diff) | |
download | rockbox-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/SOURCES | 1 | ||||
-rw-r--r-- | firmware/ata_idle_notify.c | 61 | ||||
-rw-r--r-- | firmware/events.c | 88 | ||||
-rw-r--r-- | firmware/export/ata_idle_notify.h | 10 | ||||
-rw-r--r-- | firmware/export/events.h | 51 | ||||
-rw-r--r-- | firmware/export/mpeg.h | 1 | ||||
-rw-r--r-- | firmware/mpeg.c | 41 |
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 @@ | |||
1 | ata_idle_notify.c | 1 | ata_idle_notify.c |
2 | events.c | ||
2 | backlight.c | 3 | backlight.c |
3 | buffer.c | 4 | buffer.c |
4 | id3.c | 5 | id3.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 | 26 | void register_ata_idle_func(ata_idle_notify function) |
27 | static ata_idle_notify ata_idle_notify_funcs[MAX_ATA_CALLBACKS]; | ||
28 | static int ata_callback_count = 0; | ||
29 | #endif | ||
30 | |||
31 | |||
32 | bool 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 |
60 | void unregister_ata_idle_func(ata_idle_notify func, bool run) | 39 | void 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 | ||
75 | bool call_ata_idle_notifys(bool force) | 47 | bool 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 | |||
100 | void 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 | |||
24 | struct sysevent { | ||
25 | unsigned short id; | ||
26 | void (*callback)(void *data); | ||
27 | }; | ||
28 | |||
29 | struct sysevent events[MAX_SYS_EVENTS]; | ||
30 | |||
31 | bool 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 | |||
57 | void 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 | |||
73 | void 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 | ||
39 | enum { | ||
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 | ||
41 | typedef bool (*ata_idle_notify)(void); | 46 | typedef bool (*ata_idle_notify)(void); |
42 | 47 | ||
43 | extern bool register_ata_idle_func(ata_idle_notify function); | 48 | extern void register_ata_idle_func(ata_idle_notify function); |
44 | #if USING_ATA_CALLBACK | 49 | #if USING_ATA_CALLBACK |
45 | extern void ata_idle_notify_init(void); | ||
46 | extern void unregister_ata_idle_func(ata_idle_notify function, bool run); | 50 | extern void unregister_ata_idle_func(ata_idle_notify function, bool run); |
47 | extern bool call_ata_idle_notifys(bool force); | 51 | extern 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 | */ | ||
39 | enum { | ||
40 | PLAYBACK_EVENT_TRACK_BUFFER = (EVENT_CLASS_PLAYBACK|1), | ||
41 | PLAYBACK_EVENT_TRACK_FINISH, | ||
42 | PLAYBACK_EVENT_TRACK_CHANGE, | ||
43 | }; | ||
44 | |||
45 | |||
46 | bool add_event(unsigned short id, void (*handler)); | ||
47 | void remove_event(unsigned short id, void (*handler)); | ||
48 | void 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 | ||
106 | static struct trackdata trackdata[MAX_TRACK_ENTRIES]; | 105 | static struct trackdata trackdata[MAX_TRACK_ENTRIES]; |
@@ -116,11 +115,6 @@ static int track_read_idx = 0; | |||
116 | static int track_write_idx = 0; | 115 | static int track_write_idx = 0; |
117 | #endif /* !SIMULATOR */ | 116 | #endif /* !SIMULATOR */ |
118 | 117 | ||
119 | /* Callback function to call when current track has really changed. */ | ||
120 | void (*track_changed_callback)(struct mp3entry *id3) = NULL; | ||
121 | void (*track_buffer_callback)(struct mp3entry *id3) = NULL; | ||
122 | void (*track_unbuffer_callback)(struct mp3entry *id3) = NULL; | ||
123 | |||
124 | /* Cuesheet callback */ | 118 | /* Cuesheet callback */ |
125 | static bool (*cuesheet_callback)(const char *filename) = NULL; | 119 | static 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 | ||
478 | void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3)) | ||
479 | { | ||
480 | track_buffer_callback = handler; | ||
481 | } | ||
482 | |||
483 | void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3)) | ||
484 | { | ||
485 | track_unbuffer_callback = handler; | ||
486 | } | ||
487 | |||
488 | void audio_set_track_changed_event(void (*handler)(struct mp3entry *id3)) | ||
489 | { | ||
490 | track_changed_callback = handler; | ||
491 | } | ||
492 | |||
493 | void audio_set_cuesheet_callback(bool (*handler)(const char *filename)) | 472 | void 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 | } |