This repo shows two paths for writing Foxglove audio messages into MCAP files:
| Message | Encoder | Script | Best for |
|---|---|---|---|
foxglove.RawAudio |
PCM S16 WAV bytes | audio_mcap.py |
Easiest debugging and exact uncompressed samples |
foxglove.CompressedAudio |
Opus packet or AAC-LC ADTS frame | C++ generators | Smaller files and codec-specific playback experiments |
The Python converter uses the published foxglove-sdk package and its bundled
foxglove.RawAudio schema. The C++ examples use the published MCAP C++ headers
from foxglove/mcap and a local copy of the draft foxglove.CompressedAudio
protobuf schema from foxglove/foxglove-sdk#428.
Install Python dependencies:
uv syncConvert a 16-bit PCM WAV file to foxglove.RawAudio messages:
uv run python audio_mcap.py input.wav --output raw-audio.mcapInspect the output with the MCAP CLI:
brew install mcap
mcap info raw-audio.mcapOpen raw-audio.mcap in Foxglove and add an audio panel for the /audio topic.
uv run python audio_mcap.py input.wav [more.wav ...] --output output.mcap [options]Arguments:
input.wav: One or more 16-bit PCM WAV files.--output,-o: MCAP output path. Defaults toout.mcap.--overwrite: Replace the output file if it already exists.--chunk-size: Number of PCM frames perRawAudiomessage. Defaults to1024.--topic: Output topic for one WAV file. Defaults to/audio. For multiple WAV files, the file index is appended, for example/audio1.
Examples:
uv run python audio_mcap.py audio.wav --output converted.mcap
uv run python audio_mcap.py audio.wav --output converted.mcap --chunk-size 2048
uv run python audio_mcap.py left.wav right.wav --output stereo_sources.mcapRawAudio output:
- Schema:
foxglove.RawAudiofromfoxglove-sdk - Message encoding:
protobuf - Topic:
/audiofor one input, or/audio1,/audio2, ... for multiple inputs format:pcm-s16- Audio bytes: interleaved little-endian signed 16-bit PCM
The C++ programs write Protobuf foxglove.CompressedAudio messages on the
audio topic. CompressedAudio.proto is copied from the in-progress Foxglove
SDK schema branch in foxglove/foxglove-sdk#428.
Until that schema lands in a released SDK, treat the MCAP output as matching
that draft schema.
CompressedAudio output:
| Generator | format |
Payload |
|---|---|---|
audio_to_opus_mcap |
opus |
One complete raw Opus packet per MCAP message |
audio_to_aac_mcap |
mp4a.40.2 |
One complete AAC-LC ADTS frame per MCAP message |
The examples favor readability over production-level configurability. The Opus generator pads the final short frame with silence so it is not dropped. The AAC generator flushes FDK-AAC at the end of input so buffered output is written.
- A C++17 compiler
- CMake
protocand protobuf C++ headers/libraries- Homebrew libraries:
protobuf,opus,fdk-aac,lz4, andzstd - Network access the first time CMake fetches the published
foxglove/mcapC++ headers
On macOS with Homebrew:
brew install cmake pkg-config protobuf opus fdk-aac lz4 zstd mcapThe Homebrew mcap package provides the CLI used for inspection. The C++ build
fetches the published foxglove/mcap release headers automatically. For offline
development, point CMake at an existing checkout:
cmake -S . -B build -DMCAP_CPP_SOURCE_DIR=/path/to/foxglove/mcapConfigure and build both generators:
cmake -S . -B build
cmake --build buildBuild only one generator:
cmake --build build --target audio_to_opus_mcap
cmake --build build --target audio_to_aac_mcapRemove generated binaries and build files:
rm -rf buildGenerate an Opus CompressedAudio MCAP:
./build/audio_to_opus_mcap input.wav output-opus.mcapGenerate an AAC-LC ADTS CompressedAudio MCAP:
./build/audio_to_aac_mcap input.wav output-aac.mcapThe Opus generator supports mono or stereo WAV files at 8000, 12000, 16000, 24000, or 48000 Hz. The AAC generator supports mono or stereo WAV files.
Inspect either output with:
mcap info output-opus.mcapMIT