Files
rustytorch/crates/models/rtx-csm/examples/make_silence_test.rs
T
osobhandClaude Opus 4.7 a5cedfb46a rtx-csm: emotional_speech_guide — CREMA-D vs RAVDESS firdhokk verdict
8-gen bench (4 emotions × 2 corpora) at seed=42 against firdhokk
Whisper-LV3:

  target    RAVDESS              CREMA-D
  happy     happy (0.999) ✓      happy (0.999) ✓
  angry     neutral (0.92)       sad (0.99)
  fearful   happy (0.998)        fearful (0.984) ✓
  sad       angry (0.99)         fearful (0.99)

CREMA-D 2/4 vs RAVDESS 1/4. Larger / more naturalistic corpus
produces more class-pure fearful direction. Neither corpus solves
angry or sad — recipe shifts into 'vague expressivity' rather than
class-specific corners.

Practical: prefer CREMA-D when available; A/B both per emotion if
class precision matters.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-04-30 00:01:02 -07:00

59 lines
1.9 KiB
Rust

//! Phase 8.1.3 follow-up: build a 10 s WAV that is 50% silence + 50%
//! real speech so we can verify the energy VAD gate actually skips
//! silence. The standard /tmp/asr_test.flac is ~90% speech, which
//! masks the structural VAD win.
//!
//! Output: /tmp/asr_silence_heavy.wav (10 s @ 24 kHz mono).
//!
//! Layout: 1 s silence, 4 s speech, 2 s silence, 3 s silence (total
//! 5 s silence + 5 s speech). Speech is taken from the start of the
//! input WAV.
//!
//! Usage:
//! ```bash
//! cargo run -p rtx-csm --release --example make_silence_test -- \
//! --in /tmp/asr_test.flac --out /tmp/asr_silence_heavy.wav
//! ```
use anyhow::{Context, Result};
use clap::Parser;
use rtx_csm::audio_io;
use std::path::PathBuf;
const SR: u32 = 24_000;
#[derive(Debug, Parser)]
struct Cli {
#[arg(long = "in", default_value = "/tmp/asr_test.flac")]
input: PathBuf,
#[arg(long, default_value = "/tmp/asr_silence_heavy.wav")]
out: PathBuf,
}
fn main() -> Result<()> {
let cli = Cli::parse();
let speech = audio_io::load_mono_at_rate(&cli.input, SR).context("load speech")?;
eprintln!(
"loaded speech: {} samples ({:.2}s)",
speech.len(),
speech.len() as f32 / SR as f32
);
// Build: 1s silence | 4s speech | 2s silence | 3s silence (= 5s+5s).
let mut out: Vec<f32> = Vec::with_capacity(SR as usize * 10);
out.extend(std::iter::repeat(0.0f32).take(SR as usize)); // 1 s
let speech_4s = (SR as usize * 4).min(speech.len());
out.extend_from_slice(&speech[..speech_4s]); // 4 s
out.extend(std::iter::repeat(0.0f32).take(SR as usize * 2)); // 2 s
out.extend(std::iter::repeat(0.0f32).take(SR as usize * 3)); // 3 s
audio_io::write_wav_mono(cli.out.as_path(), &out, SR).context("write wav")?;
eprintln!(
"wrote {} ({} samples = {:.2}s, ~50% silence + 50% speech)",
cli.out.display(),
out.len(),
out.len() as f32 / SR as f32
);
Ok(())
}