Audio Devices

1.0 Introduction

The world of audio on Linux is fraught with complexity and awkwardness... and I am no expert in it, so I can't exactly offer you a path of enlightenment through it, either!

Without pretending to be an expert, therefore, let me enumerate some of the difficulties 🙂

Let's start by mentioning ALSA -the Advanced Linux Sound Architecture- which has been the kind of bedrock of all audio on Linux since it was developed back in 1998 or so. It has been the default Linux sound system (replacing OSS, the Open Sound System) since kernel version 2.6. ALSA supports outputting audio to up to 8 devices (numbered in inevitable computer science fashion from 0 to 7), each of which can have subdevices, and which are addressed via an interface which is usually identified as 'hw<something>' or 'plughw<something>'. A 'default' interface is also available, which usually works, but without hardware-aware features. If you send hi-res audio to the 'default' device (your PC's soundcard, for example), you may well only get 44.1KHz standard CD Audio out. Send the same audio to plughw:2, however, and you may well get 88.2, 96 or 192KHz playback -because going via the plughw identifier means ALSA talks to the hardware drivers and thus better understands what sort of audio output the card is capable of.

Now layer on top of that PulseAudio. It's a 'sound server' that is responsible for taking multiple audio streams and passing them on to an ALSA device for output and has been around since about 2004. Most Linux distros include it (and indeed a version of it can run on Windows, macOS, the various BSDs and Solaris, for example). If your audio gets to an ALSA device via PulseAudio, then PulseAudio can 'intervene' with the signal. It can interpose a volume control, for example; or tweak bass and treble; and so on. Practically, PulseAudio allows two sound sources to play simultaneously, where going via ALSA directly usually means that only one source can 'sound' at a time. If you were playing a YouTube video, for example, and tried getting Giocoso to play some music at the same time... Giocoso will not get access to the sound card in an ALSA world, whereas PulseAudio can 'merge' the audio streams from both video and audio player and thus sound both at the same time.

And the third thing I'll mention is that if you are running Giocoso on Windows 10 or macOS, you need worry about none of the above, since they have sound systems of their own (with which PulseAudio can interact), but which aren't ALSA down at the foundational level.

But running Giocoso on Linux? Well, then you need to know how to tell Giocoso what audio device to output music to -and, by default, Giocoso wants to play to ALSA directly. That's because it's a classical music player and people who treat classical music semi-seriously tend to think that playing a YouTube video whilst listening to the death scene in La Traviata is probably not the best way to waste your time! Classical music audio doesn't need to be mixed with other audio streams: quite the reverse. Neither does it need to be 'fiddled around with', by adding volume controls, bass and treble mixers and the like: chances are that classical music listeners are going to be listening to digital audio via hardware whose price tags would make you blush and which already have their very own volume, bass and treble controls! The features of PulseAudio are not, in other words, relevant to a classical music listener; and so talking to ALSA directly is Giocoso's preferred way of working (on Linux platforms).

Which then raises the question: how do you use ALSA to be able to tell Giocoso to which devices it should direct its audio?

2.0 Device Parameter

Functionally, you direct Giocoso to send its output to a suitable hardware device by specifying the --device=xxxx runtime parameter (or the DEVICE= parameter in the persistent configuration file). If you don't do this, then the default audio device is 'default' -which, as I mentioned in the introduction, will probably work but won't be able to handle hi-res audio, for example.

This rather begs a question, however: how do you know what device to set the --device parameter to in the first place?

The first place to start is this command:

aplay -l

On my system, that produces output like this:

It appears my main PC doesn't have an internal sound card as such, but only a USB audio device called 'E30'... and that's entirely accurate, as the Topping E30 is my USB DAC (digital to analogue converter), which in turn feeds into my amplifier and speakers. So that would be exactly the sort of device I'd want Giocoso sending audio to!

Unfortunately, this doesn't tell us the --device parameter directly: you've got to work it out. Once I know it's the E30 I want to output to, I read that it's "card 0, subdevice 0". I then have to do a bit of guesswork! That seems to me to be an ALSA device called <something>0,0. I could try the 'hw' interface protocol, producing a --device="hw:0,0". Unfortunately, when I launch Giocoso with that particular runtime parameter setting, though everything seems to work just by looking at Giocoso, no music can actually be heard. So, I re-run Giocoso with --device="plughw:0,0" (note how the device identifiers are always enclosed within double quotation marks, by the way). Again, everything looks fine... but now I can hear music, so that must be the right identifier.

