So with 3 Pis 2x Pi3A+ and 1x Pi4B+2gb if you want AEC and playing media is important to you.
Guess you could do the same with a 2xPi0 and 1x Pi3 but for me ‘barge-in’ on media playback is such a common need its sort of essential.
Sattelite RPC audio is extremely light AEC is not and needs a PI3 minimum and you can actually hear a slight improvement on the Pi4 so even with a Pi3 its just on the cusp of things.
Choose your version of RTP be it Roc, Pulseaudio or whatever currently I have become a snapcast fan.
Roc is a good alternative also.
https://roc-project.github.io/roc/docs/about_project/overview.html
But we are going to head to snapcast.
We will go for the latest release so head to.
No surprises here on the server install snapserver and on the 2x satellites install snapclient.
sudo dpkg -i snapclient_0.x.x_armhf.deb
and follow with sudo apt-get -f install
just to pull in the missing dependencies.
Dunno why its like that must be some reason but works fine.
Scroll down to https://github.com/badaix/snapcast/blob/master/doc/player_setup.md#alsa
As we will set up the server to work with simple ALSA sound.
/etc/asound.conf
pcm.!default {
type plug
slave.pcm rate48000Hz
}
pcm.rate48000Hz {
type rate
slave {
pcm writeFile # Direct to the plugin which will write to a file
format S16_LE
rate 48000
}
}
pcm.writeFile {
type file
slave.pcm null
file "/tmp/snapfifo"
format "raw"
}
You can connect to various devices and setup multiple streams that can become the basis of various different groups playing different streams of multi-channel audio.
But for now that it as snapclient plays to the default sound device and if you aplay on the server then due to the inbuilt avahi you should get audio on your satelites.
You can go on google play and search for snapcast and there is a pretty nifty app for controlling your snapcast server and clients remotely.
Have to say this is why I like snapcast as its really simple.
Currently though you will have a stereo pair of satelites playing the full stream which isn’t very stereo and there unfortunately doesn’t seem to be channel support but probably because you do this by setting the channel volume on the device.
Use alsamixer set 1 to 100% left volume and the other to 100% right volume as snapclient just controls the master volume.
alsactl store to make persistent over reboots.
So thats its for stereo server to twin satellite playback be it Pi0 or Pi3.
So now we are going to do the reverse for the mics.
Install snapserver on the satellites and snapclient on the server.
If your going to use VAD or KWS to trigger mic transmission that is something for later but for now just going to concentrate on a base snapcast set up.
We are just going to pipe the mic into the snapcast fifo with
arecord (format) (device) > /tmp/snapfifo
on the cli snapserver -h
will give you a quick overview of all the cli options for running a server.
On our server because we are doing things backwards for the mics we need to run 2 snapclients.
This time we don’t want auto configure via avahi we want to point to the satellite of choice.
So snapclient -h
to view the cli options.
snapclient -h, --host, arg server hostname or ip address, -s, --soundcard arg (=default) index or name of the pcm device
snapclient has the similar method a aplay -L so snapclient -l, --list, list PCM devices.
This is where you might be thinking hold on this is going to set up a sink and also 2?! As you do need to run 2 client instances to each server.
What we are going to do is use a alsa snd-aloop device play into one side of the loopback device and the other side will be available as a mic source.
So sudo modprobe snd-aloop
Then aplay -l will not bring back the following as you will just have a single card.
pi@raspberrypi:~ $ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Loopback_1 [Loopback], device 0: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 0: Loopback_1 [Loopback], device 1: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 1: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 1: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 2: Loopback_2 [Loopback], device 0: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 2: Loopback_2 [Loopback], device 1: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 3: Loopback_3 [Loopback], device 0: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 3: Loopback_3 [Loopback], device 1: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 4: Loopback_4 [Loopback], device 0: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 4: Loopback_4 [Loopback], device 1: Loopback PCM [Loopback PCM]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
But if you wanted to go crazy with mics everywhere you can load multiple cards by setting options in a file such as /etc/modprobe.d/snd-aloop.conf
options snd-aloop enable=1,1,1,1,1
Will create 5 and so you don’t have to run modprobe each time in /etc/modules just add
snd-aloop
and reboot to test.
You can add some pcms to /etc/asound.conf to make things a little more clear.
defaults.namehint.showall on
defaults.namehint.extended on
pcm.!default {
type plug
slave.pcm rate48000Hz
}
pcm.rate48000Hz {
type rate
slave {
pcm writeFile # Direct to the plugin which will write to a file
format S16_LE
rate 48000
}
}
pcm.writeFile {
type file
slave.pcm null
file "/tmp/snapfifo"
format "raw"
}
pcm.mic1 {
type plug
slave {
pcm "hw:0,1,0"
}
hint {
description "Mic1 loopback 0,1,0"
}
}
pcm.mic2 {
type plug
slave {
pcm "hw:0,1,1"
}
hint {
description "Mic2 loopback 0,1,1"
}
}
Now you should have 2 mic sources on the oppisite side of the loopback “hw:0,0,0” & “hw:0,0,1”
The choice is yours from now as with asla you might want to combine or route into a sum.
But thats the basic setup.
If you choose pi3 then on each satelite you run AEC as with.
And start creating a wide array microphone system with aec.
But you should have a server with sateliite audio that runs as if just local alsa devices.
I haven’t tested running AEC but presume all the clock drift thing comes into play but webrtc might be interesting as then the Pi0 might be an option satelite side and AEC runs on the server.