diff options
Diffstat (limited to 'src/filter/replay_gain_filter_plugin.c')
-rw-r--r-- | src/filter/replay_gain_filter_plugin.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/filter/replay_gain_filter_plugin.c b/src/filter/replay_gain_filter_plugin.c index 248690d17..c8e74c7fe 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) { |