speakrs 0.6.0

Fast Rust speaker diarization with pyannote-level accuracy and native CPU/CoreML/CUDA inference
Documentation
mod support;

use std::path::{Path, PathBuf};
use std::thread;
use std::time::Duration;

use speakrs::{ExecutionMode, PipelineBuilder, QueueError, QueuedDiarizationRequest};

use support::{ExampleResult, file_id_from_path, load_wav_samples};

fn main() -> ExampleResult<()> {
    support::init_tracing();
    let args: Vec<String> = std::env::args().collect();
    if args.len() < 3 {
        eprintln!(
            "Usage: cargo run --features cpu --example queued -- <models-dir> <audio.wav> [audio2.wav ...]"
        );
        std::process::exit(1);
    }

    let models_dir = Path::new(&args[1]);
    let audio_paths: Vec<PathBuf> = args[2..].iter().map(PathBuf::from).collect();
    let (tx, rx) = PipelineBuilder::from_dir(models_dir, ExecutionMode::Cpu)?.build_queued()?;

    let mut handles = Vec::with_capacity(audio_paths.len());
    for audio_path in audio_paths {
        let tx = tx.clone();
        let file_id = file_id_from_path(&audio_path);
        let audio = load_wav_samples(&audio_path)?;
        handles.push(thread::spawn(move || {
            let mut request = QueuedDiarizationRequest::new(file_id, audio);
            let mut retry_delay = Duration::from_millis(1);

            loop {
                match tx.try_push(request) {
                    Ok(_) => return Ok(()),
                    Err(QueueError::Full(rejected)) => {
                        request = rejected;
                        thread::sleep(retry_delay);
                        retry_delay = retry_delay
                            .saturating_mul(2)
                            .min(Duration::from_millis(100));
                    }
                    Err(error) => return Err(error),
                }
            }
        }));
    }
    drop(tx);

    for result in rx {
        let result = result?;
        print!("{}", result.result?.rttm(&result.file_id));
    }

    for handle in handles {
        handle
            .join()
            .map_err(|_| "queue sender thread panicked")??;
    }

    Ok(())
}