@@ -53,6 +53,9 @@ static ID id_pre_converted_models;
53
53
54
54
static bool is_log_callback_finalized = false ;
55
55
56
+ // High level API
57
+ static VALUE rb_whisper_segment_initialize (VALUE context, int index);
58
+
56
59
/*
57
60
* call-seq:
58
61
* lang_max_id -> Integer
@@ -187,6 +190,69 @@ static ruby_whisper_callback_container * rb_whisper_callback_container_allocate(
187
190
return container;
188
191
}
189
192
193
+ static void new_segment_callback (struct whisper_context *ctx, struct whisper_state *state, int n_new, void *user_data) {
194
+ const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
195
+
196
+ // Currently, doesn't support state because
197
+ // those require to resolve GC-related problems.
198
+ if (!NIL_P (container->callback )) {
199
+ rb_funcall (container->callback , id_call, 4 , *container->context , Qnil, INT2NUM (n_new), container->user_data );
200
+ }
201
+ const long callbacks_len = RARRAY_LEN (container->callbacks );
202
+ if (0 == callbacks_len) {
203
+ return ;
204
+ }
205
+ const int n_segments = whisper_full_n_segments_from_state (state);
206
+ for (int i = n_new; i > 0 ; i--) {
207
+ int i_segment = n_segments - i;
208
+ VALUE segment = rb_whisper_segment_initialize (*container->context , i_segment);
209
+ for (int j = 0 ; j < callbacks_len; j++) {
210
+ VALUE cb = rb_ary_entry (container->callbacks , j);
211
+ rb_funcall (cb, id_call, 1 , segment);
212
+ }
213
+ }
214
+ }
215
+
216
+ static void progress_callback (struct whisper_context *ctx, struct whisper_state *state, int progress_cur, void *user_data) {
217
+ const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
218
+ const VALUE progress = INT2NUM (progress_cur);
219
+ // Currently, doesn't support state because
220
+ // those require to resolve GC-related problems.
221
+ if (!NIL_P (container->callback )) {
222
+ rb_funcall (container->callback , id_call, 4 , *container->context , Qnil, progress, container->user_data );
223
+ }
224
+ const long callbacks_len = RARRAY_LEN (container->callbacks );
225
+ if (0 == callbacks_len) {
226
+ return ;
227
+ }
228
+ for (int j = 0 ; j < callbacks_len; j++) {
229
+ VALUE cb = rb_ary_entry (container->callbacks , j);
230
+ rb_funcall (cb, id_call, 1 , progress);
231
+ }
232
+ }
233
+
234
+ static bool abort_callback (void * user_data) {
235
+ const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
236
+ if (!NIL_P (container->callback )) {
237
+ VALUE result = rb_funcall (container->callback , id_call, 1 , container->user_data );
238
+ if (!NIL_P (result) && Qfalse != result) {
239
+ return true ;
240
+ }
241
+ }
242
+ const long callbacks_len = RARRAY_LEN (container->callbacks );
243
+ if (0 == callbacks_len) {
244
+ return false ;
245
+ }
246
+ for (int j = 0 ; j < callbacks_len; j++) {
247
+ VALUE cb = rb_ary_entry (container->callbacks , j);
248
+ VALUE result = rb_funcall (cb, id_call, 1 , container->user_data );
249
+ if (!NIL_P (result) && Qfalse != result) {
250
+ return true ;
251
+ }
252
+ }
253
+ return false ;
254
+ }
255
+
190
256
static VALUE ruby_whisper_params_allocate (VALUE klass) {
191
257
ruby_whisper_params *rwp;
192
258
rwp = ALLOC (ruby_whisper_params);
@@ -230,8 +296,25 @@ static VALUE ruby_whisper_initialize(int argc, VALUE *argv, VALUE self) {
230
296
return self;
231
297
}
232
298
233
- // High level API
234
- static VALUE rb_whisper_segment_initialize (VALUE context, int index);
299
+ static void register_callbacks (ruby_whisper_params * rwp, VALUE * self) {
300
+ if (!NIL_P (rwp->new_segment_callback_container ->callback ) || 0 != RARRAY_LEN (rwp->new_segment_callback_container ->callbacks )) {
301
+ rwp->new_segment_callback_container ->context = self;
302
+ rwp->params .new_segment_callback = new_segment_callback;
303
+ rwp->params .new_segment_callback_user_data = rwp->new_segment_callback_container ;
304
+ }
305
+
306
+ if (!NIL_P (rwp->progress_callback_container ->callback ) || 0 != RARRAY_LEN (rwp->progress_callback_container ->callbacks )) {
307
+ rwp->progress_callback_container ->context = self;
308
+ rwp->params .progress_callback = progress_callback;
309
+ rwp->params .progress_callback_user_data = rwp->progress_callback_container ;
310
+ }
311
+
312
+ if (!NIL_P (rwp->abort_callback_container ->callback ) || 0 != RARRAY_LEN (rwp->abort_callback_container ->callbacks )) {
313
+ rwp->abort_callback_container ->context = self;
314
+ rwp->params .abort_callback = abort_callback;
315
+ rwp->params .abort_callback_user_data = rwp->abort_callback_container ;
316
+ }
317
+ }
235
318
236
319
/*
237
320
* transcribe a single file
@@ -353,80 +436,7 @@ static VALUE ruby_whisper_transcribe(int argc, VALUE *argv, VALUE self) {
353
436
rwp->params .encoder_begin_callback_user_data = &is_aborted;
354
437
}
355
438
356
- if (!NIL_P (rwp->new_segment_callback_container ->callback ) || 0 != RARRAY_LEN (rwp->new_segment_callback_container ->callbacks )) {
357
- rwp->params .new_segment_callback = [](struct whisper_context * ctx, struct whisper_state * state, int n_new, void * user_data) {
358
- const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
359
-
360
- // Currently, doesn't support state because
361
- // those require to resolve GC-related problems.
362
- if (!NIL_P (container->callback )) {
363
- rb_funcall (container->callback , id_call, 4 , *container->context , Qnil, INT2NUM (n_new), container->user_data );
364
- }
365
- const long callbacks_len = RARRAY_LEN (container->callbacks );
366
- if (0 == callbacks_len) {
367
- return ;
368
- }
369
- const int n_segments = whisper_full_n_segments_from_state (state);
370
- for (int i = n_new; i > 0 ; i--) {
371
- int i_segment = n_segments - i;
372
- VALUE segment = rb_whisper_segment_initialize (*container->context , i_segment);
373
- for (int j = 0 ; j < callbacks_len; j++) {
374
- VALUE cb = rb_ary_entry (container->callbacks , j);
375
- rb_funcall (cb, id_call, 1 , segment);
376
- }
377
- }
378
- };
379
- rwp->new_segment_callback_container ->context = &self;
380
- rwp->params .new_segment_callback_user_data = rwp->new_segment_callback_container ;
381
- }
382
-
383
- if (!NIL_P (rwp->progress_callback_container ->callback ) || 0 != RARRAY_LEN (rwp->progress_callback_container ->callbacks )) {
384
- rwp->params .progress_callback = [](struct whisper_context *ctx, struct whisper_state * /* state*/ , int progress_cur, void *user_data) {
385
- const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
386
- const VALUE progress = INT2NUM (progress_cur);
387
- // Currently, doesn't support state because
388
- // those require to resolve GC-related problems.
389
- if (!NIL_P (container->callback )) {
390
- rb_funcall (container->callback , id_call, 4 , *container->context , Qnil, progress, container->user_data );
391
- }
392
- const long callbacks_len = RARRAY_LEN (container->callbacks );
393
- if (0 == callbacks_len) {
394
- return ;
395
- }
396
- for (int j = 0 ; j < callbacks_len; j++) {
397
- VALUE cb = rb_ary_entry (container->callbacks , j);
398
- rb_funcall (cb, id_call, 1 , progress);
399
- }
400
- };
401
- rwp->progress_callback_container ->context = &self;
402
- rwp->params .progress_callback_user_data = rwp->progress_callback_container ;
403
- }
404
-
405
- if (!NIL_P (rwp->abort_callback_container ->callback ) || 0 != RARRAY_LEN (rwp->abort_callback_container ->callbacks )) {
406
- rwp->params .abort_callback = [](void * user_data) {
407
- const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
408
- if (!NIL_P (container->callback )) {
409
- VALUE result = rb_funcall (container->callback , id_call, 1 , container->user_data );
410
- if (!NIL_P (result) && Qfalse != result) {
411
- return true ;
412
- }
413
- }
414
- const long callbacks_len = RARRAY_LEN (container->callbacks );
415
- if (0 == callbacks_len) {
416
- return false ;
417
- }
418
- for (int j = 0 ; j < callbacks_len; j++) {
419
- VALUE cb = rb_ary_entry (container->callbacks , j);
420
- VALUE result = rb_funcall (cb, id_call, 1 , container->user_data );
421
- if (!NIL_P (result) && Qfalse != result) {
422
- return true ;
423
- }
424
- }
425
- return false ;
426
- };
427
- rwp->abort_callback_container ->context = &self;
428
- rwp->params .abort_callback_user_data = rwp->abort_callback_container ;
429
- }
439
+ register_callbacks (rwp, &self);
430
440
431
441
if (whisper_full_parallel (rw->context , rwp->params , pcmf32.data (), pcmf32.size (), 1 ) != 0 ) {
432
442
fprintf (stderr, " failed to process audio\n " );
@@ -631,6 +641,7 @@ VALUE ruby_whisper_full(int argc, VALUE *argv, VALUE self) {
631
641
}
632
642
}
633
643
}
644
+ register_callbacks (rwp, &self);
634
645
const int result = whisper_full (rw->context , rwp->params , c_samples, n_samples);
635
646
if (0 == result) {
636
647
return Qnil;
@@ -719,6 +730,7 @@ static VALUE ruby_whisper_full_parallel(int argc, VALUE *argv,VALUE self) {
719
730
}
720
731
}
721
732
}
733
+ register_callbacks (rwp, &self);
722
734
const int result = whisper_full_parallel (rw->context , rwp->params , c_samples, n_samples, n_processors);
723
735
if (0 == result) {
724
736
return Qnil;
@@ -823,6 +835,18 @@ static VALUE ruby_whisper_full_get_segment_text(VALUE self, VALUE i_segment) {
823
835
return rb_str_new2 (text);
824
836
}
825
837
838
+ /*
839
+ * call-seq:
840
+ * full_get_segment_no_speech_prob -> Float
841
+ */
842
+ static VALUE ruby_whisper_full_get_segment_no_speech_prob (VALUE self, VALUE i_segment) {
843
+ ruby_whisper *rw;
844
+ Data_Get_Struct (self, ruby_whisper, rw);
845
+ const int c_i_segment = ruby_whisper_full_check_segment_index (rw, i_segment);
846
+ const float no_speech_prob = whisper_full_get_segment_no_speech_prob (rw->context , c_i_segment);
847
+ return DBL2NUM (no_speech_prob);
848
+ }
849
+
826
850
/*
827
851
* params.language = "auto" | "en", etc...
828
852
*
@@ -1547,6 +1571,18 @@ static VALUE ruby_whisper_segment_get_text(VALUE self) {
1547
1571
return rb_str_new2 (text);
1548
1572
}
1549
1573
1574
+ /*
1575
+ * call-seq:
1576
+ * no_speech_prob -> Float
1577
+ */
1578
+ static VALUE ruby_whisper_segment_get_no_speech_prob (VALUE self) {
1579
+ ruby_whisper_segment *rws;
1580
+ Data_Get_Struct (self, ruby_whisper_segment, rws);
1581
+ ruby_whisper *rw;
1582
+ Data_Get_Struct (rws->context , ruby_whisper, rw);
1583
+ return DBL2NUM (whisper_full_get_segment_no_speech_prob (rw->context , rws->index ));
1584
+ }
1585
+
1550
1586
static void rb_whisper_model_mark (ruby_whisper_model *rwm) {
1551
1587
rb_gc_mark (rwm->context );
1552
1588
}
@@ -1809,6 +1845,7 @@ void Init_whisper() {
1809
1845
rb_define_method (cContext, " full_get_segment_t1" , ruby_whisper_full_get_segment_t1, 1 );
1810
1846
rb_define_method (cContext, " full_get_segment_speaker_turn_next" , ruby_whisper_full_get_segment_speaker_turn_next, 1 );
1811
1847
rb_define_method (cContext, " full_get_segment_text" , ruby_whisper_full_get_segment_text, 1 );
1848
+ rb_define_method (cContext, " full_get_segment_no_speech_prob" , ruby_whisper_full_get_segment_no_speech_prob, 1 );
1812
1849
rb_define_method (cContext, " full" , ruby_whisper_full, -1 );
1813
1850
rb_define_method (cContext, " full_parallel" , ruby_whisper_full_parallel, -1 );
1814
1851
@@ -1887,6 +1924,7 @@ void Init_whisper() {
1887
1924
rb_define_method (cSegment, " end_time" , ruby_whisper_segment_get_end_time, 0 );
1888
1925
rb_define_method (cSegment, " speaker_next_turn?" , ruby_whisper_segment_get_speaker_turn_next, 0 );
1889
1926
rb_define_method (cSegment, " text" , ruby_whisper_segment_get_text, 0 );
1927
+ rb_define_method (cSegment, " no_speech_prob" , ruby_whisper_segment_get_no_speech_prob, 0 );
1890
1928
1891
1929
cModel = rb_define_class_under (mWhisper , " Model" , rb_cObject);
1892
1930
rb_define_alloc_func (cModel, ruby_whisper_model_allocate);
0 commit comments