Pulseaudio gives some advantages over a bare alsa setup, but it has many drawbacks I won’t discuss here.
You can get some of the main advantages of alsa+pulseaudio on your SBC by setting up a loopback device and using ‘dmix’ to handle multiple streams of audio.
1) Loopback device: This lets you record what your soundcard is playing. Necessary to run visualizers as well. YOU NEED module snd-aloop available for your kernel. MANY kernel builders FORGET to enable alsa snd-aloop. Please don’t do this! Build it as a module or right in the kernel! THANKS.
Alsa Project full-duplex loopback driver documentation
If you have module snd-aloop, you can modprobe snd-aloop or automatically load it on boot the usual way.
2) Create an alsa configuration file in your home directory ~/.asoundrc (Thanks to Anko from Frankfurt!)
# set card number to the number of your output alsa device
# list devices with aplay -l
# in my case it is:
# card 2: Device [USB PnP Audio Device], device 0: USB Audio pcm.snd_card {
type hw
card 2
}
ctl.!default { # default control; alsamixer will use this
type hw
card 2
}
# software mixer for sound card
pcm.dmixer {
type dmix
ipc_key 1024
ipc_perm 0666 # allow other users
slave.pcm "snd_card"
slave {
period_time 0
period_size 1024
buffer_size 4096
channels 2 # must match bindings
}
bindings {
0 0
1 1
}
}
# software mixer for loopback device
pcm.dmixerloop {
type dmix
ipc_key 2048
ipc_perm 0666 # allow other users
slave.pcm "hw:Loopback,0,0"
slave {
period_time 0
period_size 1024
buffer_size 4096
channels 2 # must match bindings
}
bindings {
0 0
1 1
}
}
# allows multiple programs to capture simultaneously
pcm.dsnooper {
type dsnoop
ipc_key 2048
ipc_perm 0666
slave.pcm "snd_card"
slave
{
period_time 0
period_size 1024
buffer_size 4096
channels 2
}
bindings {
0 0
1 1
}
}
pcm.!default {
type asym
playback.pcm "out"
capture.pcm "dsnooper"
}
# Multi, splitting onto usual card and loopback
pcm.out {
type plug
slave.pcm {
type multi
slaves {
a { channels 2 pcm "dmixer" }
b { channels 2 pcm "dmixerloop" }
}
bindings {
0 { slave a channel 0 }
1 { slave a channel 1 }
2 { slave b channel 0 }
3 { slave b channel 1 }
}
}
ttable [
[ 1 0 1 0 ] # left -> a.left, b.left
[ 0 1 0 1 ] # right -> a.right, b.right
]
}
This has fixed all my years of ALSA headaches. Hope it helps to share to the Khadas community!