summaryrefslogtreecommitdiff
path: root/src/output/plugins/SndioOutputPlugin.cxx
diff options
context:
space:
mode:
authorChristopher Zimmermann <madroach@gmerlin.de>2017-09-16 08:21:07 +0200
committerChristopher Zimmermann <madroach@gmerlin.de>2017-09-16 11:58:33 +0200
commit030f87c90c69a4cc171dc45aa44eb149c122372d (patch)
tree722c6f8781be5b2f6041985f1cecfbc2512112c3 /src/output/plugins/SndioOutputPlugin.cxx
parentae941a766547f4b33d3f1d47bb7f2cf65b83d9ac (diff)
Add sndio mixer plugin
Diffstat (limited to 'src/output/plugins/SndioOutputPlugin.cxx')
-rw-r--r--src/output/plugins/SndioOutputPlugin.cxx52
1 files changed, 49 insertions, 3 deletions
diff --git a/src/output/plugins/SndioOutputPlugin.cxx b/src/output/plugins/SndioOutputPlugin.cxx
index bcda3126a..1ae92f1bf 100644
--- a/src/output/plugins/SndioOutputPlugin.cxx
+++ b/src/output/plugins/SndioOutputPlugin.cxx
@@ -19,6 +19,7 @@
#include "config.h"
#include "SndioOutputPlugin.hxx"
+#include "mixer/MixerList.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
@@ -47,10 +48,16 @@ SndioOutput::SndioOutput(const ConfigBlock &block)
:AudioOutput(0),
device(block.GetBlockValue("device", SIO_DEVANY)),
buffer_time(block.GetBlockValue("buffer_time",
- MPD_SNDIO_BUFFER_TIME_MS))
+ MPD_SNDIO_BUFFER_TIME_MS)),
+ raw_volume(SIO_MAXVOL)
{
}
+static void
+VolumeCallback(void *arg, unsigned int volume) {
+ ((SndioOutput *)arg)->VolumeChanged(volume);
+}
+
AudioOutput *
SndioOutput::Create(EventLoop &, const ConfigBlock &block) {
return new SndioOutput(block);
@@ -125,6 +132,15 @@ SndioOutput::Open(AudioFormat &audio_format)
throw std::runtime_error("Requested audio params cannot be satisfied");
}
+ // Set volume after opening fresh audio stream which does
+ // know nothing about previous audio streams.
+ sio_setvol(sio_hdl, raw_volume);
+ // sio_onvol returns 0 if no volume knob is available.
+ // This is the case on raw audio devices rather than
+ // the sndiod audio server.
+ if (sio_onvol(sio_hdl, VolumeCallback, this) == 0)
+ raw_volume = -1;
+
if (!sio_start(sio_hdl)) {
sio_close(sio_hdl);
throw std::runtime_error("Failed to start audio device");
@@ -148,9 +164,39 @@ SndioOutput::Play(const void *chunk, size_t size)
return n;
}
+void
+SndioOutput::SetVolume(unsigned int volume) {
+ sio_setvol(sio_hdl, volume * SIO_MAXVOL / 100);
+}
+
+static inline unsigned int
+RawToPercent(int raw_volume) {
+ return raw_volume < 0 ? 100 : raw_volume * 100 / SIO_MAXVOL;
+}
+
+void
+SndioOutput::VolumeChanged(int _raw_volume) {
+ if (raw_volume >= 0 && listener != nullptr && mixer != nullptr) {
+ raw_volume = _raw_volume;
+ listener->OnMixerVolumeChanged(*mixer,
+ RawToPercent(raw_volume));
+ }
+}
+
+unsigned int
+SndioOutput::GetVolume() {
+ return RawToPercent(raw_volume);
+}
+
+void
+SndioOutput::RegisterMixerListener(Mixer *_mixer, MixerListener *_listener) {
+ mixer = _mixer;
+ listener = _listener;
+}
+
const struct AudioOutputPlugin sndio_output_plugin = {
"sndio",
sndio_test_default_device,
- &SndioOutput::Create,
- nullptr,
+ SndioOutput::Create,
+ &sndio_mixer_plugin,
};