From 98cd3e8868a54541dce9875dfaf04e2695a97c37 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Fri, 9 Mar 2007 12:30:14 +0000 Subject: 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 --- apps/main.c | 21 ++--- apps/playback.c | 278 +++++++++++++++++++++++-------------------------------- apps/talk.c | 6 -- firmware/SOURCES | 2 + 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 -- cgit v1.2.3