diff options
Diffstat (limited to 'src/output_init.c')
-rw-r--r-- | src/output_init.c | 116 |
1 files changed, 92 insertions, 24 deletions
diff --git a/src/output_init.c b/src/output_init.c index 04609bb76..08873ac20 100644 --- a/src/output_init.c +++ b/src/output_init.c @@ -23,9 +23,17 @@ #include "output_list.h" #include "audio_parser.h" #include "mixer_control.h" +#include "mixer_type.h" +#include "mixer_list.h" +#include "mixer/software_mixer_plugin.h" +#include "filter_plugin.h" +#include "filter_registry.h" +#include "filter/chain_filter_plugin.h" #include <glib.h> +#include <assert.h> + #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "output" @@ -56,28 +64,81 @@ audio_output_detect(GError **error) return NULL; } +/** + * 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 struct mixer * +audio_output_load_mixer(const struct config_param *param, + const struct mixer_plugin *plugin, + struct filter *filter_chain) +{ + struct mixer *mixer; + + switch (audio_output_mixer_type(param)) { + case MIXER_TYPE_NONE: + case MIXER_TYPE_UNKNOWN: + return NULL; + + case MIXER_TYPE_HARDWARE: + if (plugin == NULL) + return NULL; + + return mixer_new(plugin, param); + + case MIXER_TYPE_SOFTWARE: + mixer = mixer_new(&software_mixer_plugin, NULL); + assert(mixer != NULL); + + filter_chain_append(filter_chain, + software_mixer_get_filter(mixer)); + return mixer; + } + + assert(false); + return NULL; +} + bool audio_output_init(struct audio_output *ao, const struct config_param *param, GError **error) { - const char *format; const struct audio_output_plugin *plugin = NULL; if (param) { - const char *type = NULL; + const char *p; - type = config_get_block_string(param, AUDIO_OUTPUT_TYPE, NULL); - if (type == NULL) { + p = config_get_block_string(param, AUDIO_OUTPUT_TYPE, NULL); + if (p == NULL) { g_set_error(error, audio_output_quark(), 0, "Missing \"type\" configuration"); return false; } - plugin = audio_output_plugin_get(type); + plugin = audio_output_plugin_get(p); if (plugin == NULL) { g_set_error(error, audio_output_quark(), 0, - "No such audio output plugin: %s", - type); + "No such audio output plugin: %s", p); return false; } @@ -89,8 +150,16 @@ audio_output_init(struct audio_output *ao, const struct config_param *param, return false; } - format = config_get_block_string(param, AUDIO_OUTPUT_FORMAT, + p = config_get_block_string(param, AUDIO_OUTPUT_FORMAT, NULL); + ao->config_audio_format = p != NULL; + if (p != NULL) { + bool success = + audio_format_parse(&ao->out_audio_format, + p, error); + if (!success) + return false; + } } else { g_warning("No \"%s\" defined in config file\n", CONF_AUDIO_OUTPUT); @@ -103,7 +172,7 @@ audio_output_init(struct audio_output *ao, const struct config_param *param, plugin->name); ao->name = "default detected output"; - format = NULL; + ao->config_audio_format = false; } ao->plugin = plugin; @@ -111,17 +180,10 @@ audio_output_init(struct audio_output *ao, const struct config_param *param, ao->open = false; ao->fail_timer = NULL; - pcm_convert_init(&ao->convert_state); + /* set up the filter chain */ - ao->config_audio_format = format != NULL; - if (ao->config_audio_format) { - bool ret; - - ret = audio_format_parse(&ao->out_audio_format, format, - error); - if (!ret) - return false; - } + ao->filter = filter_chain_new(); + assert(ao->filter != NULL); ao->thread = NULL; notify_init(&ao->notify); @@ -135,11 +197,17 @@ audio_output_init(struct audio_output *ao, const struct config_param *param, if (ao->data == NULL) return false; - if (plugin->mixer_plugin != NULL && - config_get_block_bool(param, "mixer_enabled", true)) - ao->mixer = mixer_new(plugin->mixer_plugin, param); - else - ao->mixer = NULL; + ao->mixer = audio_output_load_mixer(param, plugin->mixer_plugin, + ao->filter); + + /* 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; } |