From ed355d647ff79855e610d475460b0870f7392c69 Mon Sep 17 00:00:00 2001 From: Roy Shilkrot Date: Fri, 22 Sep 2023 18:06:22 -0400 Subject: [PATCH 1/4] external model file --- src/transcription-filter.cpp | 122 ++++++++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 32 deletions(-) diff --git a/src/transcription-filter.cpp b/src/transcription-filter.cpp index baa76cd..d65e8f4 100644 --- a/src/transcription-filter.cpp +++ b/src/transcription-filter.cpp @@ -216,6 +216,23 @@ void set_text_callback(struct transcription_filter_data *gf, const std::string & } }; +void shutdown_whisper_thread(struct transcription_filter_data *gf) { + if (gf->whisper_context != nullptr) { + // acquire the mutex before freeing the context + if (!gf->whisper_ctx_mutex || !gf->wshiper_thread_cv) { + obs_log(LOG_ERROR, "whisper_ctx_mutex is null"); + return; + } + std::lock_guard lock(*gf->whisper_ctx_mutex); + whisper_free(gf->whisper_context); + gf->whisper_context = nullptr; + gf->wshiper_thread_cv->notify_all(); + } + if (gf->whisper_thread.joinable()) { + gf->whisper_thread.join(); + } +} + void transcription_filter_update(void *data, obs_data_t *s) { struct transcription_filter_data *gf = @@ -296,41 +313,39 @@ void transcription_filter_update(void *data, obs_data_t *s) if (new_model_path != gf->whisper_model_path) { // model path changed, reload the model obs_log(LOG_INFO, "model path changed, reloading model"); - if (gf->whisper_context != nullptr) { - // acquire the mutex before freeing the context - if (!gf->whisper_ctx_mutex || !gf->wshiper_thread_cv) { - obs_log(LOG_ERROR, "whisper_ctx_mutex is null"); - return; - } - std::lock_guard lock(*gf->whisper_ctx_mutex); - whisper_free(gf->whisper_context); - gf->whisper_context = nullptr; - gf->wshiper_thread_cv->notify_all(); - } - if (gf->whisper_thread.joinable()) { - gf->whisper_thread.join(); - } + shutdown_whisper_thread(gf); + gf->whisper_model_path = new_model_path; - // check if the model exists, if not, download it - std::string model_file_found = find_model_file(gf->whisper_model_path); - if (model_file_found == "") { - obs_log(LOG_WARNING, "Whisper model does not exist"); - download_model_with_ui_dialog( - gf->whisper_model_path, - [gf](int download_status, const std::string &path) { - if (download_status == 0) { - obs_log(LOG_INFO, "Model download complete"); - gf->whisper_context = init_whisper_context(path); - std::thread new_whisper_thread(whisper_loop, gf); - gf->whisper_thread.swap(new_whisper_thread); - } else { - obs_log(LOG_ERROR, "Model download failed"); - } - }); + // check if the new model is external file + if (new_model_path.find("!!!external!!!") == std::string::npos) { + // new model is not external file + // check if the model exists, if not, download it + std::string model_file_found = find_model_file(gf->whisper_model_path); + if (model_file_found == "") { + obs_log(LOG_WARNING, "Whisper model does not exist"); + download_model_with_ui_dialog( + gf->whisper_model_path, + [gf](int download_status, const std::string &path) { + if (download_status == 0) { + obs_log(LOG_INFO, "Model download complete"); + gf->whisper_context = init_whisper_context(path); + std::thread new_whisper_thread(whisper_loop, gf); + gf->whisper_thread.swap(new_whisper_thread); + } else { + obs_log(LOG_ERROR, "Model download failed"); + } + }); + } else { + // Model exists, just load it + gf->whisper_context = init_whisper_context(model_file_found); + std::thread new_whisper_thread(whisper_loop, gf); + gf->whisper_thread.swap(new_whisper_thread); + } } else { - // Model exists, just load it - gf->whisper_context = init_whisper_context(model_file_found); + // new model is local file, get file location from file property + std::string external_model_file_path = obs_data_get_string(s, "whisper_model_path_external"); + gf->whisper_context = init_whisper_context(external_model_file_path); std::thread new_whisper_thread(whisper_loop, gf); gf->whisper_thread.swap(new_whisper_thread); } @@ -495,6 +510,9 @@ void transcription_filter_defaults(obs_data_t *s) obs_properties_t *transcription_filter_properties(void *data) { + struct transcription_filter_data *gf = + static_cast(data); + obs_properties_t *ppts = obs_properties_create(); obs_properties_add_bool(ppts, "vad_enabled", "VAD Enabled"); @@ -564,6 +582,46 @@ obs_properties_t *transcription_filter_properties(void *data) obs_property_list_add_string(whisper_models_list, "Small (Eng) 466Mb", "models/ggml-small.en.bin"); obs_property_list_add_string(whisper_models_list, "Small 466Mb", "models/ggml-small.bin"); + obs_property_list_add_string(whisper_models_list, "Load external model file", "!!!external!!!"); + + // Add a file selection input to select an external model file + obs_property_t* whisper_model_path_external = obs_properties_add_path(ppts, "whisper_model_path_external", "External model file", + OBS_PATH_FILE, "Model (*.bin)", NULL); + // Hide the external model file selection input + obs_property_set_visible(obs_properties_get(ppts, "whisper_model_path_external"), false); + + obs_property_set_modified_callback2(whisper_model_path_external, [](void* data, obs_properties_t *props, + obs_property_t *property, + obs_data_t *settings) { + UNUSED_PARAMETER(property); + UNUSED_PARAMETER(props); + struct transcription_filter_data *gf = + static_cast(data); + shutdown_whisper_thread(gf); + std::string external_model_file_path = obs_data_get_string(settings, "whisper_model_path_external"); + gf->whisper_context = init_whisper_context(external_model_file_path); + std::thread new_whisper_thread(whisper_loop, gf); + gf->whisper_thread.swap(new_whisper_thread); + return true; + }, gf); + + // Add a callback to the model list to handle the external model file selection + obs_property_set_modified_callback(whisper_models_list, [](obs_properties_t *props, + obs_property_t *property, + obs_data_t *settings) { + UNUSED_PARAMETER(property); + // If the selected model is the external model, show the external model file selection + // input + const char *new_model_path = obs_data_get_string(settings, "whisper_model_path"); + if (strcmp(new_model_path, "!!!external!!!") == 0) { + obs_property_set_visible( + obs_properties_get(props, "whisper_model_path_external"), true); + } else { + obs_property_set_visible( + obs_properties_get(props, "whisper_model_path_external"), false); + } + return true; + }); obs_properties_t *whisper_params_group = obs_properties_create(); obs_properties_add_group(ppts, "whisper_params_group", "Whisper Parameters", From f67db47f09bc5f37161ff30cebbe462633e27a3f Mon Sep 17 00:00:00 2001 From: Roy Shilkrot Date: Fri, 22 Sep 2023 18:08:11 -0400 Subject: [PATCH 2/4] lint --- src/transcription-filter.cpp | 58 +++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/src/transcription-filter.cpp b/src/transcription-filter.cpp index d65e8f4..9db096e 100644 --- a/src/transcription-filter.cpp +++ b/src/transcription-filter.cpp @@ -216,7 +216,8 @@ void set_text_callback(struct transcription_filter_data *gf, const std::string & } }; -void shutdown_whisper_thread(struct transcription_filter_data *gf) { +void shutdown_whisper_thread(struct transcription_filter_data *gf) +{ if (gf->whisper_context != nullptr) { // acquire the mutex before freeing the context if (!gf->whisper_ctx_mutex || !gf->wshiper_thread_cv) { @@ -328,9 +329,12 @@ void transcription_filter_update(void *data, obs_data_t *s) gf->whisper_model_path, [gf](int download_status, const std::string &path) { if (download_status == 0) { - obs_log(LOG_INFO, "Model download complete"); - gf->whisper_context = init_whisper_context(path); - std::thread new_whisper_thread(whisper_loop, gf); + obs_log(LOG_INFO, + "Model download complete"); + gf->whisper_context = + init_whisper_context(path); + std::thread new_whisper_thread(whisper_loop, + gf); gf->whisper_thread.swap(new_whisper_thread); } else { obs_log(LOG_ERROR, "Model download failed"); @@ -344,7 +348,8 @@ void transcription_filter_update(void *data, obs_data_t *s) } } else { // new model is local file, get file location from file property - std::string external_model_file_path = obs_data_get_string(s, "whisper_model_path_external"); + std::string external_model_file_path = + obs_data_get_string(s, "whisper_model_path_external"); gf->whisper_context = init_whisper_context(external_model_file_path); std::thread new_whisper_thread(whisper_loop, gf); gf->whisper_thread.swap(new_whisper_thread); @@ -582,33 +587,38 @@ obs_properties_t *transcription_filter_properties(void *data) obs_property_list_add_string(whisper_models_list, "Small (Eng) 466Mb", "models/ggml-small.en.bin"); obs_property_list_add_string(whisper_models_list, "Small 466Mb", "models/ggml-small.bin"); - obs_property_list_add_string(whisper_models_list, "Load external model file", "!!!external!!!"); + obs_property_list_add_string(whisper_models_list, "Load external model file", + "!!!external!!!"); // Add a file selection input to select an external model file - obs_property_t* whisper_model_path_external = obs_properties_add_path(ppts, "whisper_model_path_external", "External model file", - OBS_PATH_FILE, "Model (*.bin)", NULL); + obs_property_t *whisper_model_path_external = + obs_properties_add_path(ppts, "whisper_model_path_external", "External model file", + OBS_PATH_FILE, "Model (*.bin)", NULL); // Hide the external model file selection input obs_property_set_visible(obs_properties_get(ppts, "whisper_model_path_external"), false); - obs_property_set_modified_callback2(whisper_model_path_external, [](void* data, obs_properties_t *props, - obs_property_t *property, - obs_data_t *settings) { - UNUSED_PARAMETER(property); - UNUSED_PARAMETER(props); - struct transcription_filter_data *gf = - static_cast(data); - shutdown_whisper_thread(gf); - std::string external_model_file_path = obs_data_get_string(settings, "whisper_model_path_external"); - gf->whisper_context = init_whisper_context(external_model_file_path); - std::thread new_whisper_thread(whisper_loop, gf); - gf->whisper_thread.swap(new_whisper_thread); - return true; - }, gf); + obs_property_set_modified_callback2( + whisper_model_path_external, + [](void *data, obs_properties_t *props, obs_property_t *property, + obs_data_t *settings) { + UNUSED_PARAMETER(property); + UNUSED_PARAMETER(props); + struct transcription_filter_data *gf = + static_cast(data); + shutdown_whisper_thread(gf); + std::string external_model_file_path = + obs_data_get_string(settings, "whisper_model_path_external"); + gf->whisper_context = init_whisper_context(external_model_file_path); + std::thread new_whisper_thread(whisper_loop, gf); + gf->whisper_thread.swap(new_whisper_thread); + return true; + }, + gf); // Add a callback to the model list to handle the external model file selection obs_property_set_modified_callback(whisper_models_list, [](obs_properties_t *props, - obs_property_t *property, - obs_data_t *settings) { + obs_property_t *property, + obs_data_t *settings) { UNUSED_PARAMETER(property); // If the selected model is the external model, show the external model file selection // input From d4df2e8ee1b7a3cd2d60af5f7e58d8e6193afd03 Mon Sep 17 00:00:00 2001 From: Roy Shilkrot Date: Sat, 23 Sep 2023 08:19:30 -0400 Subject: [PATCH 3/4] fix shadhowed param --- src/transcription-filter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/transcription-filter.cpp b/src/transcription-filter.cpp index 9db096e..8c6bf7c 100644 --- a/src/transcription-filter.cpp +++ b/src/transcription-filter.cpp @@ -603,14 +603,14 @@ obs_properties_t *transcription_filter_properties(void *data) obs_data_t *settings) { UNUSED_PARAMETER(property); UNUSED_PARAMETER(props); - struct transcription_filter_data *gf = + struct transcription_filter_data *gf_ = static_cast(data); - shutdown_whisper_thread(gf); + shutdown_whisper_thread(gf_); std::string external_model_file_path = obs_data_get_string(settings, "whisper_model_path_external"); - gf->whisper_context = init_whisper_context(external_model_file_path); - std::thread new_whisper_thread(whisper_loop, gf); - gf->whisper_thread.swap(new_whisper_thread); + gf_->whisper_context = init_whisper_context(external_model_file_path); + std::thread new_whisper_thread(whisper_loop, gf_); + gf_->whisper_thread.swap(new_whisper_thread); return true; }, gf); From 9d5723c60d0f86cd66e5e80b578f6e07153c2273 Mon Sep 17 00:00:00 2001 From: Roy Shilkrot Date: Sat, 23 Sep 2023 08:23:37 -0400 Subject: [PATCH 4/4] more shadowed param --- src/transcription-filter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transcription-filter.cpp b/src/transcription-filter.cpp index 8c6bf7c..e9256d1 100644 --- a/src/transcription-filter.cpp +++ b/src/transcription-filter.cpp @@ -599,12 +599,12 @@ obs_properties_t *transcription_filter_properties(void *data) obs_property_set_modified_callback2( whisper_model_path_external, - [](void *data, obs_properties_t *props, obs_property_t *property, + [](void *data_, obs_properties_t *props, obs_property_t *property, obs_data_t *settings) { UNUSED_PARAMETER(property); UNUSED_PARAMETER(props); struct transcription_filter_data *gf_ = - static_cast(data); + static_cast(data_); shutdown_whisper_thread(gf_); std::string external_model_file_path = obs_data_get_string(settings, "whisper_model_path_external");