Hurd rump audio translator
Enable audio on GNU Hurd with a rump kernel server and PulseAudio.
This project provides a translator to be run at
/dev/audio which is partially
compatible with the Solaris audio device. It is not a complete implementation,
but it supports enough of the functionality for a PulseAudio sink. This allows
any application that plays sounds through PulseAudio to output audio on a GNU
This project itself depends on Hurd libraries and the rump client library, and it is a dependency of the PulseAudio build. The order should go as follows:
- Build and install everything needed for a Hurd development environment
- Build and install the rump kernel's
- Build and install this
- Build and install PulseAudio with the Solaris module enabled
The first two steps can be done with the standard upstream build processes.
Building the translator
Makefile here is very basic. It supports many of the usual variables for
configuring the build. Just running
make && sudo make install should be
enough to handle most needs. It will install the translator at
ioctl definitions at
/usr/include/sys/audio.h by default.
PulseAudio versions older than 11.0 require a minor edit to compile, since the Solaris module was only expected to be built with Solaris system headers.
sed -i -e 's,<sys/conf.h>,<sys/poll.h>,' src/modules/module-solaris.c
After this edit, it should be able to be built and installed using the normal
upstream procedure. Ensure the
configure command does not use the option
--disable-solaris so it can detect
<sys/audio.h>. Alternatively, append
--enable-solaris option to the
configure command to require it.
With the translator and PulseAudio's Solaris module installed, the following component configurations should result in an audible Hurd system.
The rump kernel described here expects to drive an AC97 sound card. For use
with QEMU, include the
-soundhw ac97 option to emulate such a device.
Rump kernel configuration
The translator acts as a rump client that accesses
/dev/audio in the rump
server's VFS. The following command starts a server with enough modules to
support this and drive AC97 sound cards.
rump_server -s -v \ -lrumpvfs \ -lrumpdev \ -lrumpdev_audio \ -lrumpdev_audio_ac97 \ -lrumpdev_pci \ -lrumpdev_pci_auich \ unix:///run/rump.sock
Note the socket it creates at
/run/rump.sock must be writable for the UID of
the translator process, which should be
root) if it was started from a
translator record on the file system.
The translator command only has a single option, the URL of the rump server's
socket. It is equivalent to using the
RUMP_SERVER environment variable, but
the command-line option has higher precedence. Assuming the translator was
/hurd/audio, the following command will start it for the above
server and write the translator record to run it automatically on future boots.
settrans -acfgp /dev/audio /hurd/audio --url=unix:///run/rump.sock
/dev/audio is writable for whatever users should have permission to
play sounds. At this point
*.au files should be playable (or recordable) by
direct writes (or reads) to this device.
To account for the translator's incomplete compatibility with Solaris, a few
settings in PulseAudio's configuration should be defined to avoid unsupported
ioctl calls, etc. If using
default.pa, make the following modifications.
- Avoid suspending, so don't load
module-detectisn't needed, replace it with
module-solaristo avoid using streams
channel_map=mono channels=1 format=ulaw rate=8000on
module-solaristo pick some known-supported playback parameters
Any applications that use PulseAudio should now be able to play sounds without
modifying them. A user's PulseAudio server should start automatically when it
is needed, e.g. by running
paplay on a sound file.
The translator provides a device node supporting four important operations:
- Writing data, i.e. playing audio out of speakers
- Reading data, i.e. recording audio from a microphone
AUDIO_GETINFOioctl, for retrieving device information
AUDIO_SETINFOioctl, for changing device information
The installed header
<sys/audio.h> is a modified version of NetBSD's header
<sys/audioio.h> to be more compatible with Solaris. However, the changes
required to build on Hurd make it incompatible with both NetBSD and Solaris.
The Solaris device node uses the old POSIX streams interface which is not implemented here, but PulseAudio's usage of the device is limited enough for it to bypass the streams ioctls with the aforementioned configuration changes.
The audio ioctl character is
A on both Solaris and NetBSD, but this value is
invalid on Hurd, so the installed
s instead. Also, Hurd's
ioctl definitions for structured parameters are normally defined by pairs of
the member data type and the count of consecutive members of that type. The
struct audio_info members are too many to fit into that encoding scheme, so
the ioctl definitions in
audio.h pretend all members are 64-bit integers,
with enough of them to match the same structure size.
The Solaris data structure has an
output_muted member used by PulseAudio, but
NetBSD does not define it. It was appended to the structure in
audio.h as a
64-bit integer (to keep things evenly divisble) for source compatibility, but
the value is never actually used by the translator.
As a final note: This is just a silly toy program. If anyone really wants to have PulseAudio use a rump server, it would be better to write a new PulseAudio module that directly connects to it for platform independence and less IPC.