use async_trait::async_trait;
use pipecrab_core::{AudioChunk, DataFrame, Decision, Processor};
use pipecrab_runtime::{Outbound, Stage, StageError};
use crate::{SttError, Transcriber};
pub struct SttStage<T: Transcriber> {
transcriber: T,
}
impl<T: Transcriber> SttStage<T> {
pub fn new(transcriber: T) -> Self {
Self { transcriber }
}
}
pub struct Transcribe(AudioChunk);
impl<T: Transcriber> Processor for SttStage<T> {
type Effect = Transcribe;
fn decide_data(&mut self, frame: &DataFrame) -> Decision<Transcribe> {
match frame {
DataFrame::Audio(chunk) => Decision::drop().emit(Transcribe(chunk.clone())),
_ => Decision::forward(),
}
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<T: Transcriber> Stage for SttStage<T> {
async fn perform(&self, Transcribe(chunk): Transcribe, out: &Outbound) -> Result<(), StageError> {
let text = self.transcriber.transcribe(&chunk.samples, chunk.format).await?;
let _ = out.send_data(DataFrame::Transcript(text.into())).await;
Ok(())
}
}
impl From<SttError> for StageError {
fn from(e: SttError) -> Self {
StageError::new(e.to_string())
}
}