gmixerctl is a GUI wrapper for the OpenBSD
mixerctl command. gmixerctl aims to have
100% feature parity with mixerctl, and may add a few more convenience features
in the future (such as setting sndiod flags).
gmixerctl is written in in Python3 with tkinter, and operates by wrapping the mixerctl command itself.
Full functionality of
mixerctl is exposed as a GUI
Robust against differing output options across different mixer devices
Support for changing
rsnd device and
python3 setup.py install
If you would like to be able to change the output device(s) that sndiod should
use, you should add the following lines to
permit nopass youruser as root cmd /usr/sbin/rcctl args set sndiod flags -f rsnd/0 permit nopass youruser as root cmd /usr/sbin/rcctl args set sndiod flags -f rsnd/1 permit nopass youruser as root cmd /usr/sbin/rcctl args set sndiod flags -f rsnd/2 permit nopass youruser as root cmd /usr/sbin/rcctl args restart sndiod
Contributions are more than welcome. If there is a feature you would like added to gmixerctl, please feel free to open a pull request. In particular, I would appreciate help implementing the following features:
Changing the mixer device at run time (this may be a Tk limitation, but I'm not experienced enough with Tk at the moment)
sndiod flags (i.e. a menu for running
rcctl set sndiod flags
-f rsnd/X ; rcctl restart sndiod)
An elegant solution for rendering enum type controls with only the choices on and off as checkboxes, rather than dropdowns.
sndiodtab does not update once the application has started.
My first attempt at writing gmixerctl was in the form of an imgui based C++
application which worked by calling into the same API as
mixerctl.c, which is
to say just sending
ioctl() calls straight to
/dev/mixer. This attempt was
abandoned due to a number of issues, namely synchronous/immediate mode
rendering proved difficult to combine with polling the mixer state - setting
the framerate too high could crash the application, presumably by exceeding the
maximum throughput of the mixer device.
Python was selected as the implementation language, as I was already familiar with it. Tkinter was chosen as the UI library due to it's reputation for ease-of use, which I found it to live up to.
In principle, I could have written a Python wrapper for the relevant audio
ioctl() calls, but chose not to as the output of
is easy to parse, and has proved not to be a bottleneck. If someone else would
like to write such a wrapper, I would be happy to use it however.