diff --git a/Makefile.am b/Makefile.am index d7551c11f..c37a6cca8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -97,6 +97,7 @@ mpd_headers = \ src/event_pipe.h \ src/mixer_plugin.h \ src/mixer_type.h \ + src/mixer/software_mixer_plugin.h \ src/daemon.h \ src/normalize.h \ src/compress.h \ @@ -522,7 +523,8 @@ MIXER_API_SRC = \ src/mixer_all.c \ src/mixer_api.c -MIXER_SRC = +MIXER_SRC = \ + src/mixer/software_mixer_plugin.c if HAVE_ALSA OUTPUT_SRC += src/output/alsa_plugin.c @@ -741,6 +743,8 @@ test_run_output_SOURCES = test/run_output.c \ $(MIXER_SRC) \ src/filter_plugin.c src/filter/chain_filter_plugin.c \ src/filter/convert_filter_plugin.c \ + src/filter/volume_filter_plugin.c \ + src/pcm_volume.c \ $(OUTPUT_SRC) test_read_mixer_CPPFLAGS = $(AM_CPPFLAGS) \ @@ -751,6 +755,8 @@ test_read_mixer_LDADD = $(MPD_LIBS) \ test_read_mixer_SOURCES = test/read_mixer.c \ src/conf.c src/buffer2array.c src/utils.c src/log.c \ src/mixer_control.c src/mixer_api.c \ + src/filter_plugin.c \ + src/filter/volume_filter_plugin.c \ $(MIXER_SRC) endif diff --git a/src/filter/volume_filter_plugin.c b/src/filter/volume_filter_plugin.c index efad3362f..039619917 100644 --- a/src/filter/volume_filter_plugin.c +++ b/src/filter/volume_filter_plugin.c @@ -25,6 +25,7 @@ #include "pcm_buffer.h" #include "pcm_volume.h" #include "audio_format.h" +#include "player_control.h" #include #include diff --git a/src/mixer/software_mixer_plugin.c b/src/mixer/software_mixer_plugin.c new file mode 100644 index 000000000..661334e1b --- /dev/null +++ b/src/mixer/software_mixer_plugin.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "software_mixer_plugin.h" +#include "mixer_api.h" +#include "filter_plugin.h" +#include "filter_registry.h" +#include "filter/volume_filter_plugin.h" +#include "pcm_volume.h" + +#include +#include + +struct software_mixer { + /** the base mixer class */ + struct mixer base; + + struct filter *filter; + + unsigned volume; +}; + +static struct mixer * +software_mixer_init(G_GNUC_UNUSED const struct config_param *param) +{ + struct software_mixer *sm = g_new(struct software_mixer, 1); + + mixer_init(&sm->base, &software_mixer_plugin); + + sm->filter = filter_new(&volume_filter_plugin, NULL, NULL); + assert(sm->filter != NULL); + + sm->volume = 100; + + return &sm->base; +} + +static void +software_mixer_finish(struct mixer *data) +{ + struct software_mixer *sm = (struct software_mixer *)data; + + g_free(sm); +} + +static bool +software_mixer_open(struct mixer *data) +{ + struct software_mixer *sm = (struct software_mixer *)data; + + (void)sm; + return true; +} + +static void +software_mixer_close(struct mixer *data) +{ + struct software_mixer *sm = (struct software_mixer *)data; + + (void)sm; +} + +static int +software_mixer_get_volume(struct mixer *mixer) +{ + struct software_mixer *sm = (struct software_mixer *)mixer; + + return sm->volume; +} + +static bool +software_mixer_set_volume(struct mixer *mixer, unsigned volume) +{ + struct software_mixer *sm = (struct software_mixer *)mixer; + + assert(volume <= 100); + + sm->volume = volume; + + if (volume >= 100) + volume = PCM_VOLUME_1; + else if (volume > 0) + volume = pcm_float_to_volume((exp(volume / 25.0) - 1) / + (54.5981500331F - 1)); + + volume_filter_set(sm->filter, volume); + return true; +} + +const struct mixer_plugin software_mixer_plugin = { + .init = software_mixer_init, + .finish = software_mixer_finish, + .open = software_mixer_open, + .close = software_mixer_close, + .get_volume = software_mixer_get_volume, + .set_volume = software_mixer_set_volume, + .global = true, +}; + +struct filter * +software_mixer_get_filter(struct mixer *mixer) +{ + struct software_mixer *sm = (struct software_mixer *)mixer; + + assert(sm->base.plugin == &software_mixer_plugin); + + return sm->filter; +} diff --git a/src/mixer/software_mixer_plugin.h b/src/mixer/software_mixer_plugin.h new file mode 100644 index 000000000..a59f7edeb --- /dev/null +++ b/src/mixer/software_mixer_plugin.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef SOFTWARE_MIXER_PLUGIN_H +#define SOFTWARE_MIXER_PLUGIN_H + +struct mixer; +struct filter; + +/** + * Returns the (volume) filter associated with this mixer. All users + * of this mixer plugin should install this filter. + */ +struct filter * +software_mixer_get_filter(struct mixer *mixer); + +#endif diff --git a/src/mixer_list.h b/src/mixer_list.h index 7db4a00d8..4e81c57b2 100644 --- a/src/mixer_list.h +++ b/src/mixer_list.h @@ -25,6 +25,7 @@ #ifndef MPD_MIXER_LIST_H #define MPD_MIXER_LIST_H +extern const struct mixer_plugin software_mixer_plugin; extern const struct mixer_plugin alsa_mixer; extern const struct mixer_plugin oss_mixer; extern const struct mixer_plugin pulse_mixer; diff --git a/test/read_mixer.c b/test/read_mixer.c index be6864ba1..bbfb23687 100644 --- a/test/read_mixer.c +++ b/test/read_mixer.c @@ -19,6 +19,8 @@ #include "mixer_control.h" #include "mixer_list.h" +#include "filter_registry.h" +#include "pcm_volume.h" #include @@ -26,6 +28,22 @@ #include #include +const struct filter_plugin * +filter_plugin_by_name(G_GNUC_UNUSED const char *name) +{ + assert(false); + return NULL; +} + +bool +pcm_volume(G_GNUC_UNUSED void *buffer, G_GNUC_UNUSED int length, + G_GNUC_UNUSED const struct audio_format *format, + G_GNUC_UNUSED int volume) +{ + assert(false); + return false; +} + int main(int argc, G_GNUC_UNUSED char **argv) { struct mixer *mixer;