summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-03-09 12:30:14 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-03-09 12:30:14 +0000
commit98cd3e8868a54541dce9875dfaf04e2695a97c37 (patch)
tree1bd3c9ead8c83baba4e735f437e8c63dc4391449
parent8e7ab3dfffe3cec8716f0842c0c9dca152402eb7 (diff)
downloadrockbox-98cd3e8868a54541dce9875dfaf04e2695a97c37.tar.gz
rockbox-98cd3e8868a54541dce9875dfaf04e2695a97c37.zip
Install the single stage synchronous audio initialization I cooked up awhile back.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12693 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/main.c21
-rw-r--r--apps/playback.c278
-rw-r--r--apps/talk.c6
-rw-r--r--firmware/SOURCES2
4 files changed, 128 insertions, 179 deletions
diff --git a/apps/main.c b/apps/main.c
index fe397c737c..8ad32446b3 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -244,9 +244,6 @@ static void init(void)
button_init();
backlight_init();
lang_init();
-#if CONFIG_CODEC == SWCODEC
- audio_preinit(); /* Must be done before settings_apply() */
-#endif
/* Must be done before any code uses the multi-screen APi */
screen_access_init();
gui_syncstatusbar_init(&statusbars);
@@ -262,6 +259,8 @@ static void init(void)
sleep(HZ/2);
tree_init();
playlist_init();
+
+#if CONFIG_CODEC != SWCODEC
mp3_init( global_settings.volume,
global_settings.bass,
global_settings.treble,
@@ -277,13 +276,12 @@ static void init(void)
global_settings.mdb_enable,
global_settings.superbass);
- scrobbler_init();
- cuesheet_init();
-
/* audio_init must to know the size of voice buffer so init voice first */
-#if CONFIG_CODEC == SWCODEC
talk_init();
-#endif
+#endif /* CONFIG_CODEC != SWCODEC */
+
+ scrobbler_init();
+ cuesheet_init();
audio_init();
button_clear_queue(); /* Empty the keyboard buffer */
@@ -365,10 +363,6 @@ static void init(void)
powermgmt_init();
-#if CONFIG_CODEC == SWCODEC
- audio_preinit();
-#endif
-
#if CONFIG_TUNER
radio_init();
#endif
@@ -499,6 +493,7 @@ static void init(void)
scrobbler_init();
cuesheet_init();
+#if CONFIG_CODEC != SWCODEC
/* No buffer allocation (see buffer.c) may take place after the call to
audio_init() since the mpeg thread takes the rest of the buffer space */
mp3_init( global_settings.volume,
@@ -518,8 +513,10 @@ static void init(void)
/* audio_init must to know the size of voice buffer so init voice first */
talk_init();
+#endif /* CONFIG_CODEC != SWCODEC */
audio_init();
+
#if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
pcm_rec_init();
#endif
diff --git a/apps/playback.c b/apps/playback.c
index 2873c90772..31ec21afda 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -832,57 +832,11 @@ void audio_set_crossfade(int enable)
audio_play(offset);
}
-void audio_preinit(void)
-{
- logf("playback system pre-init");
-
- filling = false;
- set_current_codec(CODEC_IDX_AUDIO);
- playing = false;
- paused = false;
- audio_codec_loaded = false;
-#ifdef PLAYBACK_VOICE
- voice_is_playing = false;
- voice_thread_start = false;
- voice_codec_loaded = false;
-#endif
- track_changed = false;
- current_fd = -1;
- track_buffer_callback = NULL;
- track_unbuffer_callback = NULL;
- track_changed_callback = NULL;
- track_ridx = 0; /* Just to prevent CUR_TI from being anything random. */
- prev_ti = &tracks[MAX_TRACK-1]; /* And prevent prev_ti being random too */
-
-#ifdef PLAYBACK_VOICE
- mutex_init(&mutex_codecthread);
-#endif
-
- queue_init(&audio_queue, true);
- queue_enable_queue_send(&audio_queue, &audio_queue_sender_list);
- queue_init(&codec_queue, true);
-
- create_thread(audio_thread, audio_stack, sizeof(audio_stack),
- audio_thread_name IF_PRIO(, PRIORITY_BUFFERING)
- IF_COP(, CPU, false));
-}
-
-void audio_init(void)
-{
- LOGFQUEUE("audio > audio Q_AUDIO_POSTINIT");
- queue_post(&audio_queue, Q_AUDIO_POSTINIT, 0);
-}
-
void voice_init(void)
{
#ifdef PLAYBACK_VOICE
- if (!filebuf)
- return; /* Audio buffers not yet set up */
-
- if (voice_thread_p)
- return;
-
- if (!talk_voice_required())
+ if (voice_thread_p || !filebuf || voice_codec_loaded ||
+ !talk_voice_required())
return;
logf("Starting voice codec");
@@ -1283,22 +1237,20 @@ static bool voice_request_next_track_callback(void)
static void voice_thread(void)
{
- while (1)
- {
- logf("Loading voice codec");
- voice_codec_loaded = true;
- mutex_lock(&mutex_codecthread);
- set_current_codec(CODEC_IDX_VOICE);
- dsp_configure(DSP_RESET, 0);
- voice_remaining = 0;
- voice_getmore = NULL;
+ logf("Loading voice codec");
+ voice_codec_loaded = true;
+ mutex_lock(&mutex_codecthread);
+ set_current_codec(CODEC_IDX_VOICE);
+ dsp_configure(DSP_RESET, 0);
+ voice_remaining = 0;
+ voice_getmore = NULL;
- codec_load_file(get_codec_filename(AFMT_MPA_L3), &ci_voice);
+ codec_load_file(get_codec_filename(AFMT_MPA_L3), &ci_voice);
- logf("Voice codec finished");
- voice_codec_loaded = false;
- mutex_unlock(&mutex_codecthread);
- }
+ logf("Voice codec finished");
+ voice_codec_loaded = false;
+ mutex_unlock(&mutex_codecthread);
+ remove_thread(NULL);
} /* voice_thread */
#endif /* PLAYBACK_VOICE */
@@ -3465,103 +3417,6 @@ static void audio_reset_buffer(size_t pcmbufsize)
buffer_state = BUFFER_STATE_NORMAL;
}
-#ifdef ROCKBOX_HAS_LOGF
-static void audio_test_track_changed_event(struct mp3entry *id3)
-{
- (void)id3;
-
- logf("tce:%s", id3->path);
-}
-#endif
-
-static void audio_playback_init(void)
-{
-#ifdef PLAYBACK_VOICE
- static bool voicetagtrue = true;
- static struct mp3entry id3_voice;
-#endif
- struct event ev;
-
- logf("playback api init");
- pcm_init();
-
-#ifdef AUDIO_HAVE_RECORDING
- rec_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
-#endif
-
-#ifdef ROCKBOX_HAS_LOGF
- audio_set_track_changed_event(audio_test_track_changed_event);
-#endif
-
- /* Initialize codec api. */
- ci.read_filebuf = codec_filebuf_callback;
- ci.pcmbuf_insert = codec_pcmbuf_insert_callback;
- ci.get_codec_memory = codec_get_memory_callback;
- ci.request_buffer = codec_request_buffer_callback;
- ci.advance_buffer = codec_advance_buffer_callback;
- ci.advance_buffer_loc = codec_advance_buffer_loc_callback;
- ci.request_next_track = codec_request_next_track_callback;
- ci.mp3_get_filepos = codec_mp3_get_filepos_callback;
- ci.seek_buffer = codec_seek_buffer_callback;
- ci.seek_complete = codec_seek_complete_callback;
- ci.set_elapsed = codec_set_elapsed_callback;
- ci.set_offset = codec_set_offset_callback;
- ci.configure = codec_configure_callback;
- ci.discard_codec = codec_discard_codec_callback;
-
- /* Initialize voice codec api. */
-#ifdef PLAYBACK_VOICE
- memcpy(&ci_voice, &ci, sizeof(struct codec_api));
- memset(&id3_voice, 0, sizeof(struct mp3entry));
- ci_voice.read_filebuf = voice_filebuf_callback;
- ci_voice.pcmbuf_insert = voice_pcmbuf_insert_callback;
- ci_voice.get_codec_memory = voice_get_memory_callback;
- ci_voice.request_buffer = voice_request_buffer_callback;
- ci_voice.advance_buffer = voice_advance_buffer_callback;
- ci_voice.advance_buffer_loc = voice_advance_buffer_loc_callback;
- ci_voice.request_next_track = voice_request_next_track_callback;
- ci_voice.mp3_get_filepos = voice_mp3_get_filepos_callback;
- ci_voice.seek_buffer = voice_seek_buffer_callback;
- ci_voice.seek_complete = voice_do_nothing;
- ci_voice.set_elapsed = voice_set_elapsed_callback;
- ci_voice.set_offset = voice_set_offset_callback;
- ci_voice.discard_codec = voice_do_nothing;
- ci_voice.taginfo_ready = &voicetagtrue;
- ci_voice.id3 = &id3_voice;
- id3_voice.frequency = 11200;
- id3_voice.length = 1000000L;
-#endif
-
- codec_thread_p = create_thread(
- codec_thread, codec_stack, sizeof(codec_stack),
- codec_thread_name IF_PRIO(, PRIORITY_PLAYBACK)
- IF_COP(, COP, true));
-
- while (1)
- {
- queue_wait(&audio_queue, &ev);
- if (ev.id == Q_AUDIO_POSTINIT)
- break ;
-
-#ifndef SIMULATOR
- if (ev.id == SYS_USB_CONNECTED)
- {
- logf("USB: Audio preinit");
- usb_acknowledge(SYS_USB_CONNECTED_ACK);
- usb_wait_for_disconnect(&audio_queue);
- }
-#endif
- }
-
- /* initialize the buffer */
- filebuf = audiobuf; /* must be non-NULL for audio_set_crossfade */
- buffer_state = BUFFER_STATE_TRASHED; /* force it */
- audio_set_crossfade(global_settings.crossfade);
-
- audio_is_initialized = true;
-
- sound_settings_apply();
-}
#if MEM > 8
/* we dont want this rebuffering on targets with little ram
because the disk may never spin down */
@@ -3575,8 +3430,6 @@ static bool ata_fillbuffer_callback(void)
static void audio_thread(void)
{
struct event ev;
- /* At first initialize audio system in background. */
- audio_playback_init();
while (1)
{
@@ -3707,3 +3560,106 @@ static void audio_thread(void)
} /* end while */
}
+#ifdef ROCKBOX_HAS_LOGF
+static void audio_test_track_changed_event(struct mp3entry *id3)
+{
+ (void)id3;
+
+ logf("tce:%s", id3->path);
+}
+#endif
+
+/* Initialize the audio system - called from init() in main.c.
+ * Last function because of all the references to internal symbols
+ */
+void audio_init(void)
+{
+#ifdef PLAYBACK_VOICE
+ static bool voicetagtrue = true;
+ static struct mp3entry id3_voice;
+#endif
+
+ logf("audio: %s", audio_is_initialized ?
+ "initializing" : "already initialized");
+
+ /* Can never do this twice */
+ if (audio_is_initialized)
+ return;
+
+ /* Initialize queues before giving control elsewhere in case it likes
+ to send messages. Thread creation will be delayed however so nothing
+ starts running until ready if something yields such as talk_init. */
+#ifdef PLAYBACK_VOICE
+ mutex_init(&mutex_codecthread);
+#endif
+ queue_init(&audio_queue, true);
+ queue_enable_queue_send(&audio_queue, &audio_queue_sender_list);
+ queue_init(&codec_queue, true);
+
+ pcm_init();
+
+#ifdef ROCKBOX_HAS_LOGF
+ audio_set_track_changed_event(audio_test_track_changed_event);
+#endif
+
+ /* Initialize codec api. */
+ ci.read_filebuf = codec_filebuf_callback;
+ ci.pcmbuf_insert = codec_pcmbuf_insert_callback;
+ ci.get_codec_memory = codec_get_memory_callback;
+ ci.request_buffer = codec_request_buffer_callback;
+ ci.advance_buffer = codec_advance_buffer_callback;
+ ci.advance_buffer_loc = codec_advance_buffer_loc_callback;
+ ci.request_next_track = codec_request_next_track_callback;
+ ci.mp3_get_filepos = codec_mp3_get_filepos_callback;
+ ci.seek_buffer = codec_seek_buffer_callback;
+ ci.seek_complete = codec_seek_complete_callback;
+ ci.set_elapsed = codec_set_elapsed_callback;
+ ci.set_offset = codec_set_offset_callback;
+ ci.configure = codec_configure_callback;
+ ci.discard_codec = codec_discard_codec_callback;
+
+ /* Initialize voice codec api. */
+#ifdef PLAYBACK_VOICE
+ memcpy(&ci_voice, &ci, sizeof(ci_voice));
+ memset(&id3_voice, 0, sizeof(id3_voice));
+ ci_voice.read_filebuf = voice_filebuf_callback;
+ ci_voice.pcmbuf_insert = voice_pcmbuf_insert_callback;
+ ci_voice.get_codec_memory = voice_get_memory_callback;
+ ci_voice.request_buffer = voice_request_buffer_callback;
+ ci_voice.advance_buffer = voice_advance_buffer_callback;
+ ci_voice.advance_buffer_loc = voice_advance_buffer_loc_callback;
+ ci_voice.request_next_track = voice_request_next_track_callback;
+ ci_voice.mp3_get_filepos = voice_mp3_get_filepos_callback;
+ ci_voice.seek_buffer = voice_seek_buffer_callback;
+ ci_voice.seek_complete = voice_do_nothing;
+ ci_voice.set_elapsed = voice_set_elapsed_callback;
+ ci_voice.set_offset = voice_set_offset_callback;
+ ci_voice.discard_codec = voice_do_nothing;
+ ci_voice.taginfo_ready = &voicetagtrue;
+ ci_voice.id3 = &id3_voice;
+ id3_voice.frequency = 11200;
+ id3_voice.length = 1000000L;
+#endif
+
+ /* initialize the buffer */
+ filebuf = audiobuf; /* must be non-NULL for audio_set_crossfade */
+ /* audio_reset_buffer must to know the size of voice buffer so init
+ voice first */
+ talk_init();
+
+ codec_thread_p = create_thread(
+ codec_thread, codec_stack, sizeof(codec_stack),
+ codec_thread_name IF_PRIO(, PRIORITY_PLAYBACK)
+ IF_COP(, COP, true));
+
+ create_thread(audio_thread, audio_stack, sizeof(audio_stack),
+ audio_thread_name IF_PRIO(, PRIORITY_BUFFERING)
+ IF_COP(, CPU, false));
+
+ audio_set_crossfade(global_settings.crossfade);
+
+ audio_is_initialized = true;
+
+ sound_settings_apply();
+ audio_set_buffer_margin(global_settings.buffer_margin);
+} /* audio_init */
diff --git a/apps/talk.c b/apps/talk.c
index 370604f923..f975ca2028 100644
--- a/apps/talk.c
+++ b/apps/talk.c
@@ -182,12 +182,6 @@ static void load_voicefile(void)
load_size = file_size;
#endif
-#ifndef SIMULATOR
- /* Wait until the audio is initialized before continuing */
- while(!audio_is_initialized)
- sleep(HZ/100);
-#endif
-
got_size = read(filehandle, audiobuf, load_size);
if (got_size != load_size /* failure */)
goto load_err;
diff --git a/firmware/SOURCES b/firmware/SOURCES
index ad7d372acc..2d2296a439 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -161,7 +161,9 @@ tuner_philips.c
#endif /* CONFIG_TUNER */
/* Sound */
+#if CONFIG_CODEC != SWCODEC
mp3_playback.c
+#endif /* CONFIG_CODEC != SWCODEC */
mp3data.c
sound.c