static void *
recorder_output_init(G_GNUC_UNUSED const struct audio_format *audio_format,
		     const struct config_param *param, GError **error_r)
{
	struct recorder_output *recorder = g_new(struct recorder_output, 1);
	const char *encoder_name;
	const struct encoder_plugin *encoder_plugin;

	/* read configuration */

	encoder_name = config_get_block_string(param, "encoder", "vorbis");
	encoder_plugin = encoder_plugin_get(encoder_name);
	if (encoder_plugin == NULL) {
		g_set_error(error_r, recorder_output_quark(), 0,
			    "No such encoder: %s", encoder_name);
		return NULL;
	}

	recorder->path = config_get_block_string(param, "path", NULL);
	if (recorder->path == NULL) {
		g_set_error(error_r, recorder_output_quark(), 0,
			    "'path' not configured");
		return NULL;
	}

	/* initialize encoder */

	recorder->encoder = encoder_init(encoder_plugin, param, error_r);
	if (recorder->encoder == NULL)
		return NULL;

	return recorder;
}
static bool
input_curl_init(const struct config_param *param,
		G_GNUC_UNUSED GError **error_r)
{
	CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
	if (code != CURLE_OK) {
		g_warning("curl_global_init() failed: %s\n",
			  curl_easy_strerror(code));
		return false;
	}

	http_200_aliases = curl_slist_append(http_200_aliases, "ICY 200 OK");

	proxy = config_get_block_string(param, "proxy", NULL);
	proxy_port = config_get_block_unsigned(param, "proxy_port", 0);
	proxy_user = config_get_block_string(param, "proxy_user", NULL);
	proxy_password = config_get_block_string(param, "proxy_password",
						 NULL);

	if (proxy == NULL) {
		/* deprecated proxy configuration */
		proxy = config_get_string(CONF_HTTP_PROXY_HOST, NULL);
		proxy_port = config_get_positive(CONF_HTTP_PROXY_PORT, 0);
		proxy_user = config_get_string(CONF_HTTP_PROXY_USER, NULL);
		proxy_password = config_get_string(CONF_HTTP_PROXY_PASSWORD,
						   "");
	}

	return true;
}
Exemple #3
0
static bool
vorbis_encoder_configure(struct vorbis_encoder *encoder,
			 const struct config_param *param, GError **error)
{
	const char *value;
	char *endptr;

	value = config_get_block_string(param, "quality", NULL);
	if (value != NULL) {
		/* a quality was configured (VBR) */

		encoder->quality = g_ascii_strtod(value, &endptr);

		if (*endptr != '\0' || encoder->quality < -1.0 ||
		    encoder->quality > 10.0) {
			g_set_error(error, vorbis_encoder_quark(), 0,
				    "quality \"%s\" is not a number in the "
				    "range -1 to 10, line %i",
				    value, param->line);
			return false;
		}

		if (config_get_block_string(param, "bitrate", NULL) != NULL) {
			g_set_error(error, vorbis_encoder_quark(), 0,
				    "quality and bitrate are "
				    "both defined (line %i)",
				    param->line);
			return false;
		}
	} else {
		/* a bit rate was configured */

		value = config_get_block_string(param, "bitrate", NULL);
		if (value == NULL) {
			g_set_error(error, vorbis_encoder_quark(), 0,
				    "neither bitrate nor quality defined "
				    "at line %i",
				    param->line);
			return false;
		}

		encoder->quality = -2.0;
		encoder->bitrate = g_ascii_strtoll(value, &endptr, 10);

		if (*endptr != '\0' || encoder->bitrate <= 0) {
			g_set_error(error, vorbis_encoder_quark(), 0,
				    "bitrate at line %i should be a positive integer",
				    param->line);
			return false;
		}
	}

	return true;
}
Exemple #4
0
static struct mixer *
alsa_mixer_init(G_GNUC_UNUSED void *ao, const struct config_param *param,
		G_GNUC_UNUSED GError **error_r)
{
	struct alsa_mixer *am = g_new(struct alsa_mixer, 1);

	mixer_init(&am->base, &alsa_mixer_plugin);

	am->device = config_get_block_string(param, "mixer_device",
					     VOLUME_MIXER_ALSA_DEFAULT);
	am->control = config_get_block_string(param, "mixer_control",
					      VOLUME_MIXER_ALSA_CONTROL_DEFAULT);
	am->index = config_get_block_unsigned(param, "mixer_index",
					      VOLUME_MIXER_ALSA_INDEX_DEFAULT);

	return &am->base;
}
Exemple #5
0
static void *
winmm_output_init(G_GNUC_UNUSED const struct audio_format *audio_format,
		  G_GNUC_UNUSED const struct config_param *param,
		  G_GNUC_UNUSED GError **error)
{
	struct winmm_output *wo = g_new(struct winmm_output, 1);
	const char *device = config_get_block_string(param, "device", NULL);
	wo->device_id = get_device_id(device);
	return wo;
}
static bool
lastfm_init(const struct config_param *param)
{
	const char *user = config_get_block_string(param, "user", NULL);
	const char *passwd = config_get_block_string(param, "password", NULL);

	if (user == NULL || passwd == NULL) {
		g_debug("disabling the last.fm playlist plugin "
			"because account is not configured");
		return false;
	}

	lastfm_config.user = g_uri_escape_string(user, NULL, false);

	if (strlen(passwd) != 32)
		lastfm_config.md5 = g_compute_checksum_for_string(G_CHECKSUM_MD5,
								  passwd, strlen(passwd));
	else
		lastfm_config.md5 = g_strdup(passwd);

	return true;
}
static struct audio_output *
solaris_output_init(const struct config_param *param, GError **error_r)
{
	struct solaris_output *so = g_new(struct solaris_output, 1);

	if (!ao_base_init(&so->base, &solaris_output_plugin, param, error_r)) {
		g_free(so);
		return NULL;
	}

	so->device = config_get_block_string(param, "device", "/dev/audio");

	return &so->base;
}
static const struct config_param *
find_named_config_block(const char *block, const char *name)
{
	const struct config_param *param = NULL;

	while ((param = config_get_next_param(block, param)) != NULL) {
		const char *current_name =
			config_get_block_string(param, "name", NULL);
		if (current_name != NULL && strcmp(current_name, name) == 0)
			return param;
	}

	return NULL;
}
Exemple #9
0
static void *
httpd_output_init(G_GNUC_UNUSED const struct audio_format *audio_format,
		  const struct config_param *param,
		  GError **error)
{
	struct httpd_output *httpd = g_new(struct httpd_output, 1);
	const char *encoder_name;
	const struct encoder_plugin *encoder_plugin;
	guint port;
	struct sockaddr_in *sin;

	/* read configuration */

	port = config_get_block_unsigned(param, "port", 8000);

	encoder_name = config_get_block_string(param, "encoder", "vorbis");
	encoder_plugin = encoder_plugin_get(encoder_name);
	if (encoder_plugin == NULL) {
		g_set_error(error, httpd_output_quark(), 0,
			    "No such encoder: %s", encoder_name);
		return NULL;
	}

	if (strcmp(encoder_name, "vorbis") == 0)
		httpd->content_type = "application/x-ogg";
	else if (strcmp(encoder_name, "lame") == 0)
		httpd->content_type = "audio/mpeg";
	else
		httpd->content_type = "application/octet-stream";

	/* initialize listen address */

	sin = (struct sockaddr_in *)&httpd->address;
	memset(sin, 0, sizeof(sin));
	sin->sin_port = htons(port);
	sin->sin_family = AF_INET;
	sin->sin_addr.s_addr = INADDR_ANY;
	httpd->address_size = sizeof(*sin);

	/* initialize encoder */

	httpd->encoder = encoder_init(encoder_plugin, param, error);
	if (httpd->encoder == NULL)
		return NULL;

	httpd->mutex = g_mutex_new();

	return httpd;
}
static struct audio_output *
pulse_output_init(const struct config_param *param, GError **error_r)
{
	struct pulse_output *po;

	g_setenv("PULSE_PROP_media.role", "music", true);

	po = g_new(struct pulse_output, 1);
	if (!ao_base_init(&po->base, &pulse_output_plugin, param, error_r)) {
		g_free(po);
		return NULL;
	}

	po->name = config_get_block_string(param, "name", "mpd_pulse");
	po->server = config_get_block_string(param, "server", NULL);
	po->sink = config_get_block_string(param, "sink", NULL);

	po->mixer = NULL;
	po->mainloop = NULL;
	po->context = NULL;
	po->stream = NULL;

	return &po->base;
}
Exemple #11
0
/**
 * Determines the mixer type which should be used for the specified
 * configuration block.
 *
 * This handles the deprecated options mixer_type (global) and
 * mixer_enabled, if the mixer_type setting is not configured.
 */
