Service that streams real-time audio from a Roc Toolkit Sender to a PulseAudio server.
The Roc Toolkit's Sender will allow you to stream stable CD-quality audio over the network. This service will stream that audio to your PulseAudio server.
This little Docker container will start a service that will allow you to connect any digital audio source from the Roc Toolkit, this can be as simple as its roc-send, that streams an audio file over the network, or a virtual audio device that support the Roc Toolkit real-time audio streaming protocol.
Or, use this service when you've set-up a Virtual Speakers as a Roc Virtual Audio Device in macOS. This can be a real Mac, where you need to play audio through another device, or this can be a macOS running in a VM-host (like in QEMU or VirtualBox) to connect to your speakers over the PulseAudio service that is running on your host device.
The PulseAudio service can be run on a Raspberry Pi, another Linux, or a Windows PC as a Windows Service, for Roc-Steady Sound!
Basically, all it is doing is running the equivalent of the following command in a Docker container, that contains its own PulseAudio server with Roc Toolkit PulseAudio Sink Input module (audio receive plug-in), that forwards it your PulseAudio server
roc-recv -vv -s rtp+rs8m://0.0.0.0:10001 -r rs8m://0.0.0.0:10002 -c rtcp://0.0.0.0:10003 -o pulse://@DEFAULT_SINK@
The container will listen at UDP-port 10001, UDP-port 10002, and UDP-port 10003 for a Roc Toolkit Sender to connect to.
These assume that you already have the following things configured on your (host) machine:
- PulseAudio server running and working audio on your host, test with the pacat < /dev/urandom command if that is working, it should let you hear static over your speakers.
- Docker installed on the same machine with PulseAudio installed, either under WSL 2 on Windows or directly on Linux.
For the example use, mentioned above, to have working Virtual Speakers working on macOS, the Roc Virtual Audio Device for macOS device set-up in macOS - ready to connect, see below for instructions
And of course, some knowledge how to work with the terminal, GitHub repositories, and Docker.
- check out the the GitHub repository: run
git clone https://github.com/bjaan/roc-pulse-relay
- for the AMD64 architecture (modern PC hardware): change directory in to the AMD64 Dockerfile folder (TODO other architectures)
cd roc-pulse-relay/roc-pulse-relay-amd64
- run the Docker Compose Build command, this will use both the Dockerfile and the compose.yaml to build a new Docker Image, called bjaan/roc-pulse-relay-amd64
docker compose build
- run the Docker Compose Build command, this will create a Docker Container based on the bjaan/roc-pulse-relay-amd64 Docker Image, and start it up
docker compose up -d
- Roc Toolkit Receiver to PulseAudio relay is now running, it can be stopped, and restarted now through controlling the new container through Docker.
Note: these instructions assume that you are using Docker Desktop.
- From your terminal, test the following command, when you get static on your speakers, all is fine, when you get silence, it means that your PulseAudio is either not working or your audio configuration is not working speakers
pacat < /dev/urandom
Hint: in order to run pacat, you might have to install the pulseaudio-utils packages on Ubuntu: through this command sudo apt-get install pulseaudio-utils Hint: run the following command to figure out where your PulseAudio service is running:
echo $PULSE_SERVER
- From the Exec screen on the the roc-pulse-relay-amd64 container in Docker Desktop, the following command should result in static on your speakers, when you get silence the network connection between docker and your PulseAudio server is not working
pacat < /dev/urandom
- From your terminal copy a .wav-file (e.g. CantinaBand60.wav) to the roc-pulse-relay-amd64 container, replace the
???
with its container ID. (You can copy it from the Docker Desktop window, it is right below the container name, e.g.6982f5560704455c149e8ce16f206ec639c7498ed1abfffb7cea3065da1556e9
)
docker cp CantinaBand60.wav ???:/CantinaBand60.wav
- From the Exec screen on the the roc-pulse-relay-amd64 container in Docker Desktop, the following command should result in the Cantina Band's song playing on your speakers, when you get silence the network connection between docker and your PulseAudio server is not working
roc-send -vv -s rtp+rs8m://127.0.0.1:10001 -r rs8m://127.0.0.1:10002 -i file:CantinaBand60.wav
Follow the installation instructions here (roc-vad - Installation)
After installation, you need to set up your Virtual Speakers in macOS:
- First, create a Roc Sender Virtual Audio Device, using these instructions (roc-vad - Creating Sender)
roc-vad device add sender
- Then, connect it to the container or other Roc Receiver, with this command in Terminal :
roc-vad device connect <number of created Sender device, e.g. 1> \
--source rtp+rs8m://<Roc Receiver IP Address or Hostname>:10001 \
--repair rs8m://<Roc Receiver IP Address or Hostname>:10002 \
--control rtcp://<Roc Receiver IP Address or Hostname>:10003
When everything fails, first remove the Sender device again using:
roc-vad device del <number of created Sender device, e.g. 1>
and then create a new one.
The built-in WSLg PulseAudio might be unstable or giving glitchy sound, in that case it is recommended to install a proper PulseAudio server on Windows and repoint WSL 2 to that service rather than the built-in WSLg one.
- Install PulseAudio for Windows: downloaded the installer from here or follow this guide to get it installed as a service through manual steps Make sure that the default.pa or config.pa file or what ever default configuration file only has these lines:
load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;172.16.0.0/12
load-module module-esound-protocol-tcp auth-ip-acl=127.0.0.1;172.16.0.0/12
load-module module-waveout sink_name=output source_name=input record=0
- modify the .bashrc file that will set the $PULSE_SERVER environment variable when ever a WSL 2 session is started, to point to the Windows Service hosting PulseAudio. Using e.g.
nano ~/.bashrc
command (CTRL+O to save):- Comment out this line - in case it exists - to disable WSLg pulse server:
export PULSE_SERVER=unix:/mnt/wslg/runtime-dir/pulse/native
- Add these lines, this will set the $PULSE_SERVER variable and ensure that any app needing to connect to PulseAudio for sound will connect to the Windows Service instead:
- Comment out this line - in case it exists - to disable WSLg pulse server:
export HOST_IP="$(ip route |awk '/^default/{print $3}')"
export PULSE_SERVER="tcp:$HOST_IP"
- Test
pacat < /dev/urandom
- Set up receiver, which forwards received sound to the PulseAudio server, defined in the $PULSE_SERVER environment variable.
roc-recv -vv -s rtp+rs8m://0.0.0.0:10001 -r rs8m://0.0.0.0:10002 -c rtcp://0.0.0.0:10003 -o pulse://@DEFAULT_SINK@
- Set up sender, which plays the digital audio from the .wav-file to the receiver at 127.0.0.1 (local IP-address)
roc-send -vv -s rtp+rs8m://127.0.0.1:10001 -r rs8m://127.0.0.1:10002 -c rtcp://127.0.0.1:10003 -i file:CantinaBand60.wav
- Roc Toolkit Real-time audio streaming over the network. https://github.com/roc-streaming/roc-toolkit/
- PulseAudio modules for Roc Toolkit https://github.com/roc-streaming/roc-pulse/
- Roc Virtual Audio Device for macOS https://github.com/roc-streaming/roc-vad/