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 | |
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
-rw-r--r-- | apps/lang/english.lang | 16 | ||||
-rw-r--r-- | apps/main.c | 2 | ||||
-rw-r--r-- | apps/playback.c | 58 | ||||
-rw-r--r-- | apps/playback.h | 14 | ||||
-rw-r--r-- | apps/scrobbler.c | 17 | ||||
-rw-r--r-- | apps/settings.c | 20 | ||||
-rw-r--r-- | apps/tagtree.c | 11 | ||||
-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 |
14 files changed, 182 insertions, 209 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 3911223d2d..e5df04a460 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -8191,29 +8191,27 @@ | |||
8191 | </phrase> | 8191 | </phrase> |
8192 | <phrase> | 8192 | <phrase> |
8193 | id: LANG_SETTINGS_SAVE_FAILED | 8193 | id: LANG_SETTINGS_SAVE_FAILED |
8194 | desc: displayed if save settings has failed | 8194 | desc: DEPRECATED |
8195 | user: | 8195 | user: |
8196 | <source> | 8196 | <source> |
8197 | *: "Save Failed" | 8197 | *: "" |
8198 | </source> | 8198 | </source> |
8199 | <dest> | 8199 | <dest> |
8200 | *: "Save Failed" | 8200 | *: "" |
8201 | </dest> | 8201 | </dest> |
8202 | <voice> | 8202 | <voice> |
8203 | *: "Save Failed" | 8203 | *: "" |
8204 | </voice> | 8204 | </voice> |
8205 | </phrase> | 8205 | </phrase> |
8206 | <phrase> | 8206 | <phrase> |
8207 | id: LANG_SETTINGS_PARTITION | 8207 | id: LANG_SETTINGS_PARTITION |
8208 | desc: if save settings has failed | 8208 | desc: DEPRECATED |
8209 | user: | 8209 | user: |
8210 | <source> | 8210 | <source> |
8211 | *: "No partition?" | 8211 | *: "" |
8212 | player: "Partition?" | ||
8213 | </source> | 8212 | </source> |
8214 | <dest> | 8213 | <dest> |
8215 | *: "No partition?" | 8214 | *: "" |
8216 | player: "Partition?" | ||
8217 | </dest> | 8215 | </dest> |
8218 | <voice> | 8216 | <voice> |
8219 | *: "" | 8217 | *: "" |
diff --git a/apps/main.c b/apps/main.c index 598597520f..5dd92e5e02 100644 --- a/apps/main.c +++ b/apps/main.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include "config.h" | 19 | #include "config.h" |
20 | 20 | ||
21 | #include "ata.h" | 21 | #include "ata.h" |
22 | #include "ata_idle_notify.h" | ||
23 | #include "disk.h" | 22 | #include "disk.h" |
24 | #include "fat.h" | 23 | #include "fat.h" |
25 | #include "lcd.h" | 24 | #include "lcd.h" |
@@ -428,7 +427,6 @@ static void init(void) | |||
428 | } | 427 | } |
429 | #endif | 428 | #endif |
430 | 429 | ||
431 | ata_idle_notify_init(); | ||
432 | rc = ata_init(); | 430 | rc = ata_init(); |
433 | if(rc) | 431 | if(rc) |
434 | { | 432 | { |
diff --git a/apps/playback.c b/apps/playback.c index b36f68f135..ee1787e612 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -245,13 +245,6 @@ static bool skipped_during_pause = false; /* Do we need to clear the PCM buffer | |||
245 | */ | 245 | */ |
246 | static bool codec_requested_stop = false; | 246 | static bool codec_requested_stop = false; |
247 | 247 | ||
248 | struct playback_event { | ||
249 | enum PLAYBACK_EVENT_TYPE type; | ||
250 | void (*callback)(void *data); | ||
251 | }; | ||
252 | |||
253 | struct playback_event events[PLAYBACK_MAX_EVENTS]; | ||
254 | |||
255 | static size_t buffer_margin = 0; /* Buffer margin aka anti-skip buffer (A/C-) */ | 248 | static size_t buffer_margin = 0; /* Buffer margin aka anti-skip buffer (A/C-) */ |
256 | 249 | ||
257 | /* Multiple threads */ | 250 | /* Multiple threads */ |
@@ -1447,51 +1440,6 @@ static void codec_thread(void) | |||
1447 | 1440 | ||
1448 | /* --- Audio thread --- */ | 1441 | /* --- Audio thread --- */ |
1449 | 1442 | ||
1450 | void playback_add_event(enum PLAYBACK_EVENT_TYPE type, void (*handler)) | ||
1451 | { | ||
1452 | int i; | ||
1453 | |||
1454 | /* Try to find a free slot. */ | ||
1455 | for (i = 0; i < PLAYBACK_MAX_EVENTS; i++) | ||
1456 | { | ||
1457 | if (events[i].callback == NULL) | ||
1458 | { | ||
1459 | events[i].type = type; | ||
1460 | events[i].callback = handler; | ||
1461 | return; | ||
1462 | } | ||
1463 | } | ||
1464 | |||
1465 | panicf("playback event line full"); | ||
1466 | } | ||
1467 | |||
1468 | void playback_remove_event(enum PLAYBACK_EVENT_TYPE type, void (*handler)) | ||
1469 | { | ||
1470 | int i; | ||
1471 | |||
1472 | for (i = 0; i < PLAYBACK_MAX_EVENTS; i++) | ||
1473 | { | ||
1474 | if (events[i].type == type && events[i].callback == handler) | ||
1475 | { | ||
1476 | events[i].callback = NULL; | ||
1477 | return; | ||
1478 | } | ||
1479 | } | ||
1480 | |||
1481 | panicf("playback event not found"); | ||
1482 | } | ||
1483 | |||
1484 | static void send_event(enum PLAYBACK_EVENT_TYPE type, void *data) | ||
1485 | { | ||
1486 | int i; | ||
1487 | |||
1488 | for (i = 0; i < PLAYBACK_MAX_EVENTS; i++) | ||
1489 | { | ||
1490 | if (events[i].type == type && events[i].callback != NULL) | ||
1491 | events[i].callback(data); | ||
1492 | } | ||
1493 | } | ||
1494 | |||
1495 | static bool audio_have_tracks(void) | 1443 | static bool audio_have_tracks(void) |
1496 | { | 1444 | { |
1497 | return (audio_track_count() != 0); | 1445 | return (audio_track_count() != 0); |
@@ -1783,7 +1731,7 @@ static bool audio_load_track(int offset, bool start_play) | |||
1783 | { | 1731 | { |
1784 | if (get_metadata(&id3, fd, trackname)) | 1732 | if (get_metadata(&id3, fd, trackname)) |
1785 | { | 1733 | { |
1786 | send_event(PLAYBACK_EVENT_TRACK_BUFFER, &id3); | 1734 | send_event(PLAYBACK_EVENT_TRACK_BUFFER, false, &id3); |
1787 | 1735 | ||
1788 | tracks[track_widx].id3_hid = | 1736 | tracks[track_widx].id3_hid = |
1789 | bufalloc(&id3, sizeof(struct mp3entry), TYPE_ID3); | 1737 | bufalloc(&id3, sizeof(struct mp3entry), TYPE_ID3); |
@@ -2020,7 +1968,7 @@ static int audio_check_new_track(void) | |||
2020 | bool end_of_playlist; /* Temporary flag, not the same as playlist_end */ | 1968 | bool end_of_playlist; /* Temporary flag, not the same as playlist_end */ |
2021 | 1969 | ||
2022 | /* Now it's good time to send track unbuffer events. */ | 1970 | /* Now it's good time to send track unbuffer events. */ |
2023 | send_event(PLAYBACK_EVENT_TRACK_FINISH, &curtrack_id3); | 1971 | send_event(PLAYBACK_EVENT_TRACK_FINISH, false, &curtrack_id3); |
2024 | 1972 | ||
2025 | if (dir_skip) | 1973 | if (dir_skip) |
2026 | { | 1974 | { |
@@ -2391,7 +2339,7 @@ static void audio_finalise_track_change(void) | |||
2391 | bufgetid3(prev_ti->id3_hid)->elapsed = 0; | 2339 | bufgetid3(prev_ti->id3_hid)->elapsed = 0; |
2392 | } | 2340 | } |
2393 | 2341 | ||
2394 | send_event(PLAYBACK_EVENT_TRACK_CHANGE, &curtrack_id3); | 2342 | send_event(PLAYBACK_EVENT_TRACK_CHANGE, false, &curtrack_id3); |
2395 | 2343 | ||
2396 | track_changed = true; | 2344 | track_changed = true; |
2397 | playlist_update_resume_info(audio_current_track()); | 2345 | playlist_update_resume_info(audio_current_track()); |
diff --git a/apps/playback.h b/apps/playback.h index 14ba35cea4..0b78eb3bcb 100644 --- a/apps/playback.h +++ b/apps/playback.h | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include "id3.h" | 25 | #include "id3.h" |
26 | #include "mp3data.h" | 26 | #include "mp3data.h" |
27 | #include "events.h" | ||
27 | 28 | ||
28 | #define CODEC_IDX_AUDIO 0 | 29 | #define CODEC_IDX_AUDIO 0 |
29 | #define CODEC_IDX_VOICE 1 | 30 | #define CODEC_IDX_VOICE 1 |
@@ -39,13 +40,6 @@ | |||
39 | 40 | ||
40 | #define MAX_TRACK_MASK (MAX_TRACK-1) | 41 | #define MAX_TRACK_MASK (MAX_TRACK-1) |
41 | 42 | ||
42 | #define PLAYBACK_MAX_EVENTS 4 | ||
43 | enum PLAYBACK_EVENT_TYPE { | ||
44 | PLAYBACK_EVENT_TRACK_BUFFER, | ||
45 | PLAYBACK_EVENT_TRACK_FINISH, | ||
46 | PLAYBACK_EVENT_TRACK_CHANGE, | ||
47 | }; | ||
48 | |||
49 | /* Functions */ | 43 | /* Functions */ |
50 | const char * get_codec_filename(int cod_spec); | 44 | const char * get_codec_filename(int cod_spec); |
51 | void voice_wait(void); | 45 | void voice_wait(void); |
@@ -53,13 +47,7 @@ void voice_wait(void); | |||
53 | #if CONFIG_CODEC == SWCODEC /* This #ifdef is better here than gui/gwps.c */ | 47 | #if CONFIG_CODEC == SWCODEC /* This #ifdef is better here than gui/gwps.c */ |
54 | extern void audio_next_dir(void); | 48 | extern void audio_next_dir(void); |
55 | extern void audio_prev_dir(void); | 49 | extern void audio_prev_dir(void); |
56 | void playback_add_event(enum PLAYBACK_EVENT_TYPE type, void (*handler)); | ||
57 | void playback_remove_event(enum PLAYBACK_EVENT_TYPE type, void (*handler)); | ||
58 | #else | 50 | #else |
59 | /* Really, should get rid of these HWCODEC api definitions here. */ | ||
60 | void audio_set_track_changed_event(void (*handler)(struct mp3entry *id3)); | ||
61 | void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3)); | ||
62 | void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3)); | ||
63 | # define audio_next_dir() | 51 | # define audio_next_dir() |
64 | #define audio_prev_dir() | 52 | #define audio_prev_dir() |
65 | #endif | 53 | #endif |
diff --git a/apps/scrobbler.c b/apps/scrobbler.c index 16869bf18f..2f60e858e1 100644 --- a/apps/scrobbler.c +++ b/apps/scrobbler.c | |||
@@ -183,7 +183,10 @@ static void add_to_cache(unsigned long play_length) | |||
183 | } else { | 183 | } else { |
184 | cache_pos++; | 184 | cache_pos++; |
185 | if (!scrobbler_ata_callback) | 185 | if (!scrobbler_ata_callback) |
186 | scrobbler_ata_callback = register_ata_idle_func(scrobbler_flush_callback); | 186 | { |
187 | register_ata_idle_func(scrobbler_flush_callback); | ||
188 | scrobbler_ata_callback = true; | ||
189 | } | ||
187 | } | 190 | } |
188 | 191 | ||
189 | } | 192 | } |
@@ -224,11 +227,7 @@ int scrobbler_init(void) | |||
224 | 227 | ||
225 | scrobbler_cache = buffer_alloc(SCROBBLER_MAX_CACHE*SCROBBLER_CACHE_LEN); | 228 | scrobbler_cache = buffer_alloc(SCROBBLER_MAX_CACHE*SCROBBLER_CACHE_LEN); |
226 | 229 | ||
227 | #if CONFIG_CODEC == SWCODEC | 230 | add_event(PLAYBACK_EVENT_TRACK_CHANGE, scrobbler_change_event); |
228 | playback_add_event(PLAYBACK_EVENT_TRACK_CHANGE, scrobbler_change_event); | ||
229 | #else | ||
230 | audio_set_track_changed_event(&scrobbler_change_event); | ||
231 | #endif | ||
232 | cache_pos = 0; | 231 | cache_pos = 0; |
233 | pending = false; | 232 | pending = false; |
234 | scrobbler_initialised = true; | 233 | scrobbler_initialised = true; |
@@ -263,11 +262,7 @@ void scrobbler_shutdown(void) | |||
263 | 262 | ||
264 | if (scrobbler_initialised) | 263 | if (scrobbler_initialised) |
265 | { | 264 | { |
266 | #if CONFIG_CODEC == SWCODEC | 265 | remove_event(PLAYBACK_EVENT_TRACK_CHANGE, scrobbler_change_event); |
267 | playback_remove_event(PLAYBACK_EVENT_TRACK_CHANGE, scrobbler_change_event); | ||
268 | #else | ||
269 | audio_set_track_changed_event(NULL); | ||
270 | #endif | ||
271 | scrobbler_initialised = false; | 266 | scrobbler_initialised = false; |
272 | } | 267 | } |
273 | } | 268 | } |
diff --git a/apps/settings.c b/apps/settings.c index 27832b427f..7eec15baf3 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -601,25 +601,7 @@ int settings_save( void ) | |||
601 | target doesnt have rtc ram */ | 601 | target doesnt have rtc ram */ |
602 | write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE); | 602 | write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE); |
603 | #endif | 603 | #endif |
604 | if(!register_ata_idle_func(flush_config_block_callback)) | 604 | register_ata_idle_func(flush_config_block_callback); |
605 | { | ||
606 | int i; | ||
607 | FOR_NB_SCREENS(i) | ||
608 | { | ||
609 | screens[i].clear_display(); | ||
610 | #ifdef HAVE_LCD_CHARCELLS | ||
611 | screens[i].puts(0, 0, str(LANG_SETTINGS_SAVE_FAILED)); | ||
612 | screens[i].puts(0, 1, str(LANG_SETTINGS_PARTITION)); | ||
613 | #else | ||
614 | screens[i].puts(4, 2, str(LANG_SETTINGS_SAVE_FAILED)); | ||
615 | screens[i].puts(2, 4, str(LANG_SETTINGS_PARTITION)); | ||
616 | screens[i].update(); | ||
617 | #endif | ||
618 | } | ||
619 | cond_talk_ids_fq(LANG_SETTINGS_SAVE_FAILED); | ||
620 | sleep(HZ*2); | ||
621 | return -1; | ||
622 | } | ||
623 | return 0; | 605 | return 0; |
624 | } | 606 | } |
625 | bool settings_save_config(int options) | 607 | bool settings_save_config(int options) |
diff --git a/apps/tagtree.c b/apps/tagtree.c index c5e3ebff1e..4572204ae5 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c | |||
@@ -924,14 +924,9 @@ void tagtree_init(void) | |||
924 | root_menu = 0; | 924 | root_menu = 0; |
925 | 925 | ||
926 | uniqbuf = buffer_alloc(UNIQBUF_SIZE); | 926 | uniqbuf = buffer_alloc(UNIQBUF_SIZE); |
927 | #if CONFIG_CODEC == SWCODEC | 927 | |
928 | playback_add_event(PLAYBACK_EVENT_TRACK_BUFFER, tagtree_buffer_event); | 928 | add_event(PLAYBACK_EVENT_TRACK_BUFFER, tagtree_buffer_event); |
929 | playback_add_event(PLAYBACK_EVENT_TRACK_FINISH, tagtree_track_finish_event); | 929 | add_event(PLAYBACK_EVENT_TRACK_FINISH, tagtree_track_finish_event); |
930 | #else | ||
931 | audio_set_track_buffer_event(tagtree_buffer_event); | ||
932 | audio_set_track_unbuffer_event(tagtree_track_finish_event); | ||
933 | #endif | ||
934 | |||
935 | } | 930 | } |
936 | 931 | ||
937 | static bool show_search_progress(bool init, int count) | 932 | static bool show_search_progress(bool init, int count) |
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 | } |