[Portaudio] Alsa: support for sub-device & 24-bit BE format only

Alan Horstmann gineera at aspect135.co.uk
Thu Mar 29 05:12:13 EDT 2012

Hi Dmitry,

Thanks for your reply; I would like to discuss further whether these endian 
converters are actually necessary within Portaudio.  Unfortunately I am not 
aware of the details of the issues that lead to this fix since the 
discussions were not on the Portaudio list, so there may be important details 
I have misunderstood. 

On Tuesday 27 March 2012 10:59, you wrote:
> If you checked the source I added byte-swapping ability for ALSA
> implementation. Some devices appeared to be working only in BE format,
> like Audio4DJ device. It was working only in 24bit BE. PortAudio does
> not provide converters which do swapping, nor those converters can be
> extended for swapping through providing some additional parameter for
> example. So, in order not to touch converter's code and having only
> Linux behaving like this I added byte-swapping converters but for ALSA
> only. They do work well with Aduio4DJ for capturing/playback and
> solved the problem.

It is not uncommon for audio hardware to have very specific hardware formats.  
The widely used 'Envy24'/ice1712 chipset (MAudio Delta 1010 etc, several 
cards by Terratec and StAudio) only uses 24-bit packed in 4bytes, and must 
play 10 channels and record 12, always.  But this is handled in the Alsa-lib 
layer..more below.

> > The Alsa-lib plug converter can do a lot of those things
> From my point of view PortAudio shall handle such situation like it
> happened with Audio4DJ and users will simply have software working
> without additional steps.

For the benefit of readers not familiar with Alsa, raw hardware is accessed 
through the device 'hw:', eg 'hw:0,0' is the first card, first device.  To 
use that device the pcm data must be in a format that the hardware can accept 
- in the Envy24 case that is S32_LE, all 10 channels.  It is not possible to 
play a stereo signal to the hw: device on these cards.

But Alsa provides a 'plug' layer that handles conversions, of format, number 
of channels and sample rate (rate rather poorly).  So by using 'plughw:0,0' I 
can play stereo S16_LE to the card without problem.  Equally, I could play 
S16_BE data.

Each specific card type has a dedicated config file in /usr/share/alsa/cards 
that should give a suitable set-up for that particular hardware, but these 
files are not always perfect, so sometimes improvement tweaks are required 
(essentially an Alsa bug, and raised on the Alsa lists).  Additionally a user 
can specify his/her own tailored devices in a ~/asoundrc file - in the case 
of my Envy24 cards I have some specific channel mapping devices (eg line in 
== channels 3 & 4).  Specific conversions could also be added there.  But 
that should not be necessary.

Perhaps unfortunately, Portaudio does slightly hide the 'plughw' device as it 
is on a list of ignored devices, and I had wondered previously if that might 
be unhelpful.  However, there is a specific mechanism in the Portaudio code 
to always add 'plug' to the hw: device if the env variable PA_ALSA_PLUGHW is 
set to 1.  It is unfortunate that doing so does enable poor quality rate 
conversion also.  I have considered whether Portaudio should turn off rate 
conversion, or have some mechanism for the user to do so - but that is 
another issue!

The Alsa 'default' device is normally configured to always include the plug 
plugin, so default should work regardless of the hardware native format.  If 
that is not happening it suggests a fault in the Alsa driver or config for 
that particular hardware.

All of this can be demonstrated easily using the Alsa util 'aplay'/'arecord';
here, eg,

arecord  -c2 -d5 -Dhw:0,0 -traw -r48000 -fS24_BE Test_BE.raw

fails since S24_BE is not available on this hardware (built-in sound card), 

arecord  -c2 -d5 -Dplughw:0,0 -traw -r48000 -fS24_BE Test_BE.raw

does create a 5 sec recording, which can be played with

aplay -Dplughw:0,0 -c2 -r48000 -fS24_BE -traw Test_BE.raw

but not with

aplay -Dhw:0,0 -c2 -r48000 -fS24_BE -traw Test_BE.raw

So I think it is better for the user to use the plug device, or Alsa 'default' 
rather than adding this to the Portaudio code.  If that is not working, fix 
the Alsa driver or config.  Otherwise does channel mapping and rate 
conversion need also to be provided to support all hardware raw?  It's a 
question of how much is brought inside Portaudio, when it is available 
outside.  Presumably the other hostapis must use conversions in the host 
sound system on the same hardware since they are not needed inside Portaudio?



More information about the Portaudio mailing list