mod common;
use transcribe_cpp::sys::{
TRANSCRIBE_EXT_KIND_PARAKEET_BUFFERED_STREAM, TRANSCRIBE_EXT_KIND_PARAKEET_STREAM,
TRANSCRIBE_EXT_KIND_VOXTRAL_REALTIME_STREAM,
};
use transcribe_cpp::{
ExtSlot, Model, ParakeetBufferedStreamOptions, ParakeetStreamOptions, RunOptions, Stream,
StreamExtension, StreamOptions, VoxtralRealtimeStreamOptions,
};
fn short_feed_text(stream: &mut Stream<'_>, pcm: &[f32]) -> (bool, String) {
let clip = &pcm[..pcm.len().min(2 * 16_000)];
for frame in clip.chunks(1600) {
stream.feed(frame).expect("feed");
}
let is_final = stream.finalize().expect("finalize").is_final;
(is_final, stream.text().full)
}
#[test]
fn parakeet_cache_aware_acceptance_discriminates() {
let Some(model_path) = common::smoke_parakeet_stream_model() else {
eprintln!("skip parakeet_cache_aware_acceptance_discriminates: model absent");
return;
};
let model = Model::load(&model_path).unwrap();
assert!(
model.accepts_ext(ExtSlot::Stream, TRANSCRIBE_EXT_KIND_PARAKEET_STREAM),
"cache-aware should accept PARAKEET_STREAM"
);
assert!(
!model.accepts_ext(
ExtSlot::Stream,
TRANSCRIBE_EXT_KIND_PARAKEET_BUFFERED_STREAM
),
"cache-aware should reject PARAKEET_BUFFERED_STREAM"
);
}
#[test]
fn parakeet_cache_aware_streams_with_extension() {
let (Some(model_path), Some(pcm)) =
(common::smoke_parakeet_stream_model(), common::smoke_audio())
else {
eprintln!("skip parakeet_cache_aware_streams_with_extension: model/audio absent");
return;
};
let mut session = Model::load(&model_path).unwrap().session().unwrap();
let opts = StreamOptions {
family: Some(StreamExtension::ParakeetStream(ParakeetStreamOptions {
att_context_right: Some(-1),
})),
..Default::default()
};
let mut stream = session.stream(&RunOptions::default(), &opts).unwrap();
let (is_final, text) = short_feed_text(&mut stream, &pcm);
assert!(is_final);
assert!(
!text.trim().is_empty(),
"cache-aware stream produced no text"
);
}
#[test]
fn parakeet_buffered_streams_with_extension() {
let (Some(model_path), Some(pcm)) = (
common::smoke_parakeet_buffered_model(),
common::smoke_audio(),
) else {
eprintln!("skip parakeet_buffered_streams_with_extension: model/audio absent");
return;
};
let model = Model::load(&model_path).unwrap();
assert!(
model.accepts_ext(
ExtSlot::Stream,
TRANSCRIBE_EXT_KIND_PARAKEET_BUFFERED_STREAM
),
"buffered model should accept PARAKEET_BUFFERED_STREAM"
);
let mut session = model.session().unwrap();
let opts = StreamOptions {
family: Some(StreamExtension::ParakeetBuffered(
ParakeetBufferedStreamOptions::default(),
)),
..Default::default()
};
let mut stream = session.stream(&RunOptions::default(), &opts).unwrap();
let (is_final, text) = short_feed_text(&mut stream, &pcm);
assert!(is_final);
assert!(!text.trim().is_empty(), "buffered stream produced no text");
}
#[test]
fn voxtral_realtime_streams_with_extension() {
let (Some(model_path), Some(pcm)) = (common::smoke_voxtral_model(), common::smoke_audio())
else {
eprintln!("skip voxtral_realtime_streams_with_extension: model/audio absent");
return;
};
let model = Model::load(&model_path).unwrap();
assert!(
model.accepts_ext(ExtSlot::Stream, TRANSCRIBE_EXT_KIND_VOXTRAL_REALTIME_STREAM),
"voxtral model should accept VOXTRAL_REALTIME_STREAM"
);
let mut session = model.session().unwrap();
let opts = StreamOptions {
family: Some(StreamExtension::VoxtralRealtime(
VoxtralRealtimeStreamOptions {
num_delay_tokens: Some(4),
..Default::default()
},
)),
..Default::default()
};
let mut stream = session.stream(&RunOptions::default(), &opts).unwrap();
let (is_final, text) = short_feed_text(&mut stream, &pcm);
assert!(is_final);
assert!(!text.trim().is_empty(), "voxtral produced no text");
}