summaryrefslogtreecommitdiff
path: root/apps/playback.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2013-05-31 02:41:02 -0400
committerMichael Sevakis <jethead71@rockbox.org>2013-05-31 03:20:35 -0400
commit5857c44017a1641fce7f00da7f16c143daacbaf6 (patch)
treeb8a7ff134977ee8dd6b25b5591f4eb81172f74ab /apps/playback.c
parentdf6e1bcce5071e02b5cd46736bff87ca0dcceffe (diff)
downloadrockbox-5857c44017a1641fce7f00da7f16c143daacbaf6.tar.gz
rockbox-5857c44017a1641fce7f00da7f16c143daacbaf6.zip
Refactor audio thread to run both recording and playback.
Eliminates the pcmrec thread and keeps playback and recording engine operation mutually-exclusive. audio_thread.c contains the audio thread which branches to the correct engine depending upon the request. It also handles the main audio initialization. Moves pcm_init into main.c just before dsp_init because I don't want that one in audio_init in the new file. (Also makes revision df6e1bc pointless ;) Change-Id: Ifc1db24404e6d8dd9ac42d9f4dfbc207aa9a26e1
Diffstat (limited to 'apps/playback.c')
-rw-r--r--apps/playback.c342
1 files changed, 92 insertions, 250 deletions
diff --git a/apps/playback.c b/apps/playback.c
index 15a3fe9a61..01fa7a9dda 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -27,7 +27,6 @@
27#include "core_alloc.h" 27#include "core_alloc.h"
28#include "sound.h" 28#include "sound.h"
29#include "ata.h" 29#include "ata.h"
30#include "usb.h"
31#include "codecs.h" 30#include "codecs.h"
32#include "codec_thread.h" 31#include "codec_thread.h"
33#include "voice_thread.h" 32#include "voice_thread.h"
@@ -38,6 +37,7 @@
38#include "playlist.h" 37#include "playlist.h"
39#include "abrepeat.h" 38#include "abrepeat.h"
40#include "pcmbuf.h" 39#include "pcmbuf.h"
40#include "audio_thread.h"
41#include "playback.h" 41#include "playback.h"
42#include "misc.h" 42#include "misc.h"
43#include "settings.h" 43#include "settings.h"
@@ -46,10 +46,6 @@
46#include "tagcache.h" 46#include "tagcache.h"
47#endif 47#endif
48 48
49#ifdef AUDIO_HAVE_RECORDING
50#include "pcm_record.h"
51#endif
52
53#ifdef HAVE_LCD_BITMAP 49#ifdef HAVE_LCD_BITMAP
54#ifdef HAVE_ALBUMART 50#ifdef HAVE_ALBUMART
55#include "albumart.h" 51#include "albumart.h"
@@ -104,8 +100,10 @@
104 */ 100 */
105 101
106/** Miscellaneous **/ 102/** Miscellaneous **/
107bool audio_is_initialized = false; /* (A,O-) */ 103extern unsigned int audio_thread_id; /* from audio_thread.c */
108extern struct codec_api ci; /* (A,C) */ 104extern struct event_queue audio_queue; /* from audio_thread.c */
105extern bool audio_is_initialized; /* from audio_thread.c */
106extern struct codec_api ci; /* from codecs.c */
109 107
110/** Possible arrangements of the main buffer **/ 108/** Possible arrangements of the main buffer **/
111static enum audio_buffer_state 109static enum audio_buffer_state
@@ -190,7 +188,6 @@ static enum filling_state
190 STATE_FINISHED, /* all remaining tracks are fully buffered */ 188 STATE_FINISHED, /* all remaining tracks are fully buffered */
191 STATE_ENDING, /* audio playback is ending */ 189 STATE_ENDING, /* audio playback is ending */
192 STATE_ENDED, /* audio playback is done */ 190 STATE_ENDED, /* audio playback is done */
193 STATE_USB, /* USB mode, ignore most messages */
194} filling = STATE_IDLE; 191} filling = STATE_IDLE;
195 192
196/* Track info - holds information about each track in the buffer */ 193/* Track info - holds information about each track in the buffer */
@@ -330,15 +327,6 @@ static int codec_skip_status;
330static bool codec_seeking = false; /* Codec seeking ack expected? */ 327static bool codec_seeking = false; /* Codec seeking ack expected? */
331static unsigned int position_key = 0; 328static unsigned int position_key = 0;
332 329
333/* Event queues */
334static struct event_queue audio_queue SHAREDBSS_ATTR;
335
336/* Audio thread */
337static struct queue_sender_list audio_queue_sender_list SHAREDBSS_ATTR;
338static long audio_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
339static const char audio_thread_name[] = "audio";
340static unsigned int audio_thread_id = 0;
341
342/* Forward declarations */ 330/* Forward declarations */
343enum audio_start_playback_flags 331enum audio_start_playback_flags
344{ 332{
@@ -2985,228 +2973,170 @@ static void audio_on_audio_flush(void)
2985 } 2973 }
2986} 2974}
2987 2975
2988#ifdef AUDIO_HAVE_RECORDING 2976/* Called by audio thread when playback is started */
2989/* Load the requested encoder type 2977void audio_playback_handler(struct queue_event *ev)
2990 (Q_AUDIO_LOAD_ENCODER) */
2991static void audio_on_load_encoder(int afmt)
2992{
2993 bool res = true;
2994
2995 if (play_status != PLAY_STOPPED)
2996 audio_stop_playback(); /* Can't load both types at once */
2997 else
2998 codec_unload(); /* Encoder still loaded, stop and unload it */
2999
3000 if (afmt != AFMT_UNKNOWN)
3001 {
3002 res = codec_load(-1, afmt | CODEC_TYPE_ENCODER);
3003 if (res)
3004 codec_go(); /* These are run immediately */
3005 }
3006
3007 queue_reply(&audio_queue, res);
3008}
3009#endif /* AUDIO_HAVE_RECORDING */
3010
3011static void audio_thread(void)
3012{ 2978{
3013 struct queue_event ev;
3014
3015 pcm_postinit();
3016
3017 while (1) 2979 while (1)
3018 { 2980 {
3019 switch (filling) 2981 switch (ev->id)
3020 {
3021 /* Active states */
3022 case STATE_FULL:
3023 case STATE_END_OF_PLAYLIST:
3024 if (buf_get_watermark() == 0)
3025 {
3026 /* End of buffering for now, let's calculate the watermark,
3027 register for a low buffer event and unboost */
3028 audio_update_filebuf_watermark(0);
3029 add_event(BUFFER_EVENT_BUFFER_LOW, true,
3030 buffer_event_buffer_low_callback);
3031 }
3032 /* Fall-through */
3033 case STATE_FINISHED:
3034 /* All data was buffered */
3035 cancel_cpu_boost();
3036 /* Fall-through */
3037 case STATE_FILLING:
3038 case STATE_ENDING:
3039 if (audio_pcmbuf_track_change_scan())
3040 {
3041 /* Transfer notification to audio queue event */
3042 ev.id = Q_AUDIO_TRACK_CHANGED;
3043 ev.data = 1;
3044 }
3045 else
3046 {
3047 /* If doing auto skip, poll pcmbuf track notifications a bit
3048 faster to promply detect the transition */
3049 queue_wait_w_tmo(&audio_queue, &ev,
3050 skip_pending == TRACK_SKIP_NONE ?
3051 HZ/2 : HZ/10);
3052 }
3053 break;
3054
3055 /* Idle states */
3056 default:
3057 queue_wait(&audio_queue, &ev);
3058
3059#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3060 switch (ev.id)
3061 {
3062#ifdef AUDIO_HAVE_RECORDING
3063 /* Must monitor the encoder message for recording so it can remove
3064 it if we process the insertion before it does. It cannot simply
3065 be removed from under recording however. */
3066 case Q_AUDIO_LOAD_ENCODER:
3067 break;
3068#endif
3069 case SYS_USB_DISCONNECTED:
3070 filling = STATE_IDLE;
3071 break;
3072
3073 default:
3074 if (filling == STATE_USB)
3075 continue;
3076 }
3077#endif /* CONFIG_PLATFORM */
3078 }
3079
3080 switch (ev.id)
3081 { 2982 {
3082 /** Codec and track change messages **/ 2983 /** Codec and track change messages **/
3083 case Q_AUDIO_CODEC_COMPLETE: 2984 case Q_AUDIO_CODEC_COMPLETE:
3084 /* Codec is done processing track and has gone idle */ 2985 /* Codec is done processing track and has gone idle */
3085 LOGFQUEUE("audio < Q_AUDIO_CODEC_COMPLETE: %ld", (long)ev.data); 2986 LOGFQUEUE("playback < Q_AUDIO_CODEC_COMPLETE: %ld",
3086 audio_on_codec_complete(ev.data); 2987 (long)ev->data);
2988 audio_on_codec_complete(ev->data);
3087 break; 2989 break;
3088 2990
3089 case Q_AUDIO_CODEC_SEEK_COMPLETE: 2991 case Q_AUDIO_CODEC_SEEK_COMPLETE:
3090 /* Codec is done seeking */ 2992 /* Codec is done seeking */
3091 LOGFQUEUE("audio < Q_AUDIO_SEEK_COMPLETE"); 2993 LOGFQUEUE("playback < Q_AUDIO_SEEK_COMPLETE");
3092 audio_on_codec_seek_complete(); 2994 audio_on_codec_seek_complete();
3093 break; 2995 break;
3094 2996
3095 case Q_AUDIO_TRACK_CHANGED: 2997 case Q_AUDIO_TRACK_CHANGED:
3096 /* PCM track change done */ 2998 /* PCM track change done */
3097 LOGFQUEUE("audio < Q_AUDIO_TRACK_CHANGED"); 2999 LOGFQUEUE("playback < Q_AUDIO_TRACK_CHANGED");
3098 audio_on_track_changed(); 3000 audio_on_track_changed();
3099 break; 3001 break;
3100 3002
3101 /** Control messages **/ 3003 /** Control messages **/
3102 case Q_AUDIO_PLAY: 3004 case Q_AUDIO_PLAY:
3103 LOGFQUEUE("audio < Q_AUDIO_PLAY"); 3005 LOGFQUEUE("playback < Q_AUDIO_PLAY");
3104 audio_start_playback(ev.data, 0); 3006 audio_start_playback(ev->data, 0);
3105 break; 3007 break;
3106 3008
3009#ifdef AUDIO_HAVE_RECORDING
3010 /* So we can go straight from playback to recording */
3011 case Q_AUDIO_INIT_RECORDING:
3012#endif
3013 case SYS_USB_CONNECTED:
3107 case Q_AUDIO_STOP: 3014 case Q_AUDIO_STOP:
3108 LOGFQUEUE("audio < Q_AUDIO_STOP"); 3015 LOGFQUEUE("playback < Q_AUDIO_STOP");
3109 audio_stop_playback(); 3016 audio_stop_playback();
3110 if (ev.data != 0) 3017 if (ev->data != 0)
3111 queue_clear(&audio_queue); 3018 queue_clear(&audio_queue);
3112 break; 3019 return; /* no more playback */
3113 3020
3114 case Q_AUDIO_PAUSE: 3021 case Q_AUDIO_PAUSE:
3115 LOGFQUEUE("audio < Q_AUDIO_PAUSE"); 3022 LOGFQUEUE("playback < Q_AUDIO_PAUSE");
3116 audio_on_pause(ev.data); 3023 audio_on_pause(ev->data);
3117 break; 3024 break;
3118 3025
3119 case Q_AUDIO_SKIP: 3026 case Q_AUDIO_SKIP:
3120 LOGFQUEUE("audio < Q_AUDIO_SKIP"); 3027 LOGFQUEUE("playback < Q_AUDIO_SKIP");
3121 audio_on_skip(); 3028 audio_on_skip();
3122 break; 3029 break;
3123 3030
3124 case Q_AUDIO_DIR_SKIP: 3031 case Q_AUDIO_DIR_SKIP:
3125 LOGFQUEUE("audio < Q_AUDIO_DIR_SKIP"); 3032 LOGFQUEUE("playback < Q_AUDIO_DIR_SKIP");
3126 audio_on_dir_skip(ev.data); 3033 audio_on_dir_skip(ev->data);
3127 break; 3034 break;
3128 3035
3129 case Q_AUDIO_PRE_FF_REWIND: 3036 case Q_AUDIO_PRE_FF_REWIND:
3130 LOGFQUEUE("audio < Q_AUDIO_PRE_FF_REWIND"); 3037 LOGFQUEUE("playback < Q_AUDIO_PRE_FF_REWIND");
3131 audio_on_pre_ff_rewind(); 3038 audio_on_pre_ff_rewind();
3132 break; 3039 break;
3133 3040
3134 case Q_AUDIO_FF_REWIND: 3041 case Q_AUDIO_FF_REWIND:
3135 LOGFQUEUE("audio < Q_AUDIO_FF_REWIND"); 3042 LOGFQUEUE("playback < Q_AUDIO_FF_REWIND");
3136 audio_on_ff_rewind(ev.data); 3043 audio_on_ff_rewind(ev->data);
3137 break; 3044 break;
3138 3045
3139 case Q_AUDIO_FLUSH: 3046 case Q_AUDIO_FLUSH:
3140 LOGFQUEUE("audio < Q_AUDIO_FLUSH: %d", (int)ev.data); 3047 LOGFQUEUE("playback < Q_AUDIO_FLUSH: %d", (int)ev->data);
3141 audio_on_audio_flush(); 3048 audio_on_audio_flush();
3142 break; 3049 break;
3143 3050
3144 /** Buffering messages **/ 3051 /** Buffering messages **/
3145 case Q_AUDIO_BUFFERING: 3052 case Q_AUDIO_BUFFERING:
3146 /* some buffering event */ 3053 /* some buffering event */
3147 LOGFQUEUE("audio < Q_AUDIO_BUFFERING: %d", (int)ev.data); 3054 LOGFQUEUE("playback < Q_AUDIO_BUFFERING: %d", (int)ev->data);
3148 audio_on_buffering(ev.data); 3055 audio_on_buffering(ev->data);
3149 break; 3056 break;
3150 3057
3151 case Q_AUDIO_FILL_BUFFER: 3058 case Q_AUDIO_FILL_BUFFER:
3152 /* continue buffering next track */ 3059 /* continue buffering next track */
3153 LOGFQUEUE("audio < Q_AUDIO_FILL_BUFFER"); 3060 LOGFQUEUE("playback < Q_AUDIO_FILL_BUFFER");
3154 audio_on_fill_buffer(); 3061 audio_on_fill_buffer();
3155 break; 3062 break;
3156 3063
3157 case Q_AUDIO_FINISH_LOAD_TRACK: 3064 case Q_AUDIO_FINISH_LOAD_TRACK:
3158 /* metadata is buffered */ 3065 /* metadata is buffered */
3159 LOGFQUEUE("audio < Q_AUDIO_FINISH_LOAD_TRACK"); 3066 LOGFQUEUE("playback < Q_AUDIO_FINISH_LOAD_TRACK");
3160 audio_on_finish_load_track(ev.data); 3067 audio_on_finish_load_track(ev->data);
3161 break; 3068 break;
3162 3069
3163 case Q_AUDIO_HANDLE_FINISHED: 3070 case Q_AUDIO_HANDLE_FINISHED:
3164 /* some other type is buffered */ 3071 /* some other type is buffered */
3165 LOGFQUEUE("audio < Q_AUDIO_HANDLE_FINISHED"); 3072 LOGFQUEUE("playback < Q_AUDIO_HANDLE_FINISHED");
3166 audio_on_handle_finished(ev.data); 3073 audio_on_handle_finished(ev->data);
3167 break; 3074 break;
3168 3075
3169 /** Miscellaneous messages **/ 3076 /** Miscellaneous messages **/
3170 case Q_AUDIO_REMAKE_AUDIO_BUFFER: 3077 case Q_AUDIO_REMAKE_AUDIO_BUFFER:
3171 /* buffer needs to be reinitialized */ 3078 /* buffer needs to be reinitialized */
3172 LOGFQUEUE("audio < Q_AUDIO_REMAKE_AUDIO_BUFFER"); 3079 LOGFQUEUE("playback < Q_AUDIO_REMAKE_AUDIO_BUFFER");
3173 audio_start_playback(0, AUDIO_START_RESTART | AUDIO_START_NEWBUF); 3080 audio_start_playback(0, AUDIO_START_RESTART | AUDIO_START_NEWBUF);
3174 break; 3081 break;
3175 3082
3176#ifdef HAVE_DISK_STORAGE 3083#ifdef HAVE_DISK_STORAGE
3177 case Q_AUDIO_UPDATE_WATERMARK: 3084 case Q_AUDIO_UPDATE_WATERMARK:
3178 /* buffering watermark needs updating */ 3085 /* buffering watermark needs updating */
3179 LOGFQUEUE("audio < Q_AUDIO_UPDATE_WATERMARK: %d", (int)ev.data); 3086 LOGFQUEUE("playback < Q_AUDIO_UPDATE_WATERMARK: %d",
3180 audio_update_filebuf_watermark(ev.data); 3087 (int)ev->data);
3088 audio_update_filebuf_watermark(ev->data);
3181 break; 3089 break;
3182#endif /* HAVE_DISK_STORAGE */ 3090#endif /* HAVE_DISK_STORAGE */
3183 3091
3184#ifdef AUDIO_HAVE_RECORDING 3092 case SYS_TIMEOUT:
3185 case Q_AUDIO_LOAD_ENCODER: 3093 LOGFQUEUE_SYS_TIMEOUT("playback < SYS_TIMEOUT");
3186 /* load an encoder for recording */
3187 LOGFQUEUE("audio < Q_AUDIO_LOAD_ENCODER: %d", (int)ev.data);
3188 audio_on_load_encoder(ev.data);
3189 break; 3094 break;
3190#endif /* AUDIO_HAVE_RECORDING */
3191 3095
3192 case SYS_USB_CONNECTED: 3096 default:
3193 LOGFQUEUE("audio < SYS_USB_CONNECTED"); 3097 /* LOGFQUEUE("audio < default : %08lX", ev->id); */
3194 audio_stop_playback();
3195#ifdef PLAYBACK_VOICE
3196 voice_stop();
3197#endif
3198 filling = STATE_USB;
3199 usb_acknowledge(SYS_USB_CONNECTED_ACK);
3200 break; 3098 break;
3099 } /* end switch */
3201 3100
3202 case SYS_TIMEOUT: 3101 switch (filling)
3203 LOGFQUEUE_SYS_TIMEOUT("audio < SYS_TIMEOUT"); 3102 {
3103 /* Active states */
3104 case STATE_FULL:
3105 case STATE_END_OF_PLAYLIST:
3106 if (buf_get_watermark() == 0)
3107 {
3108 /* End of buffering for now, let's calculate the watermark,
3109 register for a low buffer event and unboost */
3110 audio_update_filebuf_watermark(0);
3111 add_event(BUFFER_EVENT_BUFFER_LOW, true,
3112 buffer_event_buffer_low_callback);
3113 }
3114 /* Fall-through */
3115 case STATE_FINISHED:
3116 /* All data was buffered */
3117 cancel_cpu_boost();
3118 /* Fall-through */
3119 case STATE_FILLING:
3120 case STATE_ENDING:
3121 if (audio_pcmbuf_track_change_scan())
3122 {
3123 /* Transfer notification to audio queue event */
3124 ev->id = Q_AUDIO_TRACK_CHANGED;
3125 ev->data = 1;
3126 }
3127 else
3128 {
3129 /* If doing auto skip, poll pcmbuf track notifications a bit
3130 faster to promply detect the transition */
3131 queue_wait_w_tmo(&audio_queue, ev,
3132 skip_pending == TRACK_SKIP_NONE ? HZ/2 : HZ/10);
3133 }
3204 break; 3134 break;
3205 3135
3136 /* Idle states */
3206 default: 3137 default:
3207 /* LOGFQUEUE("audio < default : %08lX", ev.id); */ 3138 queue_wait(&audio_queue, ev);
3208 break; 3139 }
3209 } /* end switch */
3210 } /* end while */ 3140 } /* end while */
3211} 3141}
3212 3142
@@ -3356,27 +3286,6 @@ bool audio_pcmbuf_may_play(void)
3356 3286
3357/** -- External interfaces -- **/ 3287/** -- External interfaces -- **/
3358 3288
3359/* Return the playback and recording status */
3360int audio_status(void)
3361{
3362 unsigned int ret = play_status;
3363
3364#ifdef AUDIO_HAVE_RECORDING
3365 /* Do this here for constitency with mpeg.c version */
3366 ret |= pcm_rec_status();
3367#endif
3368
3369 return (int)ret;
3370}
3371
3372/* Clear all accumulated audio errors for playback and recording */
3373void audio_error_clear(void)
3374{
3375#ifdef AUDIO_HAVE_RECORDING
3376 pcm_rec_error_clear();
3377#endif
3378}
3379
3380/* Get a copy of the id3 data for the for current track + offset + skip delta */ 3289/* Get a copy of the id3 data for the for current track + offset + skip delta */
3381bool audio_peek_track(struct mp3entry *id3, int offset) 3290bool audio_peek_track(struct mp3entry *id3, int offset)
3382{ 3291{
@@ -3599,7 +3508,7 @@ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
3599{ 3508{
3600 unsigned char *buf; 3509 unsigned char *buf;
3601 3510
3602 if (audio_is_initialized) 3511 if (audio_is_initialized && thread_self() != audio_thread_id)
3603 { 3512 {
3604 audio_hard_stop(); 3513 audio_hard_stop();
3605 } 3514 }
@@ -3656,15 +3565,6 @@ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
3656 return buf; 3565 return buf;
3657} 3566}
3658 3567
3659#ifdef HAVE_RECORDING
3660/* Stop audio, voice and obtain all available buffer space */
3661unsigned char * audio_get_recording_buffer(size_t *buffer_size)
3662{
3663 audio_hard_stop();
3664 return audio_get_buffer(true, buffer_size);
3665}
3666#endif /* HAVE_RECORDING */
3667
3668/* Restore audio buffer to a particular state (promoting status) */ 3568/* Restore audio buffer to a particular state (promoting status) */
3669bool audio_restore_playback(int type) 3569bool audio_restore_playback(int type)
3670{ 3570{
@@ -3755,30 +3655,6 @@ void playback_release_aa_slot(int slot)
3755} 3655}
3756#endif /* HAVE_ALBUMART */ 3656#endif /* HAVE_ALBUMART */
3757 3657
3758
3759#ifdef HAVE_RECORDING
3760/* Load an encoder and run it */
3761bool audio_load_encoder(int afmt)
3762{
3763#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3764 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: %d", afmt);
3765 return audio_queue_send(Q_AUDIO_LOAD_ENCODER, afmt) != 0;
3766#else
3767 (void)afmt;
3768 return true;
3769#endif
3770}
3771
3772/* Stop an encoder and unload it */
3773void audio_remove_encoder(void)
3774{
3775#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
3776 LOGFQUEUE("audio >| Q_AUDIO_LOAD_ENCODER: NULL");
3777 audio_queue_send(Q_AUDIO_LOAD_ENCODER, AFMT_UNKNOWN);
3778#endif
3779}
3780#endif /* HAVE_RECORDING */
3781
3782/* Is an automatic skip in progress? If called outside transition callbacks, 3658/* Is an automatic skip in progress? If called outside transition callbacks,
3783 indicates the last skip type at the time it was processed and isn't very 3659 indicates the last skip type at the time it was processed and isn't very
3784 meaningful. */ 3660 meaningful. */
@@ -3866,58 +3742,24 @@ void audio_set_crossfade(int enable)
3866} 3742}
3867#endif /* HAVE_CROSSFADE */ 3743#endif /* HAVE_CROSSFADE */
3868 3744
3745unsigned int playback_status(void)
3746{
3747 return play_status;
3748}
3869 3749
3870/** -- Startup -- **/ 3750/** -- Startup -- **/
3871 3751void playback_init(void)
3872/* Initialize the audio system - called from init() in main.c */
3873void audio_init(void)
3874{ 3752{
3875 /* Can never do this twice */ 3753 logf("playback: initializing");
3876 if (audio_is_initialized)
3877 {
3878 logf("audio: already initialized");
3879 return;
3880 }
3881
3882 logf("audio: initializing");
3883
3884 /* Initialize queues before giving control elsewhere in case it likes
3885 to send messages. Thread creation will be delayed however so nothing
3886 starts running until ready if something yields such as talk_init. */
3887 queue_init(&audio_queue, true);
3888
3889 mutex_init(&id3_mutex);
3890
3891 pcm_init();
3892
3893 codec_thread_init();
3894
3895 /* This thread does buffer, so match its priority */
3896 audio_thread_id = create_thread(audio_thread, audio_stack,
3897 sizeof(audio_stack), 0, audio_thread_name
3898 IF_PRIO(, MIN(PRIORITY_BUFFERING, PRIORITY_USER_INTERFACE))
3899 IF_COP(, CPU));
3900
3901 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
3902 audio_thread_id);
3903 3754
3904 /* Initialize the track buffering system */ 3755 /* Initialize the track buffering system */
3756 mutex_init(&id3_mutex);
3905 track_list_init(); 3757 track_list_init();
3906 buffering_init(); 3758 buffering_init();
3907
3908#ifdef HAVE_CROSSFADE 3759#ifdef HAVE_CROSSFADE
3909 /* Set crossfade setting for next buffer init which should be about... */ 3760 /* Set crossfade setting for next buffer init which should be about... */
3910 pcmbuf_request_crossfade_enable(global_settings.crossfade); 3761 pcmbuf_request_crossfade_enable(global_settings.crossfade);
3911#endif 3762#endif
3912
3913 /* ...now...audio_reset_buffer must know the size of voicefile buffer so
3914 init talk first which will init the buffers */
3915 talk_init();
3916
3917 /* Probably safe to say */
3918 audio_is_initialized = true;
3919
3920 sound_settings_apply();
3921#ifdef HAVE_DISK_STORAGE 3763#ifdef HAVE_DISK_STORAGE
3922 audio_set_buffer_margin(global_settings.buffer_margin); 3764 audio_set_buffer_margin(global_settings.buffer_margin);
3923#endif 3765#endif