### Basic PetalSonic Usage Example Source: https://github.com/tr-nc/petalsonic/blob/main/README.md This example demonstrates the fundamental setup and usage of PetalSonic. It covers creating the audio world and engine, loading a 3D positioned sound, playing it, and updating the listener's position. Ensure 'sound.wav' exists and is accessible. ```rust use petalsonic::* fn main() -> Result<(), PetalSonicError> { // Create the audio world and engine let config = PetalSonicWorldDesc::default(); let world = PetalSonicWorld::new(config.clone())?; let mut engine = PetalSonicEngine::new(config, &world)?; engine.start()?; // Load and play a 3D positioned sound let audio = audio_data::PetalSonicAudioData::from_path("sound.wav")?; let source_id = world.register_audio( audio, SourceConfig::spatial(Vec3::new(5.0, 0.0, 0.0), 1.0) )?; world.play(source_id, playback::LoopMode::Once)?; // Update listener position in your game loop world.set_listener_pose(Pose::from_position(Vec3::ZERO)); Ok(()) } ``` -------------------------------- ### Implement Ray Tracer Examples Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md Provides examples of ready-to-use ray tracers for common scenarios, such as simple boxes, rooms, or an empty scene for testing. Used for setting up geometric audio environments. ```rust // Provide ready-to-use ray tracers for common scenarios: - SimpleBoxRayTracer::new(width, height, depth, material) - SimpleRoomRayTracer::with_walls(...) - EmptyRayTracer::new() // No geometry, for testing ``` -------------------------------- ### Basic PetalSonic Spatial Audio Setup and Playback Source: https://github.com/tr-nc/petalsonic/blob/main/petalsonic/README.md Demonstrates initializing the audio world and engine, loading an audio file, registering it as a spatial source, playing it once, updating the listener's position, and polling for playback events. ```rust use petalsonic::*; use std::sync::Arc; fn main() -> Result<(), PetalSonicError> { // Create a world configuration let config = PetalSonicWorldDesc::default(); // Create the audio world (runs on main thread) let world = PetalSonicWorld::new(config.clone())?; // Create and start the audio engine (spawns audio thread) let mut engine = PetalSonicEngine::new(config, &world)?; engine.start()?; // Load audio data from file let audio_data = audio_data::PetalSonicAudioData::from_path("path/to/audio.wav")?; // Register audio with spatial configuration let source_id = world.register_audio( audio_data, SourceConfig::spatial(Vec3::new(5.0, 0.0, 0.0), 1.0) // Position at (5, 0, 0) with volume 1.0 )?; // Play the audio once world.play(source_id, playback::LoopMode::Once)?; // Update listener position (typically in your game loop) world.set_listener_pose(Pose::from_position(Vec3::new(0.0, 0.0, 0.0))); // Poll for events for event in engine.poll_events() { match event { PetalSonicEvent::SourceCompleted { source_id } => { println!("Audio completed: {:?}", source_id); } PetalSonicEvent::SourceLooped { source_id, loop_count } => { println!("Audio looped: {:?} (iteration {})", source_id, loop_count); } _ => {} } } Ok(()) } ``` -------------------------------- ### Example: Implement and Register Custom Ray Tracer Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md This example demonstrates how to create a `MaterialTable`, implement the `RayTracer` trait with a custom scene intersection, and register it with the PetalSonic `world`. Ensure your `cast_ray` implementation correctly maps scene material IDs to the indices provided by the `MaterialTable`. ```rust use audionimbus::geometry::{Point, Direction}; // 1. Create material table let mut materials = MaterialTable::new(); let wall_mat = materials.add(AudioMaterial::CONCRETE); // index 0 let floor_mat = materials.add(AudioMaterial::WOOD); // index 1 let ceiling_mat = materials.add(AudioMaterial::PLASTER); // index 2 // 2. Implement custom ray tracer struct MyRayTracer { // Your existing scene data... } impl RayTracer for MyRayTracer { fn cast_ray(&self, origin: Point, direction: Direction, max_distance: f32) -> Result> { // Use your existing ray tracing code here if let Some(hit) = self.my_scene.intersect_ray(origin, direction, max_distance) { Ok(RayHit { hit: true, distance: hit.distance, material_index: hit.surface_material_id, // Map to your material system normal: hit.normal, }) } else { Ok(RayHit { hit: false, distance: 0.0, material_index: 0, normal: Direction::new(0.0, 1.0, 0.0) }) } } } // 3. Register with PetalSonic let tracer = MyRayTracer::new(/* ... */); world.set_ray_tracer(tracer, materials)?; // 4. Audio now uses your ray tracer for reflections and occlusion! ``` -------------------------------- ### Run PetalSonic Demo Application Source: https://github.com/tr-nc/petalsonic/blob/main/petalsonic/README.md Execute the demo application for PetalSonic using Cargo. This command is used to build and run the example project. ```bash cargo run --package petalsonic-demo ``` -------------------------------- ### Add SourceConfig Builder Pattern Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md Demonstrates the builder pattern for creating and configuring spatial audio sources. Allows for ergonomic and readable setup of source properties like volume and directivity. ```rust SourceConfig::spatial(position) .with_volume(0.8) .with_directivity(DirectivityPattern::Cardioid { orientation: Vec3::new(0.0, 0.0, -1.0), sharpness: 0.5 }) .with_occlusion(true) ``` -------------------------------- ### Build and Test Workspace Commands Source: https://github.com/tr-nc/petalsonic/blob/main/README.md Common commands for building, running the demo, testing, linting, and generating documentation for the Petalsonic workspace. ```bash cargo build ``` ```bash cargo run ``` ```bash cargo test ``` ```bash cargo clippy ``` ```bash cargo doc --open ``` -------------------------------- ### Reflection and Reverb Configuration Structures Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md Defines the configuration parameters for enabling and tuning reflection and reverb effects, including ray counts, duration, gain, and other relevant settings. ```rust pub struct ReflectionConfig { pub enabled: bool, pub num_rays: u32, pub num_bounces: u32, pub duration: f32, pub gain: f32, } pub struct ReverbConfig { pub enabled: bool, pub gain: f32, } ``` -------------------------------- ### Publishing Petalsonic Core Library to Crates.io Source: https://github.com/tr-nc/petalsonic/blob/main/README.md Steps to publish the petalsonic core library to crates.io, including login, versioning, verification, and the final publish command. Ensure you are in the core library directory before executing these commands. ```bash cargo login ``` ```bash cd petalsonic ``` ```bash cargo package --list ``` ```bash cargo publish --dry-run ``` ```bash cargo publish ``` ```bash cd .. ``` -------------------------------- ### Implement MaterialTable in Rust Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md Manages a collection of `AudioMaterial` instances, mapping indices to material properties. The `with_presets` function initializes the table with common material types. ```rust /// Material lookup table for ray tracer callbacks /// Maps material indices (u8) to AudioMaterial properties pub struct MaterialTable { materials: Vec, } impl MaterialTable { pub fn new() -> Self { /* ... */ } pub fn add(&mut self, material: AudioMaterial) -> u8 { /* returns index */ } pub fn get(&self, index: u8) -> Option<&AudioMaterial> { /* ... */ } /// Create a table with common presets pre-loaded pub fn with_presets() -> Self { let mut table = Self::new(); table.add(AudioMaterial::GENERIC); // index 0 table.add(AudioMaterial::BRICK); // index 1 table.add(AudioMaterial::CONCRETE); // index 2 // ... etc table } } ``` -------------------------------- ### Configure PetalSonicWorld Source: https://github.com/tr-nc/petalsonic/blob/main/petalsonic/README.md Sets up the main audio world configuration, including sample rate, block size, channels, and maximum sources. The distance scaler affects spatial audio simulation. ```rust use petalsonic::* let config = PetalSonicWorldDesc { sample_rate: 48000, block_size: 512, channels: 2, max_sources: 64, hrtf_path: None, hrtf_gain: 0.0, distance_scaler: 10.0, }; ``` -------------------------------- ### PetalSonic Custom Audio Loading Options Source: https://github.com/tr-nc/petalsonic/blob/main/petalsonic/README.md Loads audio data from a file with custom options, specifically forcing mono conversion for spatial audio sources. ```rust use petalsonic::audio_data::*; // Force mono conversion for spatial audio sources let options = LoadOptions::new() .convert_to_mono(ConvertToMono::ForceMono); let audio = PetalSonicAudioData::from_path_with_options( "sound_effect.wav", &options )?; ``` -------------------------------- ### PetalSonic Threading Model Source: https://github.com/tr-nc/petalsonic/blob/main/README.md Illustrates the flow of commands and data between the Main Thread, Render Thread, and Audio Callback. The Main Thread handles registration and commands, the Render Thread processes audio and spatialization, and the Audio Callback outputs audio frames. ```plaintext ┌──────────────────────────────────────────────────────────────┐ │ Main Thread (World) │ │ - register_audio(audio_data, SourceConfig) │ │ * SourceConfig::NonSpatial │ │ * SourceConfig::Spatial { position, volume, ... } │ │ - set_listener_pose(pose) │ │ - send PlaybackCommand via channel │ └──────────────────────────────────────────────────────────────┘ ↓ PlaybackCommand + SourceConfig ┌──────────────────────────────────────────────────────────────┐ │ Render Thread (generates samples at world rate) │ │ - Process PlaybackCommand │ │ - For each active source: │ │ ├─ NonSpatial → direct mixing │ │ └─ Spatial → Steam Audio (Direct, Encode, Decode) → mix │ │ - Push frames to ring buffer │ └──────────────────────────────────────────────────────────────┘ ↓ Ring Buffer (StereoFrame) ┌──────────────────────────────────────────────────────────────┐ │ Audio Callback (device rate) │ │ - Consume from ring buffer (lock-free) │ │ - Output to device │ └──────────────────────────────────────────────────────────────┘ ``` -------------------------------- ### Define Spatial Source Configuration Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md Defines the configuration structure for spatial audio sources, including position, volume, directivity, and occlusion settings. Used when setting up new audio sources. ```rust pub struct SpatialSourceConfig { pub position: Vec3, pub volume: f32, pub directivity: Option, pub occlusion_enabled: bool, pub occlusion_rays: u32, } pub enum DirectivityPattern { Omnidirectional, Cardioid { orientation: Vec3, sharpness: f32 }, Dipole { orientation: Vec3 }, Custom { /* callback or pattern data */ }, } ``` -------------------------------- ### Setting the Ray Tracer Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md Users can integrate their custom ray tracing logic by implementing the `RayTracer` trait and registering it with the `world` object using the `set_ray_tracer` method, along with a `MaterialTable`. ```APIDOC ## Function: world.set_ray_tracer ### Description Registers a custom ray tracer and material table with the spatial audio engine. ### Parameters - **`tracer`** (impl RayTracer): An object implementing the `RayTracer` trait. - **`materials`** (MaterialTable): A table containing acoustic material definitions. ### Usage Example ```rust let tracer = MyRayTracer::new(/* ... */); world.set_ray_tracer(tracer, materials)?; ``` ``` -------------------------------- ### Set Ray Tracer in PetalSonicWorld (Rust) Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md Configures the `PetalSonicWorld` with a specific `RayTracer` implementation and a `MaterialTable`. The `RayTracer` must be thread-safe (`Send + Sync`). ```rust impl PetalSonicWorld { pub fn set_ray_tracer( &self, ray_tracer: T, materials: MaterialTable ) -> Result<()> pub fn clear_ray_tracer(&self) -> Result<()> } ``` -------------------------------- ### Add PetalSonic to Cargo.toml Source: https://github.com/tr-nc/petalsonic/blob/main/petalsonic/README.md Include PetalSonic as a dependency in your project's Cargo.toml file. ```toml [dependencies] petalsonic = "0.1" ``` -------------------------------- ### Poll Timing Events for Performance Profiling Source: https://github.com/tr-nc/petalsonic/blob/main/petalsonic/README.md Retrieve and print timing information for various mixing and processing stages to profile performance. Useful for identifying bottlenecks in audio processing. ```rust for event in engine.poll_timing_events() { println!( "Mixing: {}μs (direct {}μs, spatial {}μs), physics {}μs, encode {}μs, decode {}μs, total {}μs", event.mixing_time_us, event.direct_mixing_time_us, event.spatial_time_us, event.spatial_simulation_time_us, event.ambisonics_encoding_time_us, event.ambisonics_decoding_time_us, event.total_time_us ); } ``` -------------------------------- ### SpatialProcessor Structure with Reflection and Reverb Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md Defines the fields within SpatialProcessor to handle reflection and reverb effects, including shared effect instances, buffers, and a listener source for reverb simulation. ```rust pub struct SpatialProcessor { // ...existing fields... reflection_effect: ReflectionEffect, // Shared for all sources reverb_effect: ReflectionEffect, // Global reverb listener_source: Source, // Special source for reverb cached_reflection_buf: Vec, // (frame_size * 9 channels) cached_reverb_buf: Vec // (frame_size * 9 channels) } ``` -------------------------------- ### Extend Render Timing Event Structure Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md Adds new fields to the RenderTimingEvent to capture detailed timing metrics for various spatial audio processing stages. Useful for performance analysis. ```rust pub struct RenderTimingEvent { pub mixing_time_us: u64, pub spatial_time_us: u64, pub resampling_time_us: u64, pub total_time_us: u64, // NEW: pub spatial_direct_time_us: u64, pub spatial_reflections_time_us: u64, pub spatial_reverb_time_us: u64, pub spatial_encode_time_us: u64, pub spatial_decode_time_us: u64, } ``` -------------------------------- ### PetalSonic Non-Spatial Background Music Playback Source: https://github.com/tr-nc/petalsonic/blob/main/petalsonic/README.md Loads an audio file and registers it as a non-spatial source for background music, playing it on an infinite loop. ```rust use petalsonic::*; // Load background music let music = audio_data::PetalSonicAudioData::from_path("music.mp3")?; // Register as non-spatial (no 3D effects, just plays normally) let music_id = world.register_audio( music, SourceConfig::non_spatial() )?; // Play on infinite loop world.play(music_id, playback::LoopMode::Infinite)?; ``` -------------------------------- ### Implement Custom AudioDataLoader in Rust Source: https://github.com/tr-nc/petalsonic/blob/main/petalsonic/README.md Implement the `AudioDataLoader` trait to support custom audio file formats. This involves defining a struct and implementing the `load` method with custom loading logic. ```rust use petalsonic::audio_data::*; struct MyLoader; impl AudioDataLoader for MyLoader { fn load(&self, path: &str, options: &LoadOptions) -> Result> { // Your custom loading logic todo!() } } ``` -------------------------------- ### Define RayTracer Trait and RayHit Struct Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md Implement this trait to provide custom ray tracing logic. The `cast_ray` method should return intersection details, including the material index for acoustic property lookup. Optional `begin_frame` and `end_frame` hooks are available. ```rust use audionimbus::geometry::{Point, Direction}; /// Trait for providing custom ray tracing to the spatial audio engine pub trait RayTracer: Send + Sync { /// Test if a ray intersects any geometry /// Returns: Result containing hit information, or error if ray trace failed fn cast_ray(&self, origin: Point, direction: Direction, max_distance: f32) -> Result>; /// Called once per frame before any ray casts (optional) fn begin_frame(&mut self) {} /// Called once per frame after all ray casts (optional) fn end_frame(&mut self) {} } pub struct RayHit { pub hit: bool, pub distance: f32, pub material_index: u8, // Index into material table pub normal: Direction, // Surface normal at hit point } ``` -------------------------------- ### RayTracer Trait Definition Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md The `RayTracer` trait defines the interface for custom ray tracing implementations. Users must implement the `cast_ray` method to provide intersection data to the spatial audio engine. Optional `begin_frame` and `end_frame` hooks are also provided for per-frame operations. ```APIDOC ## Trait: RayTracer ### Description Trait for providing custom ray tracing to the spatial audio engine. ### Methods #### `cast_ray(&self, origin: Point, direction: Direction, max_distance: f32) -> Result>` Test if a ray intersects any geometry. **Parameters:** - `origin` (Point): The starting point of the ray. - `direction` (Direction): The direction of the ray. - `max_distance` (f32): The maximum distance to trace the ray. **Returns:** - `Result>`: Contains hit information if an intersection occurs, or an error if the ray trace failed. #### `begin_frame(&mut self)` (Optional) Called once per frame before any ray casts. #### `end_frame(&mut self)` (Optional) Called once per frame after all ray casts. ``` -------------------------------- ### Define AudioMaterial Struct in Rust Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md Represents the acoustic properties of a surface material, including absorption, scattering, and transmission across different frequencies. Use this struct to define how sound interacts with surfaces. ```rust /// Acoustic properties of a surface material /// Matches IPLMaterial from Steam Audio C API #[derive(Debug, Clone, Copy)] pub struct AudioMaterial { /// Fraction of sound energy absorbed at [low, mid, high] frequencies (0.0 - 1.0) /// Frequency bands: 400 Hz, 2.5 KHz, 15 KHz pub absorption: [f32; 3], /// Fraction of sound energy scattered in random direction on reflection (0.0 - 1.0) /// 0.0 = pure specular (mirror-like), 1.0 = pure diffuse (scattered) pub scattering: f32, /// Fraction of sound energy transmitted through surface at [low, mid, high] frequencies (0.0 - 1.0) /// Used for direct occlusion calculations pub transmission: [f32; 3], } impl AudioMaterial { // Standard material presets pub const GENERIC: Self = Self { absorption: [0.10, 0.20, 0.30], scattering: 0.05, transmission: [0.100, 0.050, 0.030], }; pub const BRICK: Self = Self { absorption: [0.03, 0.04, 0.07], scattering: 0.05, transmission: [0.015, 0.015, 0.015], }; pub const CONCRETE: Self = Self { absorption: [0.05, 0.07, 0.08], scattering: 0.05, transmission: [0.015, 0.002, 0.001], }; pub const CERAMIC: Self = Self { absorption: [0.01, 0.02, 0.02], scattering: 0.05, transmission: [0.060, 0.044, 0.011], }; pub const GRAVEL: Self = Self { absorption: [0.60, 0.70, 0.80], scattering: 0.05, transmission: [0.031, 0.012, 0.008], }; pub const CARPET: Self = Self { absorption: [0.24, 0.69, 0.73], scattering: 0.05, transmission: [0.020, 0.005, 0.003], }; pub const GLASS: Self = Self { absorption: [0.06, 0.03, 0.02], scattering: 0.05, transmission: [0.060, 0.044, 0.011], }; pub const PLASTER: Self = Self { absorption: [0.12, 0.06, 0.04], scattering: 0.05, transmission: [0.056, 0.056, 0.004], }; pub const WOOD: Self = Self { absorption: [0.11, 0.07, 0.06], scattering: 0.05, transmission: [0.070, 0.014, 0.005], }; pub const METAL: Self = Self { absorption: [0.20, 0.07, 0.06], scattering: 0.05, transmission: [0.200, 0.025, 0.010], }; pub const ROCK: Self = Self { absorption: [0.13, 0.20, 0.24], scattering: 0.05, transmission: [0.015, 0.002, 0.001], }; } ``` -------------------------------- ### RayHit Struct Definition Source: https://github.com/tr-nc/petalsonic/blob/main/TODO.md The `RayHit` struct represents the result of a ray intersection test, containing information about the hit, distance, material index, and surface normal. ```APIDOC ## Struct: RayHit ### Description Information about a ray intersection. ### Fields - **`hit`** (bool) - Indicates if the ray intersected any geometry. - **`distance`** (f32) - The distance from the ray origin to the hit point. - **`material_index`** (u8) - Index into the material table for the intersected surface. - **`normal`** (Direction) - The surface normal at the hit point. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.