Helpfully, Giocoso displays the hardware device that's in use, at the footer of the main program display:

The 'Plughw...' marker at the right-hand side of the footer tells you all you need to know (just be warned that, for 'pretty' display purposes, Giocoso capitalises the initial letter of the hardware device name: thus, I see 'Plughw' displayed, but would need to specify '--device=plughw...' with a lower-case 'p'.)

Once you know that you've discovered a hardware device identifier that works well, you can set DEVICE=... in the persistent configuration file, so you don't need to keep specifying it every time you run Giocoso.

3.0 Forcing PulseAudio

You should never really need to do it, but if you find that no matter what you do with the --device parameter and that even leaving it set to its default of "default" doesn't result in usable audio output from Giocoso, you can use the --forcepulse runtime parameter to try to force Giocoso to send its audio signal to a PulseAudio server, rather than directly to ALSA.

You should first make sure that PulseAudio is present and functioning on your system. The command:

pactl list

...should produce a long list of audio devices, 'sinks', sources and modules if it is installed and working correctly. If it is, then simply try launching Giocoso with the --forcepulse parameter tacked onto the end of your usual assortment of runtime parameters and wait to find out if you can hear anything being played. The parameter takes no values: it's mere presence will trigger the use of PulseAudio rather than ALSA. If you find it has helped to produce audio output where there was none before, then you can permanently switch the feature on by setting FORCE_PULSE=Yes in the persistent configuration file. If forced PulseAudio is in effect, the footer area will spell it out:

Note that if you have DEVICE="something" and FORCE_PULSE=Yes in the configuration file, FORCE_PULSE 'wins'. That is true if you also specify both --forcepulse and --device="something" as runtime parameters: the --forcepulse 'wins' and the --device setting is silently ignored.

Be aware that sending audio via PulseAudio rather than direct to ALSA usually means you may encounter some of the limitations of PulseAudio: specifically, you may find it impossible to get a true hi-res audio signal from hi-res audio sources. PulseAudio tends to down-convert to standard CD Audio, instead.

On the other hand, there's one specific reason you might want to use --forcepulse that doesn't involve the 'nothing else worked!' scenario and that's: sending audio over a home network. If your main PC is running Windows, for example, and you are running Giocoso on a Raspberry Pi, you can get the Pi to send its audio signal to a PulseAudio server running on your Windows PC over the network (unfortunately, I must leave that as an exercise for the reader at this point, but will document it when I can). If the Raspberry Pi was sending its audio output to its own ALSA devices, you'd be stuck listening to the Pi itself (perhaps in a loft, where I run mine, for example!). However, if you run the Raspberry Pi with FORCE_PULSE=Yes (or --forcepulse), then you can get the Pi to pump its audio over the home network to your Windows PC's own PulseAudio server. PulseAudio is very handy for this cross-network audio capability (rather as x11 is great for cross-network graphics capabilities). As I say, I will document some specifics on getting this sort of thing working elsewhere.

4.0 Conclusion

Summing up:

  • If your Linux PC is already playing sounds, Giocoso should almost certainly be able to play music too, without great difficulty
  • Giocoso's default device setting (--device="default") will usually get audio working 9 times out of 10, though the quality may be less than optimal, since a PulseAudio device will usually be the default
  • The ability to set the --device runtime parameter (or its persistent configuration cousin) to a specific ALSA hardware device identifier allows you to play hi-res audio at the highest of quality
  • Finding the correct value for the --device runtime parameter can be tricky, but aplay -l will help you start working out what it should be
  • If you want to play music across a home network, sending an audio signal from a remote media server to a more local PC or laptop, or otherwise need to force Giocoso to use PulseAudio, the --forcepulse runtime parameter (and its FORCE_PULSE=Yes persistent configuration cousin) can help
  • Users of Apple hardware, or those running Windows, do not need to worry about any of this stuff, because those operating systems handle audio devices quite differently and, in fact, entirely ignore both the --device and --forcepulse runtime parameters (and their persistent configuration file equivalents).

[Back to Front Page]