static enum mixer_type
audio_output_mixer_type(const struct config_param *param)
{
	/* read the local "mixer_type" setting */
	const char *p = config_get_block_string(param, "mixer_type", NULL);
	if (p != NULL)
		return mixer_type_parse(p);

	/* try the local "mixer_enabled" setting next (deprecated) */
	if (!config_get_block_bool(param, "mixer_enabled", true))
		return MIXER_TYPE_NONE;

	/* fall back to the global "mixer_type" setting (also
	   deprecated) */
	return mixer_type_parse(config_get_string("mixer_type", "hardware"));
}
static bool
wildmidi_init(const struct config_param *param)
{
	const char *config_file;
	int ret;

	config_file = config_get_block_string(param, "config_file",
					      "/etc/timidity/timidity.cfg");
	if (!g_file_test(config_file, G_FILE_TEST_IS_REGULAR)) {
		g_debug("configuration file does not exist: %s", config_file);
		return false;
	}

	ret = WildMidi_Init(config_file, WILDMIDI_SAMPLE_RATE, 0);
	return ret == 0;
}
static void *
openal_init(G_GNUC_UNUSED const struct audio_format *audio_format,
	    const struct config_param *param,
	    G_GNUC_UNUSED GError **error)
{
	const char *device_name = config_get_block_string(param, "device", NULL);
	struct openal_data *od;

	if (device_name == NULL) {
		device_name = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
	}

	od = g_new(struct openal_data, 1);
	od->device_name = device_name;

	return od;
}
Exemple #14
0
static struct audio_output *
winmm_output_init(const struct config_param *param, GError **error_r)
{
	struct winmm_output *wo = g_new(struct winmm_output, 1);
	if (!ao_base_init(&wo->base, &winmm_output_plugin, param, error_r)) {
		g_free(wo);
		return NULL;
	}

	const char *device = config_get_block_string(param, "device", NULL);
	if (!get_device_id(device, &wo->device_id, error_r)) {
		ao_base_finish(&wo->base);
		g_free(wo);
		return NULL;
	}

	return &wo->base;
}
Exemple #15
0
/**
 * Find the "decoder" configuration block for the specified plugin.
 *
 * @param plugin_name the name of the decoder plugin
 * @return the configuration block, or NULL if none was configured
 */
