void audio_output_enable(struct audio_output *ao) { if (ao->thread == NULL) { if (ao->plugin->enable == NULL) { /* don't bother to start the thread now if the device doesn't even have a enable() method; just assign the variable and we're done */ ao->really_enabled = true; return; } audio_output_thread_start(ao); } ao_lock_command(ao, AO_COMMAND_ENABLE); }
static bool audio_output_open(struct audio_output *ao, const struct audio_format *audio_format, const struct music_pipe *mp) { bool open; assert(mp != NULL); if (ao->fail_timer != NULL) { g_timer_destroy(ao->fail_timer); ao->fail_timer = NULL; } if (ao->open && audio_format_equals(audio_format, &ao->in_audio_format)) { assert(ao->pipe == mp || (ao->always_on && ao->pause)); if (ao->pause) { ao->chunk = NULL; ao->pipe = mp; /* unpause with the CANCEL command; this is a hack, but suits well for forcing the thread to leave the ao_pause() thread, and we need to flush the device buffer anyway */ /* we're not using audio_output_cancel() here, because that function is asynchronous */ ao_command(ao, AO_COMMAND_CANCEL); /* the audio output is now waiting for a signal; wake it up immediately */ g_cond_signal(ao->cond); } return true; } ao->in_audio_format = *audio_format; ao->chunk = NULL; ao->pipe = mp; if (ao->thread == NULL) audio_output_thread_start(ao); ao_command(ao, ao->open ? AO_COMMAND_REOPEN : AO_COMMAND_OPEN); open = ao->open; if (open && ao->mixer != NULL) { GError *error = NULL; if (!mixer_open(ao->mixer, &error)) { g_warning("Failed to open mixer for '%s': %s", ao->name, error->message); g_error_free(error); } } return open; }