1use std::ffi::CString;
15
16use transcribe_cpp_sys as sys;
17
18use crate::error::Result;
19
20#[derive(Debug, Clone, Default, PartialEq)]
23pub struct WhisperRunOptions {
24 pub initial_prompt: Option<String>,
25 pub condition_on_prev_tokens: Option<bool>,
26 pub temperature: Option<f32>,
27 pub temperature_inc: Option<f32>,
28 pub compression_ratio_thold: Option<f32>,
29 pub logprob_thold: Option<f32>,
30 pub no_speech_thold: Option<f32>,
31 pub max_prev_context_tokens: Option<i32>,
32 pub seed: Option<u32>,
33 pub max_initial_timestamp: Option<f32>,
34}
35
36#[derive(Debug, Clone, Default, PartialEq, Eq)]
38pub struct MoonshineStreamingOptions {
39 pub min_decode_interval_ms: Option<i32>,
40}
41
42#[derive(Debug, Clone, Default, PartialEq, Eq)]
44pub struct ParakeetStreamOptions {
45 pub att_context_right: Option<i32>,
46}
47
48#[derive(Debug, Clone, Default, PartialEq, Eq)]
50pub struct ParakeetBufferedStreamOptions {
51 pub left_ms: Option<i32>,
52 pub chunk_ms: Option<i32>,
53 pub right_ms: Option<i32>,
54}
55
56#[derive(Debug, Clone, Default, PartialEq, Eq)]
58pub struct VoxtralRealtimeStreamOptions {
59 pub num_delay_tokens: Option<i32>,
60 pub min_decode_interval_ms: Option<i32>,
61}
62
63#[derive(Debug, Clone, PartialEq)]
65#[non_exhaustive]
66pub enum RunExtension {
67 Whisper(WhisperRunOptions),
68}
69
70#[derive(Debug, Clone, PartialEq, Eq)]
72#[non_exhaustive]
73pub enum StreamExtension {
74 ParakeetStream(ParakeetStreamOptions),
75 ParakeetBuffered(ParakeetBufferedStreamOptions),
76 MoonshineStreaming(MoonshineStreamingOptions),
77 VoxtralRealtime(VoxtralRealtimeStreamOptions),
78}
79
80pub(crate) enum RunExtRaw {
85 Whisper {
86 ext: Box<sys::transcribe_whisper_run_ext>,
87 _prompt: Option<CString>,
88 },
89}
90
91impl RunExtRaw {
92 pub(crate) fn ext_ptr(&self) -> *const sys::transcribe_ext {
93 match self {
94 RunExtRaw::Whisper { ext, .. } => {
96 (&**ext) as *const sys::transcribe_whisper_run_ext as *const sys::transcribe_ext
97 }
98 }
99 }
100}
101
102impl RunExtension {
103 pub(crate) fn materialize(&self) -> Result<RunExtRaw> {
104 match self {
105 RunExtension::Whisper(o) => {
106 let mut ext: sys::transcribe_whisper_run_ext = unsafe { std::mem::zeroed() };
107 unsafe { sys::transcribe_whisper_run_ext_init(&mut ext) };
108 let prompt = o.initial_prompt.as_deref().map(CString::new).transpose()?;
111 if let Some(c) = prompt.as_ref() {
112 ext.initial_prompt = c.as_ptr();
113 }
114 set(
115 &mut ext.condition_on_prev_tokens,
116 o.condition_on_prev_tokens,
117 );
118 set(&mut ext.temperature, o.temperature);
119 set(&mut ext.temperature_inc, o.temperature_inc);
120 set(&mut ext.compression_ratio_thold, o.compression_ratio_thold);
121 set(&mut ext.logprob_thold, o.logprob_thold);
122 set(&mut ext.no_speech_thold, o.no_speech_thold);
123 set(&mut ext.max_prev_context_tokens, o.max_prev_context_tokens);
124 set(&mut ext.seed, o.seed);
125 set(&mut ext.max_initial_timestamp, o.max_initial_timestamp);
126 Ok(RunExtRaw::Whisper {
127 ext: Box::new(ext),
128 _prompt: prompt,
129 })
130 }
131 }
132 }
133}
134
135pub(crate) enum StreamExtRaw {
137 ParakeetStream(Box<sys::transcribe_parakeet_stream_ext>),
138 ParakeetBuffered(Box<sys::transcribe_parakeet_buffered_stream_ext>),
139 MoonshineStreaming(Box<sys::transcribe_moonshine_streaming_stream_ext>),
140 VoxtralRealtime(Box<sys::transcribe_voxtral_realtime_stream_ext>),
141}
142
143impl StreamExtRaw {
144 pub(crate) fn ext_ptr(&self) -> *const sys::transcribe_ext {
145 match self {
146 StreamExtRaw::ParakeetStream(e) => {
147 (&**e) as *const sys::transcribe_parakeet_stream_ext as *const sys::transcribe_ext
148 }
149 StreamExtRaw::ParakeetBuffered(e) => {
150 (&**e) as *const sys::transcribe_parakeet_buffered_stream_ext
151 as *const sys::transcribe_ext
152 }
153 StreamExtRaw::MoonshineStreaming(e) => {
154 (&**e) as *const sys::transcribe_moonshine_streaming_stream_ext
155 as *const sys::transcribe_ext
156 }
157 StreamExtRaw::VoxtralRealtime(e) => {
158 (&**e) as *const sys::transcribe_voxtral_realtime_stream_ext
159 as *const sys::transcribe_ext
160 }
161 }
162 }
163}
164
165impl StreamExtension {
166 pub(crate) fn materialize(&self) -> StreamExtRaw {
167 match self {
168 StreamExtension::ParakeetStream(o) => {
169 let mut e: sys::transcribe_parakeet_stream_ext = unsafe { std::mem::zeroed() };
170 unsafe { sys::transcribe_parakeet_stream_ext_init(&mut e) };
171 set(&mut e.att_context_right, o.att_context_right);
172 StreamExtRaw::ParakeetStream(Box::new(e))
173 }
174 StreamExtension::ParakeetBuffered(o) => {
175 let mut e: sys::transcribe_parakeet_buffered_stream_ext =
176 unsafe { std::mem::zeroed() };
177 unsafe { sys::transcribe_parakeet_buffered_stream_ext_init(&mut e) };
178 set(&mut e.left_ms, o.left_ms);
179 set(&mut e.chunk_ms, o.chunk_ms);
180 set(&mut e.right_ms, o.right_ms);
181 StreamExtRaw::ParakeetBuffered(Box::new(e))
182 }
183 StreamExtension::MoonshineStreaming(o) => {
184 let mut e: sys::transcribe_moonshine_streaming_stream_ext =
185 unsafe { std::mem::zeroed() };
186 unsafe { sys::transcribe_moonshine_streaming_stream_ext_init(&mut e) };
187 set(&mut e.min_decode_interval_ms, o.min_decode_interval_ms);
188 StreamExtRaw::MoonshineStreaming(Box::new(e))
189 }
190 StreamExtension::VoxtralRealtime(o) => {
191 let mut e: sys::transcribe_voxtral_realtime_stream_ext =
192 unsafe { std::mem::zeroed() };
193 unsafe { sys::transcribe_voxtral_realtime_stream_ext_init(&mut e) };
194 set(&mut e.num_delay_tokens, o.num_delay_tokens);
195 set(&mut e.min_decode_interval_ms, o.min_decode_interval_ms);
196 StreamExtRaw::VoxtralRealtime(Box::new(e))
197 }
198 }
199 }
200}
201
202fn set<T>(slot: &mut T, value: Option<T>) {
204 if let Some(v) = value {
205 *slot = v;
206 }
207}