static const struct config_param *
decoder_plugin_config(const char *plugin_name)
{
	const struct config_param *param = NULL;

	while ((param = config_get_next_param(CONF_DECODER, param)) != NULL) {
		const char *name =
			config_get_block_string(param, "plugin", NULL);
		if (name == NULL)
			g_error("decoder configuration without 'plugin' name in line %d",
				param->line);

		if (strcmp(name, plugin_name) == 0)
			return param;
	}

	return NULL;
}
Exemple #16
0
static void
osx_output_configure(struct osx_output *oo, const struct config_param *param)
{
	const char *device = config_get_block_string(param, "device", NULL);

	if (device == NULL || 0 == strcmp(device, "default")) {
		oo->component_subtype = kAudioUnitSubType_DefaultOutput;
		oo->device_name = NULL;
	}
	else if (0 == strcmp(device, "system")) {
		oo->component_subtype = kAudioUnitSubType_SystemOutput;
		oo->device_name = NULL;
	}
	else {
		oo->component_subtype = kAudioUnitSubType_HALOutput;
		/* XXX am I supposed to g_strdup() this? */
		oo->device_name = device;
	}
}
/**
 * Find the "playlist" configuration block for the specified plugin.
 *
 * @param plugin_name the name of the playlist plugin
 * @return the configuration block, or NULL if none was configured
 */
