aboutsummaryrefslogtreecommitdiffstats
path: root/src/mixer/OssMixerPlugin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/mixer/OssMixerPlugin.cxx')
-rw-r--r--src/mixer/OssMixerPlugin.cxx143
1 files changed, 92 insertions, 51 deletions
diff --git a/src/mixer/OssMixerPlugin.cxx b/src/mixer/OssMixerPlugin.cxx
index 8d266b40a..83bc31f9f 100644
--- a/src/mixer/OssMixerPlugin.cxx
+++ b/src/mixer/OssMixerPlugin.cxx
@@ -40,15 +40,24 @@
#define VOLUME_MIXER_OSS_DEFAULT "/dev/mixer"
-struct oss_mixer {
- /** the base mixer class */
- struct mixer base;
-
+class OssMixer : public mixer {
const char *device;
const char *control;
int device_fd;
int volume_control;
+
+public:
+ OssMixer() {
+ mixer_init(this, &oss_mixer_plugin);
+ }
+
+ bool Configure(const config_param *param, GError **error_r);
+ bool Open(GError **error_r);
+ void Close();
+
+ int GetVolume(GError **error_r);
+ bool SetVolume(unsigned volume, GError **error_r);
};
/**
@@ -75,95 +84,114 @@ oss_find_mixer(const char *name)
return -1;
}
-static struct mixer *
-oss_mixer_init(G_GNUC_UNUSED void *ao, const struct config_param *param,
- GError **error_r)
+inline bool
+OssMixer::Configure(const config_param *param, GError **error_r)
{
- struct oss_mixer *om = g_new(struct oss_mixer, 1);
-
- mixer_init(&om->base, &oss_mixer_plugin);
-
- om->device = config_get_block_string(param, "mixer_device",
+ device = config_get_block_string(param, "mixer_device",
VOLUME_MIXER_OSS_DEFAULT);
- om->control = config_get_block_string(param, "mixer_control", NULL);
+ control = config_get_block_string(param, "mixer_control", NULL);
- if (om->control != NULL) {
- om->volume_control = oss_find_mixer(om->control);
- if (om->volume_control < 0) {
- g_free(om);
+ if (control != NULL) {
+ volume_control = oss_find_mixer(control);
+ if (volume_control < 0) {
g_set_error(error_r, oss_mixer_quark(), 0,
- "no such mixer control: %s", om->control);
- return NULL;
+ "no such mixer control: %s", control);
+ return false;
}
} else
- om->volume_control = SOUND_MIXER_PCM;
+ volume_control = SOUND_MIXER_PCM;
- return &om->base;
+ return true;
}
-static void
-oss_mixer_finish(struct mixer *data)
+static struct mixer *
+oss_mixer_init(G_GNUC_UNUSED void *ao, const struct config_param *param,
+ GError **error_r)
{
- struct oss_mixer *om = (struct oss_mixer *) data;
+ OssMixer *om = new OssMixer();
- g_free(om);
+ if (!om->Configure(param, error_r)) {
+ delete om;
+ return nullptr;
+ }
+
+ return om;
}
static void
-oss_mixer_close(struct mixer *data)
+oss_mixer_finish(struct mixer *data)
{
- struct oss_mixer *om = (struct oss_mixer *) data;
+ OssMixer *om = (OssMixer *) data;
+
+ delete om;
+}
- assert(om->device_fd >= 0);
+void
+OssMixer::Close()
+{
+ assert(device_fd >= 0);
- close(om->device_fd);
+ close(device_fd);
}
-static bool
-oss_mixer_open(struct mixer *data, GError **error_r)
+static void
+oss_mixer_close(struct mixer *data)
{
- struct oss_mixer *om = (struct oss_mixer *) data;
+ OssMixer *om = (OssMixer *) data;
+ om->Close();
+}
- om->device_fd = open_cloexec(om->device, O_RDONLY, 0);
- if (om->device_fd < 0) {
+inline bool
+OssMixer::Open(GError **error_r)
+{
+ device_fd = open_cloexec(device, O_RDONLY, 0);
+ if (device_fd < 0) {
g_set_error(error_r, oss_mixer_quark(), errno,
"failed to open %s: %s",
- om->device, g_strerror(errno));
+ device, g_strerror(errno));
return false;
}
- if (om->control) {
+ if (control) {
int devmask = 0;
- if (ioctl(om->device_fd, SOUND_MIXER_READ_DEVMASK, &devmask) < 0) {
+ if (ioctl(device_fd, SOUND_MIXER_READ_DEVMASK, &devmask) < 0) {
g_set_error(error_r, oss_mixer_quark(), errno,
"READ_DEVMASK failed: %s",
g_strerror(errno));
- oss_mixer_close(data);
+ Close();
return false;
}
- if (((1 << om->volume_control) & devmask) == 0) {
+ if (((1 << volume_control) & devmask) == 0) {
g_set_error(error_r, oss_mixer_quark(), 0,
"mixer control \"%s\" not usable",
- om->control);
- oss_mixer_close(data);
+ control);
+ Close();
return false;
}
}
+
return true;
}
-static int
-oss_mixer_get_volume(struct mixer *mixer, GError **error_r)
+static bool
+oss_mixer_open(struct mixer *data, GError **error_r)
+{
+ OssMixer *om = (OssMixer *) data;
+
+ return om->Open(error_r);
+}
+
+inline int
+OssMixer::GetVolume(GError **error_r)
{
- struct oss_mixer *om = (struct oss_mixer *)mixer;
int left, right, level;
int ret;
- assert(om->device_fd >= 0);
+ assert(device_fd >= 0);
- ret = ioctl(om->device_fd, MIXER_READ(om->volume_control), &level);
+ ret = ioctl(device_fd, MIXER_READ(volume_control), &level);
if (ret < 0) {
g_set_error(error_r, oss_mixer_quark(), errno,
"failed to read OSS volume: %s",
@@ -182,19 +210,25 @@ oss_mixer_get_volume(struct mixer *mixer, GError **error_r)
return left;
}
-static bool
-oss_mixer_set_volume(struct mixer *mixer, unsigned volume, GError **error_r)
+static int
+oss_mixer_get_volume(struct mixer *mixer, GError **error_r)
+{
+ OssMixer *om = (OssMixer *)mixer;
+ return om->GetVolume(error_r);
+}
+
+inline bool
+OssMixer::SetVolume(unsigned volume, GError **error_r)
{
- struct oss_mixer *om = (struct oss_mixer *)mixer;
int level;
int ret;
- assert(om->device_fd >= 0);
+ assert(device_fd >= 0);
assert(volume <= 100);
level = (volume << 8) + volume;
- ret = ioctl(om->device_fd, MIXER_WRITE(om->volume_control), &level);
+ ret = ioctl(device_fd, MIXER_WRITE(volume_control), &level);
if (ret < 0) {
g_set_error(error_r, oss_mixer_quark(), errno,
"failed to set OSS volume: %s",
@@ -205,6 +239,13 @@ oss_mixer_set_volume(struct mixer *mixer, unsigned volume, GError **error_r)
return true;
}
+static bool
+oss_mixer_set_volume(struct mixer *mixer, unsigned volume, GError **error_r)
+{
+ OssMixer *om = (OssMixer *)mixer;
+ return om->SetVolume(volume, error_r);
+}
+
const struct mixer_plugin oss_mixer_plugin = {
oss_mixer_init,
oss_mixer_finish,