aboutsummaryrefslogtreecommitdiff
path: root/src/filter
diff options
context:
space:
mode:
Diffstat (limited to 'src/filter')
-rw-r--r--src/filter/replay_gain_filter_plugin.c45
-rw-r--r--src/filter/replay_gain_filter_plugin.h13
2 files changed, 58 insertions, 0 deletions
diff --git a/src/filter/replay_gain_filter_plugin.c b/src/filter/replay_gain_filter_plugin.c
index 248690d1..c8e74c7f 100644
--- a/src/filter/replay_gain_filter_plugin.c
+++ b/src/filter/replay_gain_filter_plugin.c
@@ -27,7 +27,9 @@
#include "pcm_volume.h"
#include "replay_gain_info.h"
#include "replay_gain_config.h"
+#include "mixer_control.h"
+#include <assert.h>
#include <string.h>
#undef G_LOG_DOMAIN
@@ -36,6 +38,18 @@
struct replay_gain_filter {
struct filter filter;
+ /**
+ * If set, then this hardware mixer is used for applying
+ * replay gain, instead of the software volume library.
+ */
+ struct mixer *mixer;
+
+ /**
+ * The base volume level for scale=1.0, between 1 and 100
+ * (including).
+ */
+ unsigned base;
+
enum replay_gain_mode mode;
struct replay_gain_info info;
@@ -74,6 +88,21 @@ replay_gain_filter_update(struct replay_gain_filter *filter)
filter->volume = pcm_float_to_volume(scale);
} else
filter->volume = PCM_VOLUME_1;
+
+ if (filter->mixer != NULL) {
+ /* update the hardware mixer volume */
+
+ unsigned volume = (filter->volume * filter->base) / PCM_VOLUME_1;
+ if (volume > 100)
+ volume = 100;
+
+ GError *error = NULL;
+ if (!mixer_set_volume(filter->mixer, volume, &error)) {
+ g_warning("Failed to update hardware mixer: %s",
+ error->message);
+ g_error_free(error);
+ }
+ }
}
static struct filter *
@@ -83,6 +112,7 @@ replay_gain_filter_init(G_GNUC_UNUSED const struct config_param *param,
struct replay_gain_filter *filter = g_new(struct replay_gain_filter, 1);
filter_init(&filter->filter, &replay_gain_filter_plugin);
+ filter->mixer = NULL;
filter->mode = replay_gain_mode;
replay_gain_info_init(&filter->info);
@@ -178,6 +208,21 @@ const struct filter_plugin replay_gain_filter_plugin = {
};
void
+replay_gain_filter_set_mixer(struct filter *_filter, struct mixer *mixer,
+ unsigned base)
+{
+ struct replay_gain_filter *filter =
+ (struct replay_gain_filter *)_filter;
+
+ assert(mixer == NULL || (base > 0 && base <= 100));
+
+ filter->mixer = mixer;
+ filter->base = base;
+
+ replay_gain_filter_update(filter);
+}
+
+void
replay_gain_filter_set_info(struct filter *_filter,
const struct replay_gain_info *info)
{
diff --git a/src/filter/replay_gain_filter_plugin.h b/src/filter/replay_gain_filter_plugin.h
index 4ab9f42a..348b4f50 100644
--- a/src/filter/replay_gain_filter_plugin.h
+++ b/src/filter/replay_gain_filter_plugin.h
@@ -23,6 +23,19 @@
#include "replay_gain_info.h"
struct filter;
+struct mixer;
+
+/**
+ * Enables or disables the hardware mixer for applying replay gain.
+ *
+ * @param mixer the hardware mixer, or NULL to fall back to software
+ * volume
+ * @param base the base volume level for scale=1.0, between 1 and 100
+ * (including).
+ */
+void
+replay_gain_filter_set_mixer(struct filter *_filter, struct mixer *mixer,
+ unsigned base);
/**
* Sets a new #replay_gain_info at the beginning of a new song.