static const struct config_param *
playlist_plugin_config(const char *plugin_name)
{
	const struct config_param *param = NULL;

	assert(plugin_name != NULL);

	while ((param = config_get_next_param(CONF_PLAYLIST_PLUGIN, param)) != NULL) {
		const char *name =
			config_get_block_string(param, "name", NULL);
		if (name == NULL)
			g_error("playlist configuration without 'plugin' name in line %d",
				param->line);

		if (strcmp(name, plugin_name) == 0)
			return param;
	}

	return NULL;
}
Exemple #18
0
/**
 * Find the "input" configuration block for the specified plugin.
 *
 * @param plugin_name the name of the input plugin
 * @return the configuration block, or NULL if none was configured
 */
static const struct config_param *
input_plugin_config(const char *plugin_name, GError **error_r)
{
	const struct config_param *param = NULL;

	while ((param = config_get_next_param(CONF_INPUT, param)) != NULL) {
		const char *name =
			config_get_block_string(param, "plugin", NULL);
		if (name == NULL) {
			g_set_error(error_r, input_quark(), 0,
				    "input configuration without 'plugin' name in line %d",
				    param->line);
			return NULL;
		}

		if (strcmp(name, plugin_name) == 0)
			return param;
	}

	return NULL;
}
Exemple #19
0
static bool
fluidsynth_init(const struct config_param *param)
{
	GError *error = NULL;

	sample_rate = config_get_block_unsigned(param, "sample_rate", 48000);
	if (!audio_check_sample_rate(sample_rate, &error)) {
		g_warning("%s\n", error->message);
		g_error_free(error);
		return false;
	}

	soundfont_path =
		config_get_block_string(param, "soundfont",
					"/usr/share/sounds/sf2/FluidR3_GM.sf2");

	fluid_set_log_function(LAST_LOG_LEVEL,
			       fluidsynth_mpd_log_function, NULL);

	return true;
}
Exemple #20
0
bool
audio_output_init(struct audio_output *ao, const struct config_param *param,
		  GError **error_r)
{
	const struct audio_output_plugin *plugin = NULL;
	GError *error = NULL;

	if (param) {
		const char *p;

		p = config_get_block_string(param, AUDIO_OUTPUT_TYPE, NULL);
		if (p == NULL) {
			g_set_error(error_r, audio_output_quark(), 0,
				    "Missing \"type\" configuration");
			return false;
		}

		plugin = audio_output_plugin_get(p);
		if (plugin == NULL) {
			g_set_error(error_r, audio_output_quark(), 0,
				    "No such audio output plugin: %s", p);
			return false;
		}

		ao->name = config_get_block_string(param, AUDIO_OUTPUT_NAME,
						   NULL);
		if (ao->name == NULL) {
			g_set_error(error_r, audio_output_quark(), 0,
				    "Missing \"name\" configuration");
			return false;
		}

		p = config_get_block_string(param, AUDIO_OUTPUT_FORMAT,
						 NULL);
		if (p != NULL) {
			bool success =
				audio_format_parse(&ao->config_audio_format,
						   p, true, error_r);
			if (!success)
				return false;
		} else
			audio_format_clear(&ao->config_audio_format);
	} else {
		g_warning("No \"%s\" defined in config file\n",
			  CONF_AUDIO_OUTPUT);

		plugin = audio_output_detect(error_r);
		if (plugin == NULL)
			return false;

		g_message("Successfully detected a %s audio device",
			  plugin->name);

		ao->name = "default detected output";

		audio_format_clear(&ao->config_audio_format);
	}

	ao->plugin = plugin;
	ao->always_on = config_get_block_bool(param, "always_on", false);
	ao->enabled = config_get_block_bool(param, "enabled", true);
	ao->really_enabled = false;
	ao->open = false;
	ao->pause = false;
	ao->fail_timer = NULL;

	pcm_buffer_init(&ao->cross_fade_buffer);

	/* set up the filter chain */

	ao->filter = filter_chain_new();
	assert(ao->filter != NULL);

	/* create the replay_gain filter */

	const char *replay_gain_handler =
		config_get_block_string(param, "replay_gain_handler",
					"software");

	if (strcmp(replay_gain_handler, "none") != 0) {
		ao->replay_gain_filter = filter_new(&replay_gain_filter_plugin,
						    param, NULL);
		assert(ao->replay_gain_filter != NULL);

		ao->replay_gain_serial = 0;

		ao->other_replay_gain_filter = filter_new(&replay_gain_filter_plugin,
							  param, NULL);
		assert(ao->other_replay_gain_filter != NULL);

		ao->other_replay_gain_serial = 0;
	} else {
		ao->replay_gain_filter = NULL;
		ao->other_replay_gain_filter = NULL;
	}

	/* create the normalization filter (if configured) */

	if (config_get_bool(CONF_VOLUME_NORMALIZATION, false)) {
		struct filter *normalize_filter =
			filter_new(&normalize_filter_plugin, NULL, NULL);
		assert(normalize_filter != NULL);

		filter_chain_append(ao->filter,
				    autoconvert_filter_new(normalize_filter));
	}

	filter_chain_parse(ao->filter,
	                   config_get_block_string(param, AUDIO_FILTERS, ""),
	                   &error
	);

	// It's not really fatal - Part of the filter chain has been set up already
	// and even an empty one will work (if only with unexpected behaviour)
	if (error != NULL) {
		g_warning("Failed to initialize filter chain for '%s': %s",
			  ao->name, error->message);
		g_error_free(error);
	}

	ao->thread = NULL;
	ao->command = AO_COMMAND_NONE;
	ao->mutex = g_mutex_new();
	ao->cond = g_cond_new();

	ao->data = ao_plugin_init(plugin,
				  &ao->config_audio_format,
				  param, error_r);
	if (ao->data == NULL)
		return false;

	ao->mixer = audio_output_load_mixer(ao->data, param,
					    plugin->mixer_plugin,
					    ao->filter, &error);
	if (ao->mixer == NULL && error != NULL) {
		g_warning("Failed to initialize hardware mixer for '%s': %s",
			  ao->name, error->message);
		g_error_free(error);
	}

	/* use the hardware mixer for replay gain? */

	if (strcmp(replay_gain_handler, "mixer") == 0) {
		if (ao->mixer != NULL)
			replay_gain_filter_set_mixer(ao->replay_gain_filter,
						     ao->mixer, 100);
		else
			g_warning("No such mixer for output '%s'", ao->name);
	} else if (strcmp(replay_gain_handler, "software") != 0 &&
		   ao->replay_gain_filter != NULL) {
		g_set_error(error_r, audio_output_quark(), 0,
			    "Invalid \"replay_gain_handler\" value");
		return false;
	}

	/* the "convert" filter must be the last one in the chain */

	ao->convert_filter = filter_new(&convert_filter_plugin, NULL, NULL);
	assert(ao->convert_filter != NULL);

	filter_chain_append(ao->filter, ao->convert_filter);

	/* done */

	return true;
}
	port = config_get_block_unsigned(param, "port", 0);
	if (port == 0) {
		g_set_error(error, shout_output_quark(), 0,
			    "shout port must be configured");
		return NULL;
	}

	check_block_param("password");
	passwd = block_param->value;

	check_block_param("name");
	name = block_param->value;

	public = config_get_block_bool(param, "public", false);

	user = config_get_block_string(param, "user", "source");

	value = config_get_block_string(param, "quality", NULL);
	if (value != NULL) {
		sd->quality = strtod(value, &test);

		if (*test != '\0' || sd->quality < -1.0 || sd->quality > 10.0) {
			g_set_error(error, shout_output_quark(), 0,
				    "shout quality \"%s\" is not a number in the "
				    "range -1 to 10, line %i",
				    value, param->line);
			return NULL;
		}

		if (config_get_block_string(param, "bitrate", NULL) != NULL) {
			g_set_error(error, shout_output_quark(), 0,
/**
 * Parse the "routes" section, a string on the form
 *  a>b, c>d, e>f, ...
 * where a... are non-unique, non-negative integers
 * and input channel a gets copied to output channel b, etc.
 * @param param the configuration block to read
 * @param filter a route_filter whose min_channels and sources[] to set
 * @return true on success, false on error
 */
static bool
route_filter_parse(const struct config_param *param,
		   struct route_filter *filter,
		   GError **error_r) {

	/* TODO:
	 * With a more clever way of marking "don't copy to output N",
	 * This could easily be merged into a single loop with some
	 * dynamic g_realloc() instead of one count run and one g_malloc().
	 */

	gchar **tokens;
	int number_of_copies;

	// A cowardly default, just passthrough stereo
	const char *routes =
		config_get_block_string(param, "routes", "0>0, 1>1");

	filter->min_input_channels = 0;
	filter->min_output_channels = 0;

	tokens = g_strsplit(routes, ",", 255);
	number_of_copies = g_strv_length(tokens);

	// Start by figuring out a few basic things about the routing set
	for (int c=0; c<number_of_copies; ++c) {

		// String and int representations of the source/destination
		gchar **sd;
		int source, dest;

		// Squeeze whitespace
		g_strstrip(tokens[c]);

		// Split the a>b string into source and destination
		sd = g_strsplit(tokens[c], ">", 2);
		if (g_strv_length(sd) != 2) {
			g_set_error(error_r, config_quark(), 1,
				"Invalid copy around %d in routes spec: %s",
				param->line, tokens[c]);
			g_strfreev(sd);
			g_strfreev(tokens);
			return false;
		}

		source = strtol(sd[0], NULL, 10);
		dest = strtol(sd[1], NULL, 10);

		// Keep track of the highest channel numbers seen
		// as either in- or outputs
		if (source >= filter->min_input_channels)
			filter->min_input_channels = source + 1;
		if (dest   >= filter->min_output_channels)
			filter->min_output_channels = dest + 1;

		g_strfreev(sd);
	}

	if (!audio_valid_channel_count(filter->min_output_channels)) {
		g_strfreev(tokens);
		g_set_error(error_r, audio_format_quark(), 0,
			    "Invalid number of output channels requested: %d",
			    filter->min_output_channels);
		return false;
	}

	// Allocate a map of "copy nothing to me"
	filter->sources =
		g_malloc(filter->min_output_channels * sizeof(signed char));

	for (int i=0; i<filter->min_output_channels; ++i)
		filter->sources[i] = -1;

	// Run through the spec again, and save the
	// actual mapping output <- input
	for (int c=0; c<number_of_copies; ++c) {

		// String and int representations of the source/destination
		gchar **sd;
		int source, dest;

		// Split the a>b string into source and destination
		sd = g_strsplit(tokens[c], ">", 2);
		if (g_strv_length(sd) != 2) {
			g_set_error(error_r, config_quark(), 1,
				"Invalid copy around %d in routes spec: %s",
				param->line, tokens[c]);
			g_strfreev(sd);
			g_strfreev(tokens);
			return false;
		}

		source = strtol(sd[0], NULL, 10);
		dest = strtol(sd[1], NULL, 10);

		filter->sources[dest] = source;

		g_strfreev(sd);
	}

	g_strfreev(tokens);

	return true;
}
static struct audio_output *
httpd_output_init(const struct config_param *param,
		  GError **error)
{
	struct httpd_output *httpd = g_new(struct httpd_output, 1);
	if (!ao_base_init(&httpd->base, &httpd_output_plugin, param, error)) {
		g_free(httpd);
		return NULL;
	}

	const char *encoder_name, *bind_to_address;
	const struct encoder_plugin *encoder_plugin;
	guint port;

	/* read configuration */
	httpd->name =
		config_get_block_string(param, "name", "Set name in config");
	httpd->genre =
		config_get_block_string(param, "genre", "Set genre in config");
	httpd->website =
		config_get_block_string(param, "website", "Set website in config");

	port = config_get_block_unsigned(param, "port", 8000);

	encoder_name = config_get_block_string(param, "encoder", "vorbis");
	encoder_plugin = encoder_plugin_get(encoder_name);
	if (encoder_plugin == NULL) {
		g_set_error(error, httpd_output_quark(), 0,
			    "No such encoder: %s", encoder_name);
		ao_base_finish(&httpd->base);
		g_free(httpd);
		return NULL;
	}

	httpd->clients_max = config_get_block_unsigned(param,"max_clients", 0);

	/* set up bind_to_address */

	httpd->server_socket = server_socket_new(httpd_listen_in_event, httpd);

	bind_to_address =
		config_get_block_string(param, "bind_to_address", NULL);
	bool success = bind_to_address != NULL &&
		strcmp(bind_to_address, "any") != 0
		? server_socket_add_host(httpd->server_socket, bind_to_address,
					 port, error)
		: server_socket_add_port(httpd->server_socket, port, error);
	if (!success) {
		ao_base_finish(&httpd->base);
		g_free(httpd);
		return NULL;
	}

	/* initialize metadata */
	httpd->metadata = NULL;
	httpd->unflushed_input = 0;

	/* initialize encoder */

	httpd->encoder = encoder_init(encoder_plugin, param, error);
	if (httpd->encoder == NULL) {
		ao_base_finish(&httpd->base);
		g_free(httpd);
		return NULL;
	}

	/* determine content type */
	httpd->content_type = encoder_get_mime_type(httpd->encoder);
	if (httpd->content_type == NULL) {
		httpd->content_type = "application/octet-stream";
	}

	httpd->mutex = g_mutex_new();

	return &httpd->base;
}
Exemple #24
0
static struct audio_output *
ao_output_init(const struct config_param *param,
	       GError **error)
{
	struct ao_data *ad = g_new(struct ao_data, 1);

	if (!ao_base_init(&ad->base, &ao_output_plugin, param, error)) {
		g_free(ad);
		return NULL;
	}

	ao_info *ai;
	const char *value;

	ad->options = NULL;

	ad->write_size = config_get_block_unsigned(param, "write_size", 1024);

	if (ao_output_ref == 0) {
		ao_initialize();
	}
	ao_output_ref++;

	value = config_get_block_string(param, "driver", "default");
	if (0 == strcmp(value, "default"))
		ad->driver = ao_default_driver_id();
	else
		ad->driver = ao_driver_id(value);

	if (ad->driver < 0) {
		g_set_error(error, ao_output_quark(), 0,
			    "\"%s\" is not a valid ao driver",
			    value);
		ao_base_finish(&ad->base);
		g_free(ad);
		return NULL;
	}

	if ((ai = ao_driver_info(ad->driver)) == NULL) {
		g_set_error(error, ao_output_quark(), 0,
			    "problems getting driver info");
		ao_base_finish(&ad->base);
		g_free(ad);
		return NULL;
	}

	g_debug("using ao driver \"%s\" for \"%s\"\n", ai->short_name,
		config_get_block_string(param, "name", NULL));

	value = config_get_block_string(param, "options", NULL);
	if (value != NULL) {
		gchar **options = g_strsplit(value, ";", 0);

		for (unsigned i = 0; options[i] != NULL; ++i) {
			gchar **key_value = g_strsplit(options[i], "=", 2);

			if (key_value[0] == NULL || key_value[1] == NULL) {
				g_set_error(error, ao_output_quark(), 0,
					    "problems parsing options \"%s\"",
					    options[i]);
				ao_base_finish(&ad->base);
				g_free(ad);
				return NULL;
			}

			ao_append_option(&ad->options, key_value[0],
					 key_value[1]);

			g_strfreev(key_value);
		}

		g_strfreev(options);
	}

	return &ad->base;
}