voirs-spatial 0.1.0-rc.1

3D spatial audio and HRTF processing for VoiRS
Documentation
//! Basic spatial audio processing example
//!
//! This example demonstrates how to:
//! - Create a spatial audio processor
//! - Process audio with 3D positioning
//! - Apply HRTF and distance attenuation
//!
//! Run with: cargo run --example basic_spatial_audio --no-default-features

use voirs_spatial::{Position3D, SpatialConfig, SpatialEffect, SpatialProcessor, SpatialRequest};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("=== Basic Spatial Audio Example ===\n");

    // Create spatial audio configuration
    let config = SpatialConfig::default();
    println!("✓ Created spatial audio configuration");
    println!("  Sample rate: {} Hz", config.sample_rate);
    println!("  Buffer size: {} samples\n", config.buffer_size);

    // Create spatial processor
    let mut processor = SpatialProcessor::new(config).await?;
    println!("✓ Created spatial audio processor\n");

    // Generate a simple test audio signal (1 second of a sine wave)
    let sample_rate = 48000;
    let duration = 1.0; // seconds
    let frequency = 440.0; // A4 note
    let num_samples = (sample_rate as f32 * duration) as usize;

    let audio_data: Vec<f32> = (0..num_samples)
        .map(|i| {
            let t = i as f32 / sample_rate as f32;
            (2.0 * std::f32::consts::PI * frequency * t).sin() * 0.3
        })
        .collect();

    println!("✓ Generated test audio signal");
    println!("  Duration: {:.2}s", duration);
    println!("  Frequency: {}Hz", frequency);
    println!("  Samples: {}\n", num_samples);

    // Position sound source to the right of the listener
    let source_position = Position3D::new(2.0, 0.0, 0.0); // 2 meters to the right

    println!("✓ Positioned sound source");
    println!(
        "  Location: ({:.1}, {:.1}, {:.1}) meters\n",
        source_position.x, source_position.y, source_position.z
    );

    // Create spatial audio request
    let request = SpatialRequest {
        id: "example_source".to_string(),
        audio: audio_data,
        source_position,
        sample_rate,
        effects: vec![
            SpatialEffect::Hrtf,                // Apply HRTF for 3D positioning
            SpatialEffect::DistanceAttenuation, // Attenuate based on distance
            SpatialEffect::Reverb,              // Add room reverb
        ],
    };

    println!("✓ Created spatial audio request");
    println!("  Effects: HRTF, Distance Attenuation, Reverb\n");

    // Process the spatial audio
    println!("Processing spatial audio...");
    let result = processor.process_request(request).await?;

    println!("\n✓ Spatial audio processed successfully!");
    println!("  Left channel: {} samples", result.audio.left.len());
    println!("  Right channel: {} samples", result.audio.right.len());
    println!(
        "  Processing time: {:.2}ms",
        result.processing_time.as_secs_f64() * 1000.0
    );
    println!("  Request ID: {}", result.request_id);

    // Calculate some basic statistics
    let left_max = result
        .audio
        .left
        .iter()
        .map(|&x| x.abs())
        .max_by(|a, b| a.partial_cmp(b).unwrap())
        .unwrap_or(0.0);

    let right_max = result
        .audio
        .right
        .iter()
        .map(|&x| x.abs())
        .max_by(|a, b| a.partial_cmp(b).unwrap())
        .unwrap_or(0.0);

    println!("\nOutput Statistics:");
    println!("  Left channel peak: {:.3}", left_max);
    println!("  Right channel peak: {:.3}", right_max);
    println!(
        "  Stereo difference: {:.1}dB",
        20.0 * (right_max / left_max.max(0.001)).log10()
    );

    println!("\n✅ Example completed successfully!");

    Ok(())
}