use crate::estimator::{EstimatorError, PitchEstimator, PitchFrame, Result};
use swipe_rs::{Swipe, SAMPLE_RATE};
pub use swipe_rs::DEFAULT_MAX_WINDOW;
pub struct SwipeEstimator {
inner: Swipe,
scratch: Vec<swipe_rs::PitchFrame>,
}
impl SwipeEstimator {
pub fn with_max_window(max_window: usize) -> Result<Self> {
let inner = Swipe::with_max_window(max_window)
.map_err(|e| EstimatorError::Ort(format!("swipe init: {e}")))?;
Ok(Self {
inner,
scratch: Vec::new(),
})
}
pub fn new() -> Result<Self> {
let inner =
Swipe::new().map_err(|e| EstimatorError::Ort(format!("swipe init: {e}")))?;
Ok(Self {
inner,
scratch: Vec::new(),
})
}
}
impl PitchEstimator for SwipeEstimator {
fn name(&self) -> &str {
"swipe"
}
fn target_sample_rate(&self) -> u32 {
SAMPLE_RATE
}
fn reset(&mut self) {
self.inner.reset();
self.scratch.clear();
}
fn process(&mut self, audio: &[f32]) -> Result<Vec<PitchFrame>> {
self.scratch.clear();
self.inner
.process_into(audio, &mut self.scratch)
.map_err(|e| EstimatorError::Ort(format!("swipe fft: {e}")))?;
Ok(self
.scratch
.iter()
.map(|f| PitchFrame {
frame_index: f.frame_index,
time_s: f.time_s,
pitch_hz: f.pitch_hz,
confidence: f.confidence,
is_preliminary: false,
})
.collect())
}
}