pub mod estimator;
pub mod praat_ac;
pub mod pyin_est;
pub mod resample;
pub mod swipe;
pub use estimator::{calibrate_confidence, EstimatorError, PitchEstimator, PitchFrame, Result};
pub use praat_ac::PraatAcEstimator;
pub use pyin_est::PyinEstimator;
pub use swipe::SwipeEstimator;
pub struct PitchTracker {
estimator: Box<dyn PitchEstimator>,
resampler: resample::LinearResampler,
input_sr: u32,
target_sr: u32,
}
impl PitchTracker {
pub fn new<E: PitchEstimator + 'static>(
estimator: E,
input_sample_rate: u32,
resample_chunk: usize,
) -> Result<Self> {
Self::from_boxed(Box::new(estimator), input_sample_rate, resample_chunk)
}
pub fn from_boxed(
estimator: Box<dyn PitchEstimator>,
input_sample_rate: u32,
resample_chunk: usize,
) -> Result<Self> {
let target_sr = estimator.target_sample_rate();
let resampler =
resample::LinearResampler::new(input_sample_rate, target_sr, resample_chunk)?;
Ok(Self {
estimator,
resampler,
input_sr: input_sample_rate,
target_sr,
})
}
pub fn algorithm(&self) -> &str {
self.estimator.name()
}
pub fn input_sample_rate(&self) -> u32 {
self.input_sr
}
pub fn target_sample_rate(&self) -> u32 {
self.target_sr
}
pub fn reset(&mut self) {
self.resampler.reset();
self.estimator.reset();
}
pub fn process(&mut self, audio: &[f32]) -> Result<Vec<PitchFrame>> {
let resampled = self.resampler.push(audio)?;
if resampled.is_empty() {
return Ok(Vec::new());
}
self.estimator.process(&resampled)
}
}