ROS Package bob_audio
A high-performance ROS 2 package for audio mixing and conversion, optimized for Docker and headless environments. It allows combining multiple audio sources (TTS, Music, SFX) into a single master stream without the need for a full audio server like PulseAudio or JACK.
Features
High Performance: Written in C++ with Multithreaded execution for low-latency audio processing.
Flexible Mixing: Mix a configurable number of ROS topics (via
Int16MultiArray) and optional FIFO inputs.Smart Upmixing: Automatic Mono-to-Stereo upmixing for seamless integration of TTS and music sources.
Dynamic Control: Live reconfiguration of gain and channel counts for each individual input via JSON.
Docker Friendly: No hardware audio device requirements.
Multiple Output Sinks: Stream to ROS topics, FIFO pipes, or directly to stdout (for FFmpeg).
Audio Conversion: Bidirectional conversion between raw streams and ROS messages.
Installation & Build
Prerequisites
ROS 2 Humble (or newer)
std_msgs,nlohmann_json
Build
# Navigate to your workspace
cd ~/ros2_ws/src
git clone https://github.com/bob-ros2/bob_audio.git
cd ..
colcon build --packages-select bob_audio
source install/setup.bash
ROS API
1. Mixer Node (mixer)
The mixer node takes multiple audio inputs and aggregates them into one master output using additive mixing with clipping protection.
Parameters & Environment Variables
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
int |
|
Number of input topics ( |
|
string |
|
Path to the output FIFO pipe. Enables FIFO output if set. (Env: |
|
bool |
|
Generate silent frames if no input is received (keeps stream alive). (Env: |
|
bool |
|
Write raw audio to stdout for piping (Env: |
|
bool |
|
Publish mixed audio to ROS topic |
|
bool |
|
Read from an additional input FIFO pipe (Env: |
|
string |
|
Path to the input FIFO (Env: |
|
int |
|
Audio sample rate in Hz (Env: |
|
int |
|
Number of audio channels (Env: |
|
int |
|
Processing interval per chunk in ms (Env: |
Topics
Subscribers:
in0…inN-1(std_msgs/msg/Int16MultiArray): Audio input streams.control(std_msgs/msg/String): JSON-based volume and channel control.
Publishers:
out(std_msgs/msg/Int16MultiArray): Mixed master output.
Dynamic Control (JSON)
You can adjust volumes and input channel counts on the fly by sending a JSON string to the control topic.
Format (Nested Object):
{
"in0": {"gain": 0.5, "channels": 1},
"in1": {"gain": 1.2},
"master": {"gain": 0.7}
}
Format (Flat Keys):
{
"in0_gain": 0.2,
"in1_channels": 2,
"fifo": 0.8
}
Example:
ros2 topic pub --once /control std_msgs/msg/String "{data: '{\"in0\": {\"gain\": 0.2, \"channels\": 1}, \"master\": 0.5}'}"
2. Convert Node (convert)
Bidirectional conversion between raw audio streams (FIFO/Pipe/stdin) and ROS messages.
Parameters & Environment Variables
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
string |
|
Operation mode ( |
|
string |
|
Path to the input or output FIFO |
|
bool |
|
Generate silent frames if no input is received in |
|
int |
|
Audio sample rate (Hz) |
|
int |
|
Number of audio channels |
|
int |
|
Audio chunk size per ROS message (ms) (Env: |
Topics
Subscribers:
in(std_msgs/msg/Int16MultiArray): Active if mode isros_to_fifo.Publishers:
out(std_msgs/msg/Int16MultiArray): Active if mode is*_to_ros.
Usage Examples
Endlessly looping Background Music
ffmpeg -re -stream_loop -1 -i music.mp3 -f s16le -ar 44100 -ac 2 pipe:1 | \
ros2 run bob_audio convert --ros-args -p mode:=stdin_to_ros -r out:=/bob/audio_music
Listening to ROS audio (e.g. from Mixer) via ffplay
# Convert ROS topic to FIFO
ros2 run bob_audio convert --ros-args \
-r in:=/out \
-p mode:=ros_to_fifo \
-p fifo_path:=/tmp/audio_ffplay
# Play the FIFO
ffplay -f s16le -ar 44100 -ac 2 -i /tmp/audio_ffplay
Piping Mixer directly into FFmpeg
export MIXER_ENABLE_STDOUT_OUTPUT=true
ros2 run bob_audio mixer | ffmpeg -f s16le -ar 44100 -ac 2 -i pipe:0 ...
Full Audio Pipeline Test (FFmpeg -> ROS -> ffplay)
A complete roundtrip to verify the entire system:
# 1. Create the FIFO for ffplay
mkfifo /tmp/audio_ffplay
# 2. Start the player (waits for data)
ffplay -f s16le -ar 44100 -ac 2 -i /tmp/audio_ffplay
# 3. Start the ROS-to-FIFO converter (Terminal 2)
ros2 run bob_audio convert --ros-args \
-p mode:=ros_to_fifo \
-p fifo_path:=/tmp/audio_ffplay \
-r in:=/audio_stream
# 4. Start the FFmpeg-to-ROS producer (Terminal 3)
ffmpeg -re -i music.mp3 -f s16le -ar 44100 -ac 2 pipe:1 | \
ros2 run bob_audio convert --ros-args \
-p mode:=stdin_to_ros \
-r out:=/audio_stream
License
Apache-2.0