The libasound library supports devices with up to
eight voices. Configuration of the libasound
library is based on the maximum number of voices that are supported in hardware.
If the numbers of source and destination voices are different, then
snd_pcm_plugin_params() creates an instance of a voice converter.
The default voice conversion behavior is as follows:
From |
To |
Conversion |
Mono
|
Stereo
|
Replicate channel 1 (left) to channel 2 (right)
|
Stereo
|
Mono
|
Remove channel 2 (right)
|
Mono
|
4-channel
|
Replicate channel 1 to all other channels
|
Stereo
|
4-channel
|
Replicate channel 1 (front left) to channel 3 (rear
left), and channel 2 (front right) to channel 4
(rear right)
|
Previous versions of libasound converted stereo to mono by averaging the left and
right channels to generate the mono stream. Now, by default, the right channel is
dropped.
You can use the voice conversion API to configure the conversion
behavior and place any source channel in any destination channel slot:
-
snd_pcm_plugin_get_voice_conversion()
- Get the current voice conversion structure for a channel
-
snd_pcm_plugin_set_voice_conversion()
- Set the current voice conversion structure for a channel
The snd_pcm_voice_conversion_t structure, which is
defined below, controls the actual conversion:
typedef struct snd_pcm_voice_conversion
{
uint32_t app_voices;
uint32_t hw_voices;
uint32_t matrix[32];
} snd_pcm_voice_conversion_t
The matrix member forms a 32-by-32-bit array that specifies how to
convert the voices. The array is ranked with rows representing app voices, with
voice 0 first. The columns represent hardware voices, with the low voice being
Least Significant Bit (LSB) aligned and increasing right to left.
For example, consider a mono app stream sent to a 4-voice hardware
device. A bit array of:
matrix[0] = 0x1; // 00000001
causes the sound to be output on only the first hardware channel. A
bit array of:
matrix[0] = 0x9; // 00001001
causes the sound to be output on the first and last hardware
channel.
Another example is a stereo app stream to a 6-channel (5.1) output
device. A bit array of:
matrix[0] = 0x1; // 00000001
matrix[1] = 0x2; // 00000010
causes the sound to be output on only the front two channels,
while:
matrix[0] = 0x5; // 00000101
matrix[1] = 0x2; // 00000010
causes the stream signal to be output on the first four channels
(likely the front and rear pairs, but not on the center or Low-Frequency Effects
(LFE) channels). The bitmap that's used to describe the hardware (the columns)
depends on the hardware. Further, the actual hardware that it's running on
determines how the channels are mapped. For example:
- When the hardware arranges the channels such that the center
channel is the third channel, then bit 2 represents the center.
- When the hardware arranges the channels such that the rear
left is the third channel, then bit 2 represents the rear left.
When the number of source voices matches the number of destination
voices, the converter isn't invoked and the channels cannot be rerouted. When
you're playing a stereo file on stereo hardware, you can't use the voice matrix to
swap the channels, because the voice converter isn't used in this case.
When you call snd_pcm_plugin_get_voice_conversion() or snd_pcm_plugin_set_voice_conversion() before the voice conversion
plugin has been instantiated, the functions fail and return -ENOENT.