static bool is_log_callback_finalized = false;
+// High level API
+static VALUE rb_whisper_segment_initialize(VALUE context, int index);
+
/*
* call-seq:
* lang_max_id -> Integer
return container;
}
+static void new_segment_callback(struct whisper_context *ctx, struct whisper_state *state, int n_new, void *user_data) {
+ const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
+
+ // Currently, doesn't support state because
+ // those require to resolve GC-related problems.
+ if (!NIL_P(container->callback)) {
+ rb_funcall(container->callback, id_call, 4, *container->context, Qnil, INT2NUM(n_new), container->user_data);
+ }
+ const long callbacks_len = RARRAY_LEN(container->callbacks);
+ if (0 == callbacks_len) {
+ return;
+ }
+ const int n_segments = whisper_full_n_segments_from_state(state);
+ for (int i = n_new; i > 0; i--) {
+ int i_segment = n_segments - i;
+ VALUE segment = rb_whisper_segment_initialize(*container->context, i_segment);
+ for (int j = 0; j < callbacks_len; j++) {
+ VALUE cb = rb_ary_entry(container->callbacks, j);
+ rb_funcall(cb, id_call, 1, segment);
+ }
+ }
+}
+
+static void progress_callback(struct whisper_context *ctx, struct whisper_state *state, int progress_cur, void *user_data) {
+ const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
+ const VALUE progress = INT2NUM(progress_cur);
+ // Currently, doesn't support state because
+ // those require to resolve GC-related problems.
+ if (!NIL_P(container->callback)) {
+ rb_funcall(container->callback, id_call, 4, *container->context, Qnil, progress, container->user_data);
+ }
+ const long callbacks_len = RARRAY_LEN(container->callbacks);
+ if (0 == callbacks_len) {
+ return;
+ }
+ for (int j = 0; j < callbacks_len; j++) {
+ VALUE cb = rb_ary_entry(container->callbacks, j);
+ rb_funcall(cb, id_call, 1, progress);
+ }
+}
+
+static bool abort_callback(void * user_data) {
+ const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
+ if (!NIL_P(container->callback)) {
+ VALUE result = rb_funcall(container->callback, id_call, 1, container->user_data);
+ if (!NIL_P(result) && Qfalse != result) {
+ return true;
+ }
+ }
+ const long callbacks_len = RARRAY_LEN(container->callbacks);
+ if (0 == callbacks_len) {
+ return false;
+ }
+ for (int j = 0; j < callbacks_len; j++) {
+ VALUE cb = rb_ary_entry(container->callbacks, j);
+ VALUE result = rb_funcall(cb, id_call, 1, container->user_data);
+ if (!NIL_P(result) && Qfalse != result) {
+ return true;
+ }
+ }
+ return false;
+}
+
static VALUE ruby_whisper_params_allocate(VALUE klass) {
ruby_whisper_params *rwp;
rwp = ALLOC(ruby_whisper_params);
return self;
}
-// High level API
-static VALUE rb_whisper_segment_initialize(VALUE context, int index);
+static void register_callbacks(ruby_whisper_params * rwp, VALUE * self) {
+ if (!NIL_P(rwp->new_segment_callback_container->callback) || 0 != RARRAY_LEN(rwp->new_segment_callback_container->callbacks)) {
+ rwp->new_segment_callback_container->context = self;
+ rwp->params.new_segment_callback = new_segment_callback;
+ rwp->params.new_segment_callback_user_data = rwp->new_segment_callback_container;
+ }
+
+ if (!NIL_P(rwp->progress_callback_container->callback) || 0 != RARRAY_LEN(rwp->progress_callback_container->callbacks)) {
+ rwp->progress_callback_container->context = self;
+ rwp->params.progress_callback = progress_callback;
+ rwp->params.progress_callback_user_data = rwp->progress_callback_container;
+ }
+
+ if (!NIL_P(rwp->abort_callback_container->callback) || 0 != RARRAY_LEN(rwp->abort_callback_container->callbacks)) {
+ rwp->abort_callback_container->context = self;
+ rwp->params.abort_callback = abort_callback;
+ rwp->params.abort_callback_user_data = rwp->abort_callback_container;
+ }
+}
/*
* transcribe a single file
rwp->params.encoder_begin_callback_user_data = &is_aborted;
}
- if (!NIL_P(rwp->new_segment_callback_container->callback) || 0 != RARRAY_LEN(rwp->new_segment_callback_container->callbacks)) {
- rwp->params.new_segment_callback = [](struct whisper_context * ctx, struct whisper_state * state, int n_new, void * user_data) {
- const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
-
- // Currently, doesn't support state because
- // those require to resolve GC-related problems.
- if (!NIL_P(container->callback)) {
- rb_funcall(container->callback, id_call, 4, *container->context, Qnil, INT2NUM(n_new), container->user_data);
- }
- const long callbacks_len = RARRAY_LEN(container->callbacks);
- if (0 == callbacks_len) {
- return;
- }
- const int n_segments = whisper_full_n_segments_from_state(state);
- for (int i = n_new; i > 0; i--) {
- int i_segment = n_segments - i;
- VALUE segment = rb_whisper_segment_initialize(*container->context, i_segment);
- for (int j = 0; j < callbacks_len; j++) {
- VALUE cb = rb_ary_entry(container->callbacks, j);
- rb_funcall(cb, id_call, 1, segment);
- }
- }
- };
- rwp->new_segment_callback_container->context = &self;
- rwp->params.new_segment_callback_user_data = rwp->new_segment_callback_container;
- }
-
- if (!NIL_P(rwp->progress_callback_container->callback) || 0 != RARRAY_LEN(rwp->progress_callback_container->callbacks)) {
- rwp->params.progress_callback = [](struct whisper_context *ctx, struct whisper_state * /*state*/, int progress_cur, void *user_data) {
- const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
- const VALUE progress = INT2NUM(progress_cur);
- // Currently, doesn't support state because
- // those require to resolve GC-related problems.
- if (!NIL_P(container->callback)) {
- rb_funcall(container->callback, id_call, 4, *container->context, Qnil, progress, container->user_data);
- }
- const long callbacks_len = RARRAY_LEN(container->callbacks);
- if (0 == callbacks_len) {
- return;
- }
- for (int j = 0; j < callbacks_len; j++) {
- VALUE cb = rb_ary_entry(container->callbacks, j);
- rb_funcall(cb, id_call, 1, progress);
- }
- };
- rwp->progress_callback_container->context = &self;
- rwp->params.progress_callback_user_data = rwp->progress_callback_container;
- }
-
- if (!NIL_P(rwp->abort_callback_container->callback) || 0 != RARRAY_LEN(rwp->abort_callback_container->callbacks)) {
- rwp->params.abort_callback = [](void * user_data) {
- const ruby_whisper_callback_container *container = (ruby_whisper_callback_container *)user_data;
- if (!NIL_P(container->callback)) {
- VALUE result = rb_funcall(container->callback, id_call, 1, container->user_data);
- if (!NIL_P(result) && Qfalse != result) {
- return true;
- }
- }
- const long callbacks_len = RARRAY_LEN(container->callbacks);
- if (0 == callbacks_len) {
- return false;
- }
- for (int j = 0; j < callbacks_len; j++) {
- VALUE cb = rb_ary_entry(container->callbacks, j);
- VALUE result = rb_funcall(cb, id_call, 1, container->user_data);
- if (!NIL_P(result) && Qfalse != result) {
- return true;
- }
- }
- return false;
- };
- rwp->abort_callback_container->context = &self;
- rwp->params.abort_callback_user_data = rwp->abort_callback_container;
- }
+ register_callbacks(rwp, &self);
if (whisper_full_parallel(rw->context, rwp->params, pcmf32.data(), pcmf32.size(), 1) != 0) {
fprintf(stderr, "failed to process audio\n");
}
}
}
+ register_callbacks(rwp, &self);
const int result = whisper_full(rw->context, rwp->params, c_samples, n_samples);
if (0 == result) {
return Qnil;
}
}
}
+ register_callbacks(rwp, &self);
const int result = whisper_full_parallel(rw->context, rwp->params, c_samples, n_samples, n_processors);
if (0 == result) {
return Qnil;
return rb_str_new2(text);
}
+/*
+ * call-seq:
+ * full_get_segment_no_speech_prob -> Float
+ */
+static VALUE ruby_whisper_full_get_segment_no_speech_prob(VALUE self, VALUE i_segment) {
+ ruby_whisper *rw;
+ Data_Get_Struct(self, ruby_whisper, rw);
+ const int c_i_segment = ruby_whisper_full_check_segment_index(rw, i_segment);
+ const float no_speech_prob = whisper_full_get_segment_no_speech_prob(rw->context, c_i_segment);
+ return DBL2NUM(no_speech_prob);
+}
+
/*
* params.language = "auto" | "en", etc...
*
return rb_str_new2(text);
}
+/*
+ * call-seq:
+ * no_speech_prob -> Float
+ */
+static VALUE ruby_whisper_segment_get_no_speech_prob(VALUE self) {
+ ruby_whisper_segment *rws;
+ Data_Get_Struct(self, ruby_whisper_segment, rws);
+ ruby_whisper *rw;
+ Data_Get_Struct(rws->context, ruby_whisper, rw);
+ return DBL2NUM(whisper_full_get_segment_no_speech_prob(rw->context, rws->index));
+}
+
static void rb_whisper_model_mark(ruby_whisper_model *rwm) {
rb_gc_mark(rwm->context);
}
rb_define_method(cContext, "full_get_segment_t1", ruby_whisper_full_get_segment_t1, 1);
rb_define_method(cContext, "full_get_segment_speaker_turn_next", ruby_whisper_full_get_segment_speaker_turn_next, 1);
rb_define_method(cContext, "full_get_segment_text", ruby_whisper_full_get_segment_text, 1);
+ rb_define_method(cContext, "full_get_segment_no_speech_prob", ruby_whisper_full_get_segment_no_speech_prob, 1);
rb_define_method(cContext, "full", ruby_whisper_full, -1);
rb_define_method(cContext, "full_parallel", ruby_whisper_full_parallel, -1);
rb_define_method(cSegment, "end_time", ruby_whisper_segment_get_end_time, 0);
rb_define_method(cSegment, "speaker_next_turn?", ruby_whisper_segment_get_speaker_turn_next, 0);
rb_define_method(cSegment, "text", ruby_whisper_segment_get_text, 0);
+ rb_define_method(cSegment, "no_speech_prob", ruby_whisper_segment_get_no_speech_prob, 0);
cModel = rb_define_class_under(mWhisper, "Model", rb_cObject);
rb_define_alloc_func(cModel, ruby_whisper_model_allocate);