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 @@
id: LANG_SETTINGS_SAVE_FAILED
- desc: displayed if save settings has failed
+ desc: DEPRECATED
user:
- *: "Save Failed"
+ *: ""
- *: "Save Failed"
+ *: ""
id: LANG_SETTINGS_PARTITION
- desc: if save settings has failed
+ desc: DEPRECATED
user:
- *: "No partition?"
- player: "Partition?"
+ *: ""
*: ""
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 @@
#include "config.h"
#include "ata.h"
-#include "ata_idle_notify.h"
#include "disk.h"
#include "fat.h"
#include "lcd.h"
@@ -428,7 +427,6 @@ static void init(void)
}
#endif
- ata_idle_notify_init();
rc = ata_init();
if(rc)
{
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
*/
static bool codec_requested_stop = false;
-struct playback_event {
- enum PLAYBACK_EVENT_TYPE type;
- void (*callback)(void *data);
-};
-
-struct playback_event events[PLAYBACK_MAX_EVENTS];
-
static size_t buffer_margin = 0; /* Buffer margin aka anti-skip buffer (A/C-) */
/* Multiple threads */
@@ -1447,51 +1440,6 @@ static void codec_thread(void)
/* --- Audio thread --- */
-void playback_add_event(enum PLAYBACK_EVENT_TYPE type, void (*handler))
-{
- int i;
-
- /* Try to find a free slot. */
- for (i = 0; i < PLAYBACK_MAX_EVENTS; i++)
- {
- if (events[i].callback == NULL)
- {
- events[i].type = type;
- events[i].callback = handler;
- return;
- }
- }
-
- panicf("playback event line full");
-}
-
-void playback_remove_event(enum PLAYBACK_EVENT_TYPE type, void (*handler))
-{
- int i;
-
- for (i = 0; i < PLAYBACK_MAX_EVENTS; i++)
- {
- if (events[i].type == type && events[i].callback == handler)
- {
- events[i].callback = NULL;
- return;
- }
- }
-
- panicf("playback event not found");
-}
-
-static void send_event(enum PLAYBACK_EVENT_TYPE type, void *data)
-{
- int i;
-
- for (i = 0; i < PLAYBACK_MAX_EVENTS; i++)
- {
- if (events[i].type == type && events[i].callback != NULL)
- events[i].callback(data);
- }
-}
-
static bool audio_have_tracks(void)
{
return (audio_track_count() != 0);
@@ -1783,7 +1731,7 @@ static bool audio_load_track(int offset, bool start_play)
{
if (get_metadata(&id3, fd, trackname))
{
- send_event(PLAYBACK_EVENT_TRACK_BUFFER, &id3);
+ send_event(PLAYBACK_EVENT_TRACK_BUFFER, false, &id3);
tracks[track_widx].id3_hid =
bufalloc(&id3, sizeof(struct mp3entry), TYPE_ID3);
@@ -2020,7 +1968,7 @@ static int audio_check_new_track(void)
bool end_of_playlist; /* Temporary flag, not the same as playlist_end */
/* Now it's good time to send track unbuffer events. */
- send_event(PLAYBACK_EVENT_TRACK_FINISH, &curtrack_id3);
+ send_event(PLAYBACK_EVENT_TRACK_FINISH, false, &curtrack_id3);
if (dir_skip)
{
@@ -2391,7 +2339,7 @@ static void audio_finalise_track_change(void)
bufgetid3(prev_ti->id3_hid)->elapsed = 0;
}
- send_event(PLAYBACK_EVENT_TRACK_CHANGE, &curtrack_id3);
+ send_event(PLAYBACK_EVENT_TRACK_CHANGE, false, &curtrack_id3);
track_changed = true;
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 @@
#include "id3.h"
#include "mp3data.h"
+#include "events.h"
#define CODEC_IDX_AUDIO 0
#define CODEC_IDX_VOICE 1
@@ -39,13 +40,6 @@
#define MAX_TRACK_MASK (MAX_TRACK-1)
-#define PLAYBACK_MAX_EVENTS 4
-enum PLAYBACK_EVENT_TYPE {
- PLAYBACK_EVENT_TRACK_BUFFER,
- PLAYBACK_EVENT_TRACK_FINISH,
- PLAYBACK_EVENT_TRACK_CHANGE,
-};
-
/* Functions */
const char * get_codec_filename(int cod_spec);
void voice_wait(void);
@@ -53,13 +47,7 @@ void voice_wait(void);
#if CONFIG_CODEC == SWCODEC /* This #ifdef is better here than gui/gwps.c */
extern void audio_next_dir(void);
extern void audio_prev_dir(void);
-void playback_add_event(enum PLAYBACK_EVENT_TYPE type, void (*handler));
-void playback_remove_event(enum PLAYBACK_EVENT_TYPE type, void (*handler));
#else
-/* Really, should get rid of these HWCODEC api definitions here. */
-void audio_set_track_changed_event(void (*handler)(struct mp3entry *id3));
-void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3));
-void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3));
# define audio_next_dir()
#define audio_prev_dir()
#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)
} else {
cache_pos++;
if (!scrobbler_ata_callback)
- scrobbler_ata_callback = register_ata_idle_func(scrobbler_flush_callback);
+ {
+ register_ata_idle_func(scrobbler_flush_callback);
+ scrobbler_ata_callback = true;
+ }
}
}
@@ -224,11 +227,7 @@ int scrobbler_init(void)
scrobbler_cache = buffer_alloc(SCROBBLER_MAX_CACHE*SCROBBLER_CACHE_LEN);
-#if CONFIG_CODEC == SWCODEC
- playback_add_event(PLAYBACK_EVENT_TRACK_CHANGE, scrobbler_change_event);
-#else
- audio_set_track_changed_event(&scrobbler_change_event);
-#endif
+ add_event(PLAYBACK_EVENT_TRACK_CHANGE, scrobbler_change_event);
cache_pos = 0;
pending = false;
scrobbler_initialised = true;
@@ -263,11 +262,7 @@ void scrobbler_shutdown(void)
if (scrobbler_initialised)
{
-#if CONFIG_CODEC == SWCODEC
- playback_remove_event(PLAYBACK_EVENT_TRACK_CHANGE, scrobbler_change_event);
-#else
- audio_set_track_changed_event(NULL);
-#endif
+ remove_event(PLAYBACK_EVENT_TRACK_CHANGE, scrobbler_change_event);
scrobbler_initialised = false;
}
}
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 )
target doesnt have rtc ram */
write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
#endif
- if(!register_ata_idle_func(flush_config_block_callback))
- {
- int i;
- FOR_NB_SCREENS(i)
- {
- screens[i].clear_display();
-#ifdef HAVE_LCD_CHARCELLS
- screens[i].puts(0, 0, str(LANG_SETTINGS_SAVE_FAILED));
- screens[i].puts(0, 1, str(LANG_SETTINGS_PARTITION));
-#else
- screens[i].puts(4, 2, str(LANG_SETTINGS_SAVE_FAILED));
- screens[i].puts(2, 4, str(LANG_SETTINGS_PARTITION));
- screens[i].update();
-#endif
- }
- cond_talk_ids_fq(LANG_SETTINGS_SAVE_FAILED);
- sleep(HZ*2);
- return -1;
- }
+ register_ata_idle_func(flush_config_block_callback);
return 0;
}
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)
root_menu = 0;
uniqbuf = buffer_alloc(UNIQBUF_SIZE);
-#if CONFIG_CODEC == SWCODEC
- playback_add_event(PLAYBACK_EVENT_TRACK_BUFFER, tagtree_buffer_event);
- playback_add_event(PLAYBACK_EVENT_TRACK_FINISH, tagtree_track_finish_event);
-#else
- audio_set_track_buffer_event(tagtree_buffer_event);
- audio_set_track_unbuffer_event(tagtree_track_finish_event);
-#endif
-
+
+ add_event(PLAYBACK_EVENT_TRACK_BUFFER, tagtree_buffer_event);
+ add_event(PLAYBACK_EVENT_TRACK_FINISH, tagtree_track_finish_event);
}
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 @@
ata_idle_notify.c
+events.c
backlight.c
buffer.c
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 @@
#include "kernel.h"
#include "string.h"
-#if USING_ATA_CALLBACK
-static ata_idle_notify ata_idle_notify_funcs[MAX_ATA_CALLBACKS];
-static int ata_callback_count = 0;
-#endif
-
-
-bool register_ata_idle_func(ata_idle_notify function)
+void register_ata_idle_func(ata_idle_notify function)
{
#if USING_ATA_CALLBACK
- int i;
- if (ata_callback_count >= MAX_ATA_CALLBACKS)
- return false;
- for (i=0; i ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Miika Pekkarinen
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include
+#include "events.h"
+#include "panic.h"
+
+struct sysevent {
+ unsigned short id;
+ void (*callback)(void *data);
+};
+
+struct sysevent events[MAX_SYS_EVENTS];
+
+bool add_event(unsigned short id, void (*handler))
+{
+ int i;
+
+ /* Chcek if the event already exists. */
+ for (i = 0; i < MAX_SYS_EVENTS; i++)
+ {
+ if (events[i].callback == handler && events[i].id == id)
+ return false;
+ }
+
+ /* Try to find a free slot. */
+ for (i = 0; i < MAX_SYS_EVENTS; i++)
+ {
+ if (events[i].callback == NULL)
+ {
+ events[i].id = id;
+ events[i].callback = handler;
+ return true;
+ }
+ }
+
+ panicf("event line full");
+ return false;
+}
+
+void remove_event(unsigned short id, void (*handler))
+{
+ int i;
+
+ for (i = 0; i < MAX_SYS_EVENTS; i++)
+ {
+ if (events[i].id == id && events[i].callback == handler)
+ {
+ events[i].callback = NULL;
+ return;
+ }
+ }
+
+ panicf("event not found");
+}
+
+void send_event(unsigned short id, bool oneshot, void *data)
+{
+ int i;
+
+ for (i = 0; i < MAX_SYS_EVENTS; i++)
+ {
+ if (events[i].id == id && events[i].callback != NULL)
+ {
+ events[i].callback(data);
+
+ if (oneshot)
+ events[i].callback = NULL;
+ }
+ }
+}
+
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 @@
#ifndef __ATACALLBACK_H__
#define __ATACALLBACK_H__
+
#include
+#include "events.h"
#if 0
NOTE: ata_idle_nofity usage notes..
@@ -34,15 +36,17 @@
5) Dont Panic!
#endif
+enum {
+ DISK_EVENT_SPINUP = (EVENT_CLASS_DISK|1),
+};
+
#define USING_ATA_CALLBACK !defined(SIMULATOR) \
&& !defined(HAVE_FLASH_DISK)
-#define MAX_ATA_CALLBACKS 5
typedef bool (*ata_idle_notify)(void);
-extern bool register_ata_idle_func(ata_idle_notify function);
+extern void register_ata_idle_func(ata_idle_notify function);
#if USING_ATA_CALLBACK
-extern void ata_idle_notify_init(void);
extern void unregister_ata_idle_func(ata_idle_notify function, bool run);
extern bool call_ata_idle_notifys(bool force);
#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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Miika Pekkarinen
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _EVENTS_H
+#define _EVENTS_H
+
+#include
+
+#define MAX_SYS_EVENTS 10
+
+/**
+ * High nibble = Event class definition
+ * Low nibble = Event ID
+ */
+
+#define EVENT_CLASS_DISK 0x0100
+#define EVENT_CLASS_PLAYBACK 0x0200
+
+/**
+ * Because same playback events are used in mpeg.c and playback.c, define
+ * them here to prevent cluttering and ifdefs.
+ */
+enum {
+ PLAYBACK_EVENT_TRACK_BUFFER = (EVENT_CLASS_PLAYBACK|1),
+ PLAYBACK_EVENT_TRACK_FINISH,
+ PLAYBACK_EVENT_TRACK_CHANGE,
+};
+
+
+bool add_event(unsigned short id, void (*handler));
+void remove_event(unsigned short id, void (*handler));
+void send_event(unsigned short id, bool oneshot, void *data);
+
+#endif
+
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 @@
#include
#include "id3.h"
+#include "events.h"
#define MPEG_SWAP_CHUNKSIZE 0x2000
#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
struct mp3entry id3;
int mempos;
int load_ahead_index;
- bool event_sent;
};
static struct trackdata trackdata[MAX_TRACK_ENTRIES];
@@ -116,11 +115,6 @@ static int track_read_idx = 0;
static int track_write_idx = 0;
#endif /* !SIMULATOR */
-/* Callback function to call when current track has really changed. */
-void (*track_changed_callback)(struct mp3entry *id3) = NULL;
-void (*track_buffer_callback)(struct mp3entry *id3) = NULL;
-void (*track_unbuffer_callback)(struct mp3entry *id3) = NULL;
-
/* Cuesheet callback */
static bool (*cuesheet_callback)(const char *filename) = NULL;
@@ -475,21 +469,6 @@ unsigned long mpeg_get_last_header(void)
#endif /* !SIMULATOR */
}
-void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3))
-{
- track_buffer_callback = handler;
-}
-
-void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3))
-{
- track_unbuffer_callback = handler;
-}
-
-void audio_set_track_changed_event(void (*handler)(struct mp3entry *id3))
-{
- track_changed_callback = handler;
-}
-
void audio_set_cuesheet_callback(bool (*handler)(const char *filename))
{
cuesheet_callback = handler;
@@ -506,12 +485,7 @@ static void generate_unbuffer_events(void)
for (i = 0; i < numentries; i++)
{
/* Send an event to notify that track has finished. */
- if (trackdata[cur_idx].event_sent)
- {
- if (track_unbuffer_callback)
- track_unbuffer_callback(&trackdata[cur_idx].id3);
- trackdata[cur_idx].event_sent = false;
- }
+ send_event(PLAYBACK_EVENT_TRACK_FINISH, false, &trackdata[cur_idx].id3);
cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
}
}
@@ -525,12 +499,7 @@ static void generate_postbuffer_events(void)
for (i = 0; i < numentries; i++)
{
- if (!trackdata[cur_idx].event_sent)
- {
- if (track_buffer_callback)
- track_buffer_callback(&trackdata[cur_idx].id3);
- trackdata[cur_idx].event_sent = true;
- }
+ send_event(PLAYBACK_EVENT_TRACK_BUFFER, false, &trackdata[cur_idx].id3);
cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
}
}
@@ -1080,8 +1049,7 @@ static void track_change(void)
if (num_tracks_in_memory() > 0)
{
remove_current_tag();
- if (track_changed_callback)
- track_changed_callback(audio_current_track());
+ send_event(PLAYBACK_EVENT_TRACK_CHANGE, false, audio_current_track());
update_playlist();
}
@@ -1134,8 +1102,7 @@ static void start_playback_if_ready(void)
if (play_pending_track_change)
{
play_pending_track_change = false;
- if(track_changed_callback)
- track_changed_callback(audio_current_track());
+ send_event(PLAYBACK_EVENT_TRACK_CHANGE, false, audio_current_track());
}
play_pending = false;
}