A while ago I wrote about creating random numbers out of noise gathered from an audio device and also created a password generator based on the idea. The implementation was based on Open Sound System (commonly known as OSS). OSS was the de facto way to access audio devices a couple of years ago, until it hit licensing issues and was subsequently replaced by ALSA. As Ubuntu no longer supports OSS (and even the ALSA wrapper for it is in Universe), I’ve decided to re-write the code using some modern alternative.
This is the place to note that by the time OSS was being replaced, it lagged behind ALSA in many advanced features (such as mixing and support for audio devices), but ALSA’s emulation layer for OSS solved most of those issues. But one may ask why use the emulation layer at all when one can use ALSA directly? Because OSS is about as simple as it gets if you don’t need anything fancy.
Take a look at a simple OSS code sample that reads from the microphone:
m_dsp_fd = fopen("/dev/dsp","rb");
if (!m_dsp_fd)
goto error;
if (fread(&sample_buffer, sizeof(int16_t), 512, m_dsp_fd) != 512)
goto error;
This is the gist of it. Just reading/writing “plain” files – the true Unix way. If you want to change the default format, just throw in a bit of ioctls, like this:
int format = AFMT_S16_NE;
if (ioctl(fileno(m_dsp_fd), SNDCTL_DSP_SETFMT, &format)==-1)
goto error;
if (format != AFMT_S16_NE)
goto error;
int speed = 44100; // cd speed, should be supported anywhere
if (ioctl(fileno(m_dsp_fd), SNDCTL_DSP_SPEED, &speed)==-1)
goto error;
As you can see, OSS is simple, and it’s actually well documented.
I’ve ported my password generator to PortAudio, and it just doesn’t feel as intuitive as OSS (for example, you need to explicitly start/stop the stream before/after reading from it), but at least it says it’s cross-platform. PortAudio has its quirks too. As part of the library initialization, it enumerates all the ALSA devices, and apparently some of the devices aren’t supposed to work (or something along those lines), so it just dumps 8 lines of errors complaining about ALSA, and there isn’t a way to silence them.
I’m planning to try and make another backend for my program, this time using ALSA directly, but from a couple of quick looks, it isn’t as simple as OSS either (and the documentation isn’t as good).
I think the common cause for this is that audio library writers try to offer many features and capabilities to suit advanced applications. But somewhere along the way, they neglect offering a simple way to use them for the many developers and applications out there that don’t need any special features.