Esempio n. 1
0
void audio_output_finish(struct audio_output *ao)
{
	audio_output_close(ao);

	assert(ao->fail_timer == NULL);

	if (ao->thread != NULL) {
		g_mutex_lock(ao->mutex);
		ao_command(ao, AO_COMMAND_KILL);
		g_mutex_unlock(ao->mutex);
		g_thread_join(ao->thread);
	}

	if (ao->mixer != NULL)
		mixer_free(ao->mixer);

	ao_plugin_finish(ao->plugin, ao->data);

	g_cond_free(ao->cond);
	g_mutex_free(ao->mutex);

	if (ao->replay_gain_filter != NULL)
		filter_free(ao->replay_gain_filter);

	if (ao->other_replay_gain_filter != NULL)
		filter_free(ao->other_replay_gain_filter);

	filter_free(ao->filter);

	pcm_buffer_deinit(&ao->cross_fade_buffer);
}
Esempio n. 2
0
/**
 * Lock the #audio_output object and execute the command
 * synchronously.
 */
static void
ao_lock_command(struct audio_output *ao, enum audio_output_command cmd)
{
    g_mutex_lock(ao->mutex);
    ao_command(ao, cmd);
    g_mutex_unlock(ao->mutex);
}
Esempio n. 3
0
/**
 * Same as audio_output_close(), but expects the lock to be held by
 * the caller.
 */
static void
audio_output_close_locked(struct audio_output *ao)
{
	if (ao->mixer != NULL)
		mixer_auto_close(ao->mixer);

	assert(!ao->open || ao->fail_timer == NULL);

	if (ao->open)
		ao_command(ao, AO_COMMAND_CLOSE);
	else if (ao->fail_timer != NULL) {
		g_timer_destroy(ao->fail_timer);
		ao->fail_timer = NULL;
	}
}
Esempio n. 4
0
static int
aoplug_seek_sample (DB_fileinfo_t *_info, int sample) {
    aoplug_info_t *info = (aoplug_info_t *)_info;
    if (sample > info->currentsample) {
        info->skipsamples = sample-info->currentsample;
    }
    else {
        // restart song
        ao_command (info->type, info->decoder, COMMAND_RESTART, 0);
        info->skipsamples = sample;
    }
    info->currentsample = sample;
    _info->readpos = (float)sample / _info->fmt.samplerate;
    return 0;
}
Esempio n. 5
0
void
audio_output_disable(struct audio_output *ao)
{
	if (ao->thread == NULL) {
		if (ao->plugin->disable == NULL)
			ao->really_enabled = false;
		else
			/* if there's no thread yet, the device cannot
			   be enabled */
			assert(!ao->really_enabled);

		return;
	}

	g_mutex_lock(ao->mutex);
	ao_command(ao, AO_COMMAND_DISABLE);
	g_mutex_unlock(ao->mutex);
}
Esempio n. 6
0
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);
	}

	g_mutex_lock(ao->mutex);
	ao_command(ao, AO_COMMAND_ENABLE);
	g_mutex_unlock(ao->mutex);
}
Esempio n. 7
0
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;
}