use crate::{
Result, SampleRate, Session, SpeechOptions, SpeechSegment, SpeechSegmenter, StreamState,
};
pub trait SpeechSegmenterExt {
fn push_samples(
&mut self,
session: &mut Session,
stream: &mut StreamState,
samples: &[f32],
) -> Result<Option<SpeechSegment>>;
fn flush_stream(
&mut self,
session: &mut Session,
stream: &mut StreamState,
) -> Result<Option<SpeechSegment>>;
fn finish_stream(
&mut self,
session: &mut Session,
stream: &mut StreamState,
) -> Result<Option<SpeechSegment>>;
}
impl SpeechSegmenterExt for SpeechSegmenter {
fn push_samples(
&mut self,
session: &mut Session,
stream: &mut StreamState,
samples: &[f32],
) -> Result<Option<SpeechSegment>> {
ensure_sample_rate(self, stream.sample_rate())?;
if !samples.is_empty() {
let probabilities = session.process_stream(stream, samples)?;
self.push_probabilities(probabilities);
}
Ok(self.pop_pending())
}
fn flush_stream(
&mut self,
session: &mut Session,
stream: &mut StreamState,
) -> Result<Option<SpeechSegment>> {
ensure_sample_rate(self, stream.sample_rate())?;
if let Some(probability) = session.flush_stream(stream)? {
self.push_probabilities(&[probability]);
}
Ok(self.pop_pending())
}
fn finish_stream(
&mut self,
session: &mut Session,
stream: &mut StreamState,
) -> Result<Option<SpeechSegment>> {
ensure_sample_rate(self, stream.sample_rate())?;
if let Some(probability) = session.flush_stream(stream)? {
self.push_probabilities(&[probability]);
}
Ok(self.finish())
}
}
fn ensure_sample_rate(segmenter: &SpeechSegmenter, sample_rate: SampleRate) -> Result<()> {
if segmenter.sample_rate() == sample_rate {
Ok(())
} else {
Err(
zuoer::Error::IncompatibleSampleRate {
expected: segmenter.sample_rate().hz(),
actual: sample_rate.hz(),
}
.into(),
)
}
}
pub fn detect_speech(
session: &mut Session,
samples: &[f32],
config: SpeechOptions,
) -> Result<Vec<SpeechSegment>> {
let mut stream = StreamState::new(config.sample_rate());
let mut segmenter = SpeechSegmenter::new(config);
let mut segments = Vec::new();
if let Some(segment) = segmenter.push_samples(session, &mut stream, samples)? {
segments.push(segment);
while let Some(more) = segmenter.push_samples(session, &mut stream, &[])? {
segments.push(more);
}
}
if let Some(segment) = segmenter.finish_stream(session, &mut stream)? {
segments.push(segment);
while let Some(more) = segmenter.push_samples(session, &mut stream, &[])? {
segments.push(more);
}
}
Ok(segments)
}