# ROS Package [bob_audio](https://github.com/bob-ros2/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 minimal overhead. - **Flexible Mixing**: Mix up to 8 ROS topics (via `Int16MultiArray`) and optional FIFO inputs. - **Real-time Volume Control**: Change gain for each input or master 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**: Easily convert between raw pipes/stdin and ROS messages. ## Installation & Build ### Prerequisites - ROS 2 Humble (or newer) - `std_msgs`, `nlohmann_json` ### Build ```bash # 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 | | :--- | :--- | :--- | :--- | | `enable_fifo_output` | bool | `false` | Enable writing to a FIFO pipe (Env: `MIXER_ENABLE_FIFO_OUTPUT`) | | `output_fifo` | string | `/tmp/audio_master_pipe`| Path to the master output FIFO (Env: `MIXER_OUTPUT_FIFO`) | | `enable_stdout_output`| bool | `false` | Write raw audio to stdout for piping (Env: `MIXER_ENABLE_STDOUT_OUTPUT`) | | `enable_topic_output` | bool | `true` | Publish mixed audio to ROS topic `out` (Env: `MIXER_ENABLE_TOPIC_OUTPUT`) | | `enable_fifo_input` | bool | `false` | Read from an additional input FIFO pipe (Env: `MIXER_ENABLE_FIFO_INPUT`) | | `input_fifo` | string | `/tmp/audio_pipe` | Path to the input FIFO (Env: `MIXER_INPUT_FIFO`) | | `sample_rate` | int | `44100` | Audio sample rate in Hz (Env: `MIXER_SAMPLE_RATE`) | | `channels` | int | `2` | Number of audio channels (Env: `MIXER_CHANNELS`) | | `chunk_ms` | int | `20` | Processing interval per chunk in ms (Env: `MIXER_CHUNK_MS`) | #### Topics - **Subscribers**: - `in0` ... `in7` (`std_msgs/msg/Int16MultiArray`): Audio input streams. - `levels` (`std_msgs/msg/String`): JSON-based volume control. - **Publishers**: - `out` (`std_msgs/msg/Int16MultiArray`): Mixed master output. #### Real-time Volume Control (JSON) You can adjust volumes on the fly by sending a JSON string to the `levels` topic. **Format:** ```json { "in0": 0.5, // Set input 0 to 50% "in1": 1.2, // Set input 1 to 120% "fifo": 0.8, // Set FIFO input gain "master": 0.7 // Set global master gain } ``` **Example:** ```bash ros2 topic pub --once /levels std_msgs/msg/String "{data: '{\"in0\": 0.2, \"master\": 0.5}'}" ``` ### 2. Convert Node (`convert`) Converts external raw audio streams (from files, pipes, or stdin) into ROS topics for the mixer. #### Parameters & Environment Variables | Parameter | Type | Default | Description | | :--- | :--- | :--- | :--- | | `enable_fifo` | bool | `false` | Read raw bytes from a FIFO pipe (Env: `CONVERT_ENABLE_FIFO`) | | `input_fifo` | string | `/tmp/audio_pipe` | Path to the input FIFO (Env: `CONVERT_INPUT_FIFO`) | | `enable_stdin` | bool | `false` | Read raw bytes from stdin (Env: `CONVERT_ENABLE_STDIN`) | | `sample_rate` | int | `44100` | Audio sample rate in Hz (Env: `CONVERT_SAMPLE_RATE`) | | `channels` | int | `2` | Number of audio channels (Env: `CONVERT_CHANNELS`) | | `chunk_ms` | int | `20` | Chunk size in ms per ROS message (Env: `CONVERT_CHUNK_MS`) | #### Topics - **Publishers**: `out` (`std_msgs/msg/Int16MultiArray`). ## Usage Examples ### Endlessly looping Background Music ```bash ffmpeg -re -stream_loop -1 -i music.mp3 -f s16le -ar 44100 -ac 2 pipe:1 | \ ros2 run bob_audio convert --ros-args -p enable_stdin:=true -r out:=/bob/audio_music ``` ### Mixing TTS and Music for a Twitch Stream ```bash # Start the mixer, remapping inputs to specific sources ros2 run bob_audio mixer --ros-args \ -r in0:=/bob/audio_speech \ -r in1:=/bob/audio_music \ -p enable_fifo_output:=true \ -p output_fifo:=/tmp/audio_master_pipe ``` ### Piping directly into FFmpeg ```bash export MIXER_ENABLE_STDOUT_OUTPUT=true ros2 run bob_audio mixer | ffmpeg -f s16le -ar 44100 -ac 2 -i pipe:0 ... ``` ## License Apache-2.0