@@ -47,7 +47,7 @@ extern void ruby_whisper_callback_container_mark(ruby_whisper_callback_container
4747extern ruby_whisper_callback_container * ruby_whisper_callback_container_allocate (void );
4848extern bool ruby_whisper_callback_container_is_present (const ruby_whisper_callback_container * container );
4949extern VALUE ruby_whisper_parakeet_segment_init (VALUE context , int index );
50- extern VALUE ruby_whisper_parakeet_token_s_from_token_data (struct parakeet_context * context , parakeet_token_data * token_data );
50+ extern VALUE ruby_whisper_parakeet_token_s_from_token_data (struct parakeet_context * context , const parakeet_token_data * token_data );
5151
5252static ID param_names [RUBY_WHISPER_PARAKEET_NUM_PARAMS ];
5353typedef VALUE (* param_writer_t )(VALUE , VALUE );
@@ -157,15 +157,146 @@ ruby_whisper_parakeet_new_token_callback(struct parakeet_context *context, struc
157157 rb_thread_call_with_gvl (call_parakeet_new_token_callbacks , (void * )& args );
158158}
159159
160+ typedef struct {
161+ const ruby_whisper_callback_container * container ;
162+ struct parakeet_state * state ;
163+ int progress ;
164+ } call_parakeet_progress_callbacks_args ;
165+
166+ static void *
167+ call_parakeet_progress_callback (void * v_args )
168+ {
169+ call_parakeet_progress_callbacks_args * args = (call_parakeet_progress_callbacks_args * )v_args ;
170+ const ruby_whisper_callback_container * container = args -> container ;
171+
172+ if (!NIL_P (container -> callback )) {
173+ rb_funcall (container -> callback , id_call , 4 , * container -> context , Qnil , INT2NUM (args -> progress ), container -> user_data );
174+ }
175+ if (NIL_P (container -> callbacks )) {
176+ return NULL ;
177+ }
178+ const long n_callbacks = RARRAY_LEN (container -> callbacks );
179+ if (n_callbacks == 0 ) {
180+ return NULL ;
181+ }
182+ for (long i = 0 ; i < n_callbacks ; i ++ ) {
183+ VALUE cb = rb_ary_entry (container -> callbacks , i );
184+ rb_funcall (cb , id_call , 1 , INT2NUM (args -> progress ));
185+ }
186+
187+ return NULL ;
188+ }
189+
160190static void
161191ruby_whisper_parakeet_progress_callback (struct parakeet_context * context , struct parakeet_state * state , int progress , void * user_data )
162192{
193+ const ruby_whisper_callback_container * container = (ruby_whisper_callback_container * )user_data ;
194+ if (!ruby_whisper_callback_container_is_present (container )) {
195+ return ;
196+ }
197+
198+ call_parakeet_progress_callbacks_args args = {
199+ container ,
200+ state ,
201+ progress ,
202+ };
203+ rb_thread_call_with_gvl (call_parakeet_progress_callback , (void * )& args );
204+ }
205+
206+ typedef struct {
207+ const ruby_whisper_callback_container * container ;
208+ struct parakeet_state * state ;
209+ bool is_continued ;
210+ } call_parakeet_encoder_begin_callbacks_args ;
211+
212+ static void *
213+ call_parakeet_encoder_begin_callbacks (void * v_args )
214+ {
215+ call_parakeet_encoder_begin_callbacks_args * args = (call_parakeet_encoder_begin_callbacks_args * )v_args ;
216+ const ruby_whisper_callback_container * container = args -> container ;
217+ VALUE result = Qnil ;
218+
219+ if (!NIL_P (container -> callback )) {
220+ result = rb_funcall (container -> callback , id_call , 3 , * container -> context , Qnil , container -> user_data );
221+ if (result == Qfalse ) {
222+ args -> is_continued = false;
223+ return NULL ;
224+ }
225+ }
226+ if (NIL_P (container -> callbacks )) {
227+ return NULL ;
228+ }
229+ const long n_callbacks = RARRAY_LEN (container -> callbacks );
230+ if (n_callbacks == 0 ) {
231+ return NULL ;
232+ }
233+ for (long i = 0 ; i < n_callbacks ; i ++ ) {
234+ VALUE cb = rb_ary_entry (container -> callbacks , i );
235+ result = rb_funcall (cb , id_call , 0 );
236+ if (result == Qfalse ) {
237+ args -> is_continued = false;
238+ return NULL ;
239+ }
240+ }
241+
242+ return NULL ;
163243}
164244
165245static bool
166246ruby_whisper_parakeet_encoder_begin_callback (struct parakeet_context * context , struct parakeet_state * state , void * user_data )
167247{
168- return true;
248+ const ruby_whisper_callback_container * container = (ruby_whisper_callback_container * )user_data ;
249+ if (!ruby_whisper_callback_container_is_present (container )) {
250+ return true;
251+ }
252+
253+ call_parakeet_encoder_begin_callbacks_args args = {
254+ container ,
255+ state ,
256+ true,
257+ };
258+ rb_thread_call_with_gvl (call_parakeet_encoder_begin_callbacks , (void * )& args );
259+
260+ return args .is_continued ;
261+ }
262+
263+ typedef struct {
264+ const ruby_whisper_callback_container * container ;
265+ bool is_interrupted ;
266+ } call_parakeet_abort_callbacks_args ;
267+
268+ static void *
269+ call_parakeet_abort_callbacks (void * v_args )
270+ {
271+ call_parakeet_abort_callbacks_args * args = (call_parakeet_abort_callbacks_args * )v_args ;
272+ const ruby_whisper_callback_container * container = args -> container ;
273+ VALUE result = Qnil ;
274+
275+ if (!NIL_P (container -> callback )) {
276+ result = rb_funcall (container -> callback , id_call , 1 , container -> user_data );
277+ if (RTEST (result )) {
278+ args -> is_interrupted = true;
279+ return NULL ;
280+ }
281+ }
282+ if (NIL_P (container -> callbacks )) {
283+ return NULL ;
284+ }
285+ const long n_callbacks = RARRAY_LEN (container -> callbacks );
286+ if (n_callbacks == 0 ) {
287+ return NULL ;
288+ }
289+ VALUE cb ;
290+ for (long i = 0 ; i < n_callbacks ; i ++ ) {
291+ cb = rb_ary_entry (container -> callbacks , i );
292+ result = rb_funcall (cb , id_call , 0 );
293+ if (RTEST (result )) {
294+ args -> is_interrupted = true;
295+ return NULL ;
296+ }
297+ }
298+
299+ return NULL ;
169300}
170301
171302static bool
@@ -174,8 +305,21 @@ ruby_whisper_parakeet_abort_callback(void *user_data)
174305 ruby_whisper_parakeet_abort_callback_user_data * data = (ruby_whisper_parakeet_abort_callback_user_data * )user_data ;
175306
176307 int is_interrupted = RUBY_ATOMIC_LOAD (data -> is_interrupted );
308+ if (is_interrupted ) {
309+ return true;
310+ }
311+
312+ if (!(data -> callback_container ) || !ruby_whisper_callback_container_is_present (data -> callback_container )) {
313+ return false;
314+ }
177315
178- return is_interrupted == 1 ;
316+ call_parakeet_abort_callbacks_args args = {
317+ data -> callback_container ,
318+ false,
319+ };
320+ rb_thread_call_with_gvl (call_parakeet_abort_callbacks , (void * )& args );
321+
322+ return args .is_interrupted ;
179323}
180324
181325#define CALLBACK_CONTAINER_NAME (name ) name ## _container
@@ -317,6 +461,14 @@ ITERATE_NORMAL_CALLBACK_NAMES(DEF_HOOK, _)
317461static VALUE
318462ruby_whisper_parakeet_params_abort_on (VALUE self )
319463{
464+ ruby_whisper_parakeet_params * rwpp ;
465+ GetParakeetParams (self , rwpp );
466+ const VALUE blk = rb_block_proc ();
467+ if (NIL_P (rwpp -> abort_callback_container -> callbacks )) {
468+ rwpp -> abort_callback_container -> callbacks = rb_ary_new ();
469+ }
470+ rb_ary_push (rwpp -> abort_callback_container -> callbacks , blk );
471+
320472 return Qnil ;
321473}
322474
0 commit comments