Skip to content

Commit cc97997

Browse files
committed
Implement hooks for Parakeet
1 parent b69bf9d commit cc97997

2 files changed

Lines changed: 157 additions & 5 deletions

File tree

bindings/ruby/ext/ruby_whisper_parakeet_params.c

Lines changed: 155 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extern void ruby_whisper_callback_container_mark(ruby_whisper_callback_container
4747
extern ruby_whisper_callback_container* ruby_whisper_callback_container_allocate(void);
4848
extern bool ruby_whisper_callback_container_is_present(const ruby_whisper_callback_container *container);
4949
extern 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

5252
static ID param_names[RUBY_WHISPER_PARAKEET_NUM_PARAMS];
5353
typedef 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+
160190
static void
161191
ruby_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

165245
static bool
166246
ruby_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

171302
static 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, _)
317461
static VALUE
318462
ruby_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

bindings/ruby/ext/ruby_whisper_segment.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ extern const rb_data_type_t ruby_whisper_type;
1515

1616
extern VALUE cSegment;
1717

18-
extern VALUE ruby_whisper_token_s_from_index(struct whisper_context *context, int i_segment, int index);
18+
extern VALUE ruby_whisper_token_s_init(struct whisper_context *context, int i_segment, int index);
1919

2020
static void
2121
rb_whisper_segment_mark(void *p)
@@ -190,7 +190,7 @@ ruby_whisper_segment_each_token(VALUE self)
190190

191191
const int n_tokens = whisper_full_n_tokens(rw->context, rws->index);
192192
for (int i = 0; i < n_tokens; ++i) {
193-
rb_yield(ruby_whisper_token_s_from_index(rw->context, rws->index, i));
193+
rb_yield(ruby_whisper_token_s_init(rw->context, rws->index, i));
194194
}
195195

196196
return self;

0 commit comments

Comments
 (0)