PetalSonic
A real-time safe spatial audio library for Rust that uses Steam Audio for 3D spatialization.
Features
- High-Quality 3D Spatialization: Steam Audio integration for HRTF-based binaural audio
- Real-Time Safe: No allocations or locks in the audio callback path
- Flexible Source Management: Support for both spatial and non-spatial audio sources
- Automatic Resampling: Audio is automatically resampled to match the world's sample rate
- Multiple Loop Modes: Play once, loop infinitely, or loop a specific number of times
- Event-Driven: Get notified of playback events (completion, loops, errors)
- Multiple Audio Formats: Support for WAV, MP3, FLAC, OGG, and more via Symphonia
Quick Start
Add this to your Cargo.toml:
[]
= "0.1"
Basic Example
use *;
use Arc;
Non-Spatial Audio Example
use *;
// Load background music
let music = from_path?;
// Register as non-spatial (no 3D effects, just plays normally)
let music_id = world.register_audio?;
// Play on infinite loop
world.play?;
Custom Audio Loading
use *;
// Force mono conversion for spatial audio sources
let options = new
.convert_to_mono;
let audio = from_path_with_options?;
Architecture
PetalSonic uses a three-layer threading model to ensure real-time safety:
┌──────────────────────────────────────────────────────────────┐
│ Main Thread (World) │
│ - register_audio(audio_data, SourceConfig) │
│ - set_listener_pose(pose) │
│ - play(), pause(), stop() │
│ - poll_events() │
└──────────────────────────────────────────────────────────────┘
↓ Commands via channel
┌──────────────────────────────────────────────────────────────┐
│ Render Thread (generates samples at world rate) │
│ - Process playback commands │
│ - Spatialize audio sources via Steam Audio │
│ - Mix sources together │
│ - Push frames to ring buffer │
└──────────────────────────────────────────────────────────────┘
↓ Lock-free ring buffer
┌──────────────────────────────────────────────────────────────┐
│ Audio Callback (device rate) │
│ - Consume from ring buffer (real-time safe) │
│ - Output to audio device via CPAL │
└──────────────────────────────────────────────────────────────┘
Key Design Principles
- World-Driven API: Main thread owns the 3D world state
- Real-Time Safety: Audio callback has no allocations, locks, or blocking operations
- Lock-Free Communication: Commands sent via channels, audio data via ring buffer
- Automatic Resampling: All audio is resampled to world rate on load
- Mixed Spatialization: Spatial and non-spatial sources coexist in the same world
API Overview
Core Types
PetalSonicWorld: Main API for managing audio sources and playback (main thread)PetalSonicEngine: Audio processing engine (dedicated thread)SourceId: Type-safe handle for audio sourcesSourceConfig: Configuration for spatial vs. non-spatial sourcesPetalSonicAudioData: Container for loaded and decoded audio data
Configuration
PetalSonicWorldDesc: World configuration (sample rate, channels, buffer size, etc.)LoadOptions: Options for audio loading (mono conversion, etc.)
Playback Control
LoopMode:OnceorInfinitePlayState:Playing,Paused, orStoppedPlaybackInfo: Detailed playback position and timing
Events
PetalSonicEvent: Events emitted by the engineSourceCompleted,SourceLooped,SourceStarted,SourceStoppedBufferUnderrun,BufferOverrunEngineError,SpatializationError
Math & Spatial
Pose: Position + rotation for listener and sourcesVec3: 3D vector (fromglamcrate)Quat: Quaternion rotation (fromglamcrate)
Configuration Options
use *;
let config = PetalSonicWorldDesc ;
Performance Considerations
Real-Time Safety
The audio callback thread is completely real-time safe:
- No allocations
- No locks
- No blocking operations
- Only lock-free ring buffer reads
Buffer Sizing
block_size: Smaller = lower latency, higher CPU usage (typical: 256-1024)buffer_duration: Ring buffer size in seconds (typical: 0.1-0.5)- Balance latency vs. robustness based on your target platform
Performance Monitoring
// Get timing information for performance profiling
for event in engine.poll_timing_events
Advanced Features
Custom Audio Loaders
Implement AudioDataLoader for custom file formats:
use *;
;
Examples
See the petalsonic-demo crate for complete examples:
# Run the demo application
Platform Support
PetalSonic uses:
- CPAL for cross-platform audio output (Windows, macOS, Linux, iOS, Android, Web)
- Symphonia for audio decoding (supports most common formats)
- Steam Audio (audionimbus) for spatialization (auto-installs native library)
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.