aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mixer_control.c13
-rw-r--r--src/mixer_control.h3
-rw-r--r--src/output_init.c58
-rw-r--r--src/player_control.c11
-rw-r--r--src/player_control.h3
-rw-r--r--src/player_thread.c14
-rw-r--r--src/volume.c79
7 files changed, 60 insertions, 121 deletions
diff --git a/src/mixer_control.c b/src/mixer_control.c
index a17885935..927a1276c 100644
--- a/src/mixer_control.c
+++ b/src/mixer_control.c
@@ -28,24 +28,11 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "mixer"
-static bool mixers_enabled = true;
-
-void
-mixer_disable_all(void)
-{
- g_debug("mixer api is disabled");
- mixers_enabled = false;
-}
-
struct mixer *
mixer_new(const struct mixer_plugin *plugin, const struct config_param *param)
{
struct mixer *mixer;
- //mixers are disabled (by using software volume)
- if (!mixers_enabled) {
- return NULL;
- }
assert(plugin != NULL);
mixer = plugin->init(param);
diff --git a/src/mixer_control.h b/src/mixer_control.h
index 0f73e8f75..b8997a795 100644
--- a/src/mixer_control.h
+++ b/src/mixer_control.h
@@ -31,9 +31,6 @@ struct mixer;
struct mixer_plugin;
struct config_param;
-void
-mixer_disable_all(void);
-
struct mixer *
mixer_new(const struct mixer_plugin *plugin, const struct config_param *param);
diff --git a/src/output_init.c b/src/output_init.c
index eba665e77..08873ac20 100644
--- a/src/output_init.c
+++ b/src/output_init.c
@@ -23,6 +23,9 @@
#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"
@@ -61,17 +64,59 @@ 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)
+ const struct mixer_plugin *plugin,
+ struct filter *filter_chain)
{
- if (!config_get_block_bool(param, "mixer_enabled", true))
- return NULL;
+ struct mixer *mixer;
- if (plugin == NULL)
+ switch (audio_output_mixer_type(param)) {
+ case MIXER_TYPE_NONE:
+ case MIXER_TYPE_UNKNOWN:
return NULL;
- return mixer_new(plugin, param);
+ 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
@@ -152,7 +197,8 @@ audio_output_init(struct audio_output *ao, const struct config_param *param,
if (ao->data == NULL)
return false;
- ao->mixer = audio_output_load_mixer(param, plugin->mixer_plugin);
+ ao->mixer = audio_output_load_mixer(param, plugin->mixer_plugin,
+ ao->filter);
/* the "convert" filter must be the last one in the chain */
diff --git a/src/player_control.c b/src/player_control.c
index ac4b006dd..df80ac4ff 100644
--- a/src/player_control.c
+++ b/src/player_control.c
@@ -40,7 +40,6 @@ void pc_init(unsigned buffer_chunks, unsigned int buffered_before_play)
pc.error = PLAYER_ERROR_NOERROR;
pc.state = PLAYER_STATE_STOP;
pc.cross_fade_seconds = 0;
- pc.software_volume = PCM_VOLUME_1;
}
void pc_deinit(void)
@@ -253,16 +252,6 @@ void setPlayerCrossFade(float crossFadeInSeconds)
idle_add(IDLE_OPTIONS);
}
-void setPlayerSoftwareVolume(int volume)
-{
- if (volume > PCM_VOLUME_1)
- volume = PCM_VOLUME_1;
- else if (volume < 0)
- volume = 0;
-
- pc.software_volume = volume;
-}
-
double getPlayerTotalPlayTime(void)
{
return pc.total_play_time;
diff --git a/src/player_control.h b/src/player_control.h
index b1f7481cd..0cc3c73a8 100644
--- a/src/player_control.h
+++ b/src/player_control.h
@@ -81,7 +81,6 @@ struct player_control {
struct song *errored_song;
volatile double seek_where;
float cross_fade_seconds;
- uint16_t software_volume;
double total_play_time;
};
@@ -145,8 +144,6 @@ void setPlayerCrossFade(float crossFadeInSeconds);
float getPlayerCrossFade(void);
-void setPlayerSoftwareVolume(int volume);
-
double getPlayerTotalPlayTime(void);
static inline const struct audio_format *
diff --git a/src/player_thread.c b/src/player_thread.c
index 7fc55d3d1..657968f6c 100644
--- a/src/player_thread.c
+++ b/src/player_thread.c
@@ -423,8 +423,6 @@ static bool
play_chunk(struct song *song, struct music_chunk *chunk,
const struct audio_format *format, double sizeToTime)
{
- bool success;
-
assert(music_chunk_check_format(chunk, format));
if (chunk->tag != NULL) {
@@ -455,18 +453,6 @@ play_chunk(struct song *song, struct music_chunk *chunk,
pc.elapsed_time = chunk->times;
pc.bit_rate = chunk->bit_rate;
- /* apply software volume */
-
- success = pcm_volume(chunk->data, chunk->length,
- format, pc.software_volume);
- if (!success) {
- g_warning("pcm_volume() failed on %u:%u:%u",
- format->sample_rate, format->bits, format->channels);
- pc.errored_song = dc.current_song;
- pc.error = PLAYER_ERROR_AUDIO;
- return false;
- }
-
/* send the chunk to the audio outputs */
if (!audio_output_all_play(chunk)) {
diff --git a/src/volume.c b/src/volume.c
index 3d240f4e4..3e6079cd6 100644
--- a/src/volume.c
+++ b/src/volume.c
@@ -40,8 +40,6 @@
#define SW_VOLUME_STATE "sw_volume: "
-static enum mixer_type volume_mixer_type = MIXER_TYPE_HARDWARE;
-
static unsigned volume_software_set = 100;
/** the cached hardware mixer value; invalid if negative */
@@ -51,37 +49,15 @@ static GTimer *hardware_volume_timer;
void volume_finish(void)
{
- if (volume_mixer_type == MIXER_TYPE_HARDWARE)
- g_timer_destroy(hardware_volume_timer);
+ g_timer_destroy(hardware_volume_timer);
}
void volume_init(void)
{
- const struct config_param *param = config_get_param(CONF_MIXER_TYPE);
- //hw mixing is by default
- if (param) {
- volume_mixer_type = mixer_type_parse(param->value);
- switch (volume_mixer_type) {
- case MIXER_TYPE_NONE:
- case MIXER_TYPE_SOFTWARE:
- mixer_disable_all();
- break;
-
- case MIXER_TYPE_HARDWARE:
- //nothing to do
- break;
-
- case MIXER_TYPE_UNKNOWN:
- g_error("unknown mixer type %s at line %i\n",
- param->value, param->line);
- }
- }
-
- if (volume_mixer_type == MIXER_TYPE_HARDWARE)
- hardware_volume_timer = g_timer_new();
+ hardware_volume_timer = g_timer_new();
}
-static int hardware_volume_get(void)
+int volume_level_get(void)
{
assert(hardware_volume_timer != NULL);
@@ -95,43 +71,12 @@ static int hardware_volume_get(void)
return last_hardware_volume;
}
-static int software_volume_get(void)
-{
- return volume_software_set;
-}
-
-int volume_level_get(void)
-{
- switch (volume_mixer_type) {
- case MIXER_TYPE_SOFTWARE:
- return software_volume_get();
- case MIXER_TYPE_HARDWARE:
- return hardware_volume_get();
- case MIXER_TYPE_NONE:
- case MIXER_TYPE_UNKNOWN:
- return -1;
- }
-
- /* unreachable */
- assert(false);
- return -1;
-}
-
static bool software_volume_change(unsigned volume)
{
assert(volume <= 100);
volume_software_set = volume;
-
- if (volume >= 100)
- volume = PCM_VOLUME_1;
- else if (volume <= 0)
- volume = 0;
- else
- volume = pcm_float_to_volume((exp(volume / 25.0) - 1) /
- (54.5981500331F - 1));
-
- setPlayerSoftwareVolume(volume);
+ mixer_all_set_software_volume(volume);
return true;
}
@@ -148,16 +93,11 @@ bool volume_level_change(unsigned volume)
{
assert(volume <= 100);
+ volume_software_set = volume;
+
idle_add(IDLE_MIXER);
- switch (volume_mixer_type) {
- case MIXER_TYPE_HARDWARE:
- return hardware_volume_change(volume);
- case MIXER_TYPE_SOFTWARE:
- return software_volume_change(volume);
- default:
- return true;
- }
+ return hardware_volume_change(volume);
}
void read_sw_volume_state(FILE *fp)
@@ -166,8 +106,6 @@ void read_sw_volume_state(FILE *fp)
char *end = NULL;
long int sv;
- if (volume_mixer_type != MIXER_TYPE_SOFTWARE)
- return;
while (fgets(buf, sizeof(buf), fp)) {
if (!g_str_has_prefix(buf, SW_VOLUME_STATE))
continue;
@@ -184,6 +122,5 @@ void read_sw_volume_state(FILE *fp)
void save_sw_volume_state(FILE *fp)
{
- if (volume_mixer_type == MIXER_TYPE_SOFTWARE)
- fprintf(fp, SW_VOLUME_STATE "%u\n", volume_software_set);
+ fprintf(fp, SW_VOLUME_STATE "%u\n", volume_software_set);
}