summaryrefslogtreecommitdiff
path: root/apps/playback.c
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 /apps/playback.c
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
Diffstat (limited to 'apps/playback.c')
-rw-r--r--apps/playback.c278
1 files changed, 117 insertions, 161 deletions
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)
832 audio_play(offset); 832 audio_play(offset);
833} 833}
834 834
835void audio_preinit(void)
836{
837 logf("playback system pre-init");
838
839 filling = false;
840 set_current_codec(CODEC_IDX_AUDIO);
841 playing = false;
842 paused = false;
843 audio_codec_loaded = false;
844#ifdef PLAYBACK_VOICE
845 voice_is_playing = false;
846 voice_thread_start = false;
847 voice_codec_loaded = false;
848#endif
849 track_changed = false;
850 current_fd = -1;
851 track_buffer_callback = NULL;
852 track_unbuffer_callback = NULL;
853 track_changed_callback = NULL;
854 track_ridx = 0; /* Just to prevent CUR_TI from being anything random. */
855 prev_ti = &tracks[MAX_TRACK-1]; /* And prevent prev_ti being random too */
856
857#ifdef PLAYBACK_VOICE
858 mutex_init(&mutex_codecthread);
859#endif
860
861 queue_init(&audio_queue, true);
862 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list);
863 queue_init(&codec_queue, true);
864
865 create_thread(audio_thread, audio_stack, sizeof(audio_stack),
866 audio_thread_name IF_PRIO(, PRIORITY_BUFFERING)
867 IF_COP(, CPU, false));
868}
869
870void audio_init(void)
871{
872 LOGFQUEUE("audio > audio Q_AUDIO_POSTINIT");
873 queue_post(&audio_queue, Q_AUDIO_POSTINIT, 0);
874}
875
876void voice_init(void) 835void voice_init(void)
877{ 836{
878#ifdef PLAYBACK_VOICE 837#ifdef PLAYBACK_VOICE
879 if (!filebuf) 838 if (voice_thread_p || !filebuf || voice_codec_loaded ||
880 return; /* Audio buffers not yet set up */ 839 !talk_voice_required())
881
882 if (voice_thread_p)
883 return;
884
885 if (!talk_voice_required())
886 return; 840 return;
887 841
888 logf("Starting voice codec"); 842 logf("Starting voice codec");
@@ -1283,22 +1237,20 @@ static bool voice_request_next_track_callback(void)
1283 1237
1284static void voice_thread(void) 1238static void voice_thread(void)
1285{ 1239{
1286 while (1) 1240 logf("Loading voice codec");
1287 { 1241 voice_codec_loaded = true;
1288 logf("Loading voice codec"); 1242 mutex_lock(&mutex_codecthread);
1289 voice_codec_loaded = true; 1243 set_current_codec(CODEC_IDX_VOICE);
1290 mutex_lock(&mutex_codecthread); 1244 dsp_configure(DSP_RESET, 0);
1291 set_current_codec(CODEC_IDX_VOICE); 1245 voice_remaining = 0;
1292 dsp_configure(DSP_RESET, 0); 1246 voice_getmore = NULL;
1293 voice_remaining = 0;
1294 voice_getmore = NULL;
1295 1247
1296 codec_load_file(get_codec_filename(AFMT_MPA_L3), &ci_voice); 1248 codec_load_file(get_codec_filename(AFMT_MPA_L3), &ci_voice);
1297 1249
1298 logf("Voice codec finished"); 1250 logf("Voice codec finished");
1299 voice_codec_loaded = false; 1251 voice_codec_loaded = false;
1300 mutex_unlock(&mutex_codecthread); 1252 mutex_unlock(&mutex_codecthread);
1301 } 1253 remove_thread(NULL);
1302} /* voice_thread */ 1254} /* voice_thread */
1303 1255
1304#endif /* PLAYBACK_VOICE */ 1256#endif /* PLAYBACK_VOICE */
@@ -3465,103 +3417,6 @@ static void audio_reset_buffer(size_t pcmbufsize)
3465 buffer_state = BUFFER_STATE_NORMAL; 3417 buffer_state = BUFFER_STATE_NORMAL;
3466} 3418}
3467 3419
3468#ifdef ROCKBOX_HAS_LOGF
3469static void audio_test_track_changed_event(struct mp3entry *id3)
3470{
3471 (void)id3;
3472
3473 logf("tce:%s", id3->path);
3474}
3475#endif
3476
3477static void audio_playback_init(void)
3478{
3479#ifdef PLAYBACK_VOICE
3480 static bool voicetagtrue = true;
3481 static struct mp3entry id3_voice;
3482#endif
3483 struct event ev;
3484
3485 logf("playback api init");
3486 pcm_init();
3487
3488#ifdef AUDIO_HAVE_RECORDING
3489 rec_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
3490#endif
3491
3492#ifdef ROCKBOX_HAS_LOGF
3493 audio_set_track_changed_event(audio_test_track_changed_event);
3494#endif
3495
3496 /* Initialize codec api. */
3497 ci.read_filebuf = codec_filebuf_callback;
3498 ci.pcmbuf_insert = codec_pcmbuf_insert_callback;
3499 ci.get_codec_memory = codec_get_memory_callback;
3500 ci.request_buffer = codec_request_buffer_callback;
3501 ci.advance_buffer = codec_advance_buffer_callback;
3502 ci.advance_buffer_loc = codec_advance_buffer_loc_callback;
3503 ci.request_next_track = codec_request_next_track_callback;
3504 ci.mp3_get_filepos = codec_mp3_get_filepos_callback;
3505 ci.seek_buffer = codec_seek_buffer_callback;
3506 ci.seek_complete = codec_seek_complete_callback;
3507 ci.set_elapsed = codec_set_elapsed_callback;
3508 ci.set_offset = codec_set_offset_callback;
3509 ci.configure = codec_configure_callback;
3510 ci.discard_codec = codec_discard_codec_callback;
3511
3512 /* Initialize voice codec api. */
3513#ifdef PLAYBACK_VOICE
3514 memcpy(&ci_voice, &ci, sizeof(struct codec_api));
3515 memset(&id3_voice, 0, sizeof(struct mp3entry));
3516 ci_voice.read_filebuf = voice_filebuf_callback;
3517 ci_voice.pcmbuf_insert = voice_pcmbuf_insert_callback;
3518 ci_voice.get_codec_memory = voice_get_memory_callback;
3519 ci_voice.request_buffer = voice_request_buffer_callback;
3520 ci_voice.advance_buffer = voice_advance_buffer_callback;
3521 ci_voice.advance_buffer_loc = voice_advance_buffer_loc_callback;
3522 ci_voice.request_next_track = voice_request_next_track_callback;
3523 ci_voice.mp3_get_filepos = voice_mp3_get_filepos_callback;
3524 ci_voice.seek_buffer = voice_seek_buffer_callback;
3525 ci_voice.seek_complete = voice_do_nothing;
3526 ci_voice.set_elapsed = voice_set_elapsed_callback;
3527 ci_voice.set_offset = voice_set_offset_callback;
3528 ci_voice.discard_codec = voice_do_nothing;
3529 ci_voice.taginfo_ready = &voicetagtrue;
3530 ci_voice.id3 = &id3_voice;
3531 id3_voice.frequency = 11200;
3532 id3_voice.length = 1000000L;
3533#endif
3534
3535 codec_thread_p = create_thread(
3536 codec_thread, codec_stack, sizeof(codec_stack),
3537 codec_thread_name IF_PRIO(, PRIORITY_PLAYBACK)
3538 IF_COP(, COP, true));
3539
3540 while (1)
3541 {
3542 queue_wait(&audio_queue, &ev);
3543 if (ev.id == Q_AUDIO_POSTINIT)
3544 break ;
3545
3546#ifndef SIMULATOR
3547 if (ev.id == SYS_USB_CONNECTED)
3548 {
3549 logf("USB: Audio preinit");
3550 usb_acknowledge(SYS_USB_CONNECTED_ACK);
3551 usb_wait_for_disconnect(&audio_queue);
3552 }
3553#endif
3554 }
3555
3556 /* initialize the buffer */
3557 filebuf = audiobuf; /* must be non-NULL for audio_set_crossfade */
3558 buffer_state = BUFFER_STATE_TRASHED; /* force it */
3559 audio_set_crossfade(global_settings.crossfade);
3560
3561 audio_is_initialized = true;
3562
3563 sound_settings_apply();
3564}
3565#if MEM > 8 3420#if MEM > 8
3566/* we dont want this rebuffering on targets with little ram 3421/* we dont want this rebuffering on targets with little ram
3567 because the disk may never spin down */ 3422 because the disk may never spin down */
@@ -3575,8 +3430,6 @@ static bool ata_fillbuffer_callback(void)
3575static void audio_thread(void) 3430static void audio_thread(void)
3576{ 3431{
3577 struct event ev; 3432 struct event ev;
3578 /* At first initialize audio system in background. */
3579 audio_playback_init();
3580 3433
3581 while (1) 3434 while (1)
3582 { 3435 {
@@ -3707,3 +3560,106 @@ static void audio_thread(void)
3707 } /* end while */ 3560 } /* end while */
3708} 3561}
3709 3562
3563#ifdef ROCKBOX_HAS_LOGF
3564static void audio_test_track_changed_event(struct mp3entry *id3)
3565{
3566 (void)id3;
3567
3568 logf("tce:%s", id3->path);
3569}
3570#endif
3571
3572/* Initialize the audio system - called from init() in main.c.
3573 * Last function because of all the references to internal symbols
3574 */
3575void audio_init(void)
3576{
3577#ifdef PLAYBACK_VOICE
3578 static bool voicetagtrue = true;
3579 static struct mp3entry id3_voice;
3580#endif
3581
3582 logf("audio: %s", audio_is_initialized ?
3583 "initializing" : "already initialized");
3584
3585 /* Can never do this twice */
3586 if (audio_is_initialized)
3587 return;
3588
3589 /* Initialize queues before giving control elsewhere in case it likes
3590 to send messages. Thread creation will be delayed however so nothing
3591 starts running until ready if something yields such as talk_init. */
3592#ifdef PLAYBACK_VOICE
3593 mutex_init(&mutex_codecthread);
3594#endif
3595 queue_init(&audio_queue, true);
3596 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list);
3597 queue_init(&codec_queue, true);
3598
3599 pcm_init();
3600
3601#ifdef ROCKBOX_HAS_LOGF
3602 audio_set_track_changed_event(audio_test_track_changed_event);
3603#endif
3604
3605 /* Initialize codec api. */
3606 ci.read_filebuf = codec_filebuf_callback;
3607 ci.pcmbuf_insert = codec_pcmbuf_insert_callback;
3608 ci.get_codec_memory = codec_get_memory_callback;
3609 ci.request_buffer = codec_request_buffer_callback;
3610 ci.advance_buffer = codec_advance_buffer_callback;
3611 ci.advance_buffer_loc = codec_advance_buffer_loc_callback;
3612 ci.request_next_track = codec_request_next_track_callback;
3613 ci.mp3_get_filepos = codec_mp3_get_filepos_callback;
3614 ci.seek_buffer = codec_seek_buffer_callback;
3615 ci.seek_complete = codec_seek_complete_callback;
3616 ci.set_elapsed = codec_set_elapsed_callback;
3617 ci.set_offset = codec_set_offset_callback;
3618 ci.configure = codec_configure_callback;
3619 ci.discard_codec = codec_discard_codec_callback;
3620
3621 /* Initialize voice codec api. */
3622#ifdef PLAYBACK_VOICE
3623 memcpy(&ci_voice, &ci, sizeof(ci_voice));
3624 memset(&id3_voice, 0, sizeof(id3_voice));
3625 ci_voice.read_filebuf = voice_filebuf_callback;
3626 ci_voice.pcmbuf_insert = voice_pcmbuf_insert_callback;
3627 ci_voice.get_codec_memory = voice_get_memory_callback;
3628 ci_voice.request_buffer = voice_request_buffer_callback;
3629 ci_voice.advance_buffer = voice_advance_buffer_callback;
3630 ci_voice.advance_buffer_loc = voice_advance_buffer_loc_callback;
3631 ci_voice.request_next_track = voice_request_next_track_callback;
3632 ci_voice.mp3_get_filepos = voice_mp3_get_filepos_callback;
3633 ci_voice.seek_buffer = voice_seek_buffer_callback;
3634 ci_voice.seek_complete = voice_do_nothing;
3635 ci_voice.set_elapsed = voice_set_elapsed_callback;
3636 ci_voice.set_offset = voice_set_offset_callback;
3637 ci_voice.discard_codec = voice_do_nothing;
3638 ci_voice.taginfo_ready = &voicetagtrue;
3639 ci_voice.id3 = &id3_voice;
3640 id3_voice.frequency = 11200;
3641 id3_voice.length = 1000000L;
3642#endif
3643
3644 /* initialize the buffer */
3645 filebuf = audiobuf; /* must be non-NULL for audio_set_crossfade */
3646 /* audio_reset_buffer must to know the size of voice buffer so init
3647 voice first */
3648 talk_init();
3649
3650 codec_thread_p = create_thread(
3651 codec_thread, codec_stack, sizeof(codec_stack),
3652 codec_thread_name IF_PRIO(, PRIORITY_PLAYBACK)
3653 IF_COP(, COP, true));
3654
3655 create_thread(audio_thread, audio_stack, sizeof(audio_stack),
3656 audio_thread_name IF_PRIO(, PRIORITY_BUFFERING)
3657 IF_COP(, CPU, false));
3658
3659 audio_set_crossfade(global_settings.crossfade);
3660
3661 audio_is_initialized = true;
3662
3663 sound_settings_apply();
3664 audio_set_buffer_margin(global_settings.buffer_margin);
3665} /* audio_init */