mirror of
https://github.com/occ-ai/obs-localvocal
synced 2024-11-07 18:57:14 +00:00
Merge remote-tracking branch 'origin/master' into roy.step_by_step_realtime_processing
This commit is contained in:
commit
44811674b7
4
.github/scripts/Build-Windows.ps1
vendored
4
.github/scripts/Build-Windows.ps1
vendored
@ -7,7 +7,7 @@ param(
|
|||||||
[switch] $SkipAll,
|
[switch] $SkipAll,
|
||||||
[switch] $SkipBuild,
|
[switch] $SkipBuild,
|
||||||
[switch] $SkipDeps,
|
[switch] $SkipDeps,
|
||||||
[string] $ExtraCmakeArgs
|
[string[]] $ExtraCmakeArgs
|
||||||
)
|
)
|
||||||
|
|
||||||
$ErrorActionPreference = 'Stop'
|
$ErrorActionPreference = 'Stop'
|
||||||
@ -58,7 +58,7 @@ function Build {
|
|||||||
Ensure-Location $ProjectRoot
|
Ensure-Location $ProjectRoot
|
||||||
|
|
||||||
# take cmake args from $ExtraCmakeArgs
|
# take cmake args from $ExtraCmakeArgs
|
||||||
$CmakeArgs = @($ExtraCmakeArgs)
|
$CmakeArgs = $ExtraCmakeArgs
|
||||||
$CmakeBuildArgs = @()
|
$CmakeBuildArgs = @()
|
||||||
$CmakeInstallArgs = @()
|
$CmakeInstallArgs = @()
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ After installing the CUDA toolkit, you need to set variables to point CMake to t
|
|||||||
|
|
||||||
For example
|
For example
|
||||||
```powershell
|
```powershell
|
||||||
> .github/scripts/Build-Windows.ps1 -Target x64 -ExtraCmakeFlags "-D LOCALVOCAL_WITH_CUDA=ON -D CUDA_TOOLKIT_ROOT_DIR='C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4'"
|
.github/scripts/Build-Windows.ps1 -Target x64 -ExtraCmakeArgs '-D','LOCALVOCAL_WITH_CUDA=ON','-D',"CUDA_TOOLKIT_ROOT_DIR='C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.2'"
|
||||||
```
|
```
|
||||||
|
|
||||||
You will need to copy a few CUDA .dll files to the location of the plugin .dll for it to run. The required .dll files from CUDA (which are located in the `bin` folder of the CUDA toolkit installation directory) are:
|
You will need to copy a few CUDA .dll files to the location of the plugin .dll for it to run. The required .dll files from CUDA (which are located in the `bin` folder of the CUDA toolkit installation directory) are:
|
||||||
@ -104,4 +104,4 @@ You will need to copy a few CUDA .dll files to the location of the plugin .dll f
|
|||||||
- `cublas64_NN.dll`
|
- `cublas64_NN.dll`
|
||||||
- `cublasLt64_NN.dll`
|
- `cublasLt64_NN.dll`
|
||||||
|
|
||||||
where `NN` is the CUDA version number. For example, if you have installed CUDA 11.4 then `NN` is likely `11`.
|
where `NN` is the CUDA major version number. For example, if you have installed CUDA 12.2 as in example above, then `NN` is `12`.
|
||||||
|
3
src/model-utils/model-downloader-types.h
Normal file
3
src/model-utils/model-downloader-types.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
typedef std::function<void(int download_status, const std::string &path)>
|
||||||
|
download_finished_callback_t;
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <obs-module.h>
|
#include <obs-module.h>
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
const std::string MODEL_BASE_PATH = "https://huggingface.co/ggerganov/whisper.cpp";
|
const std::string MODEL_BASE_PATH = "https://huggingface.co/ggerganov/whisper.cpp";
|
||||||
const std::string MODEL_PREFIX = "resolve/main/";
|
const std::string MODEL_PREFIX = "resolve/main/";
|
||||||
|
|
||||||
@ -12,14 +14,17 @@ size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
|||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelDownloader::ModelDownloader(
|
ModelDownloader::ModelDownloader(const std::string &model_name,
|
||||||
const std::string &model_name,
|
download_finished_callback_t download_finished_callback_,
|
||||||
std::function<void(int download_status)> download_finished_callback_, QWidget *parent)
|
QWidget *parent)
|
||||||
: QDialog(parent), download_finished_callback(download_finished_callback_)
|
: QDialog(parent), download_finished_callback(download_finished_callback_)
|
||||||
{
|
{
|
||||||
this->setWindowTitle("Downloading model...");
|
this->setWindowTitle("LocalVocal: Downloading model...");
|
||||||
this->setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
|
this->setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
|
||||||
this->setFixedSize(300, 100);
|
this->setFixedSize(300, 100);
|
||||||
|
// Bring the dialog to the front
|
||||||
|
this->activateWindow();
|
||||||
|
this->raise();
|
||||||
|
|
||||||
this->layout = new QVBoxLayout(this);
|
this->layout = new QVBoxLayout(this);
|
||||||
|
|
||||||
@ -59,24 +64,32 @@ ModelDownloader::ModelDownloader(
|
|||||||
this->download_thread->start();
|
this->download_thread->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelDownloader::closeEvent(QCloseEvent *e)
|
||||||
|
{
|
||||||
|
if (!this->mPrepareToClose)
|
||||||
|
e->ignore();
|
||||||
|
else
|
||||||
|
QDialog::closeEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelDownloader::close()
|
||||||
|
{
|
||||||
|
this->mPrepareToClose = true;
|
||||||
|
|
||||||
|
QDialog::close();
|
||||||
|
}
|
||||||
|
|
||||||
void ModelDownloader::update_progress(int progress)
|
void ModelDownloader::update_progress(int progress)
|
||||||
{
|
{
|
||||||
this->progress_bar->setValue(progress);
|
this->progress_bar->setValue(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelDownloader::download_finished()
|
void ModelDownloader::download_finished(const std::string &path)
|
||||||
{
|
{
|
||||||
this->setWindowTitle("Download finished!");
|
// Call the callback with the path to the downloaded model
|
||||||
this->progress_bar->setValue(100);
|
this->download_finished_callback(0, path);
|
||||||
this->progress_bar->setFormat("Download finished!");
|
// Close the dialog
|
||||||
this->progress_bar->setAlignment(Qt::AlignCenter);
|
this->close();
|
||||||
this->progress_bar->setStyleSheet("QProgressBar::chunk { background-color: #05B8CC; }");
|
|
||||||
// Add a button to close the dialog
|
|
||||||
QPushButton *close_button = new QPushButton("Close", this);
|
|
||||||
this->layout->addWidget(close_button);
|
|
||||||
connect(close_button, &QPushButton::clicked, this, &ModelDownloader::close);
|
|
||||||
// Call the callback
|
|
||||||
this->download_finished_callback(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelDownloader::show_error(const std::string &reason)
|
void ModelDownloader::show_error(const std::string &reason)
|
||||||
@ -96,7 +109,7 @@ void ModelDownloader::show_error(const std::string &reason)
|
|||||||
QPushButton *close_button = new QPushButton("Close", this);
|
QPushButton *close_button = new QPushButton("Close", this);
|
||||||
this->layout->addWidget(close_button);
|
this->layout->addWidget(close_button);
|
||||||
connect(close_button, &QPushButton::clicked, this, &ModelDownloader::close);
|
connect(close_button, &QPushButton::clicked, this, &ModelDownloader::close);
|
||||||
this->download_finished_callback(1);
|
this->download_finished_callback(1, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelDownloadWorker::ModelDownloadWorker(const std::string &model_name_)
|
ModelDownloadWorker::ModelDownloadWorker(const std::string &model_name_)
|
||||||
@ -106,9 +119,23 @@ ModelDownloadWorker::ModelDownloadWorker(const std::string &model_name_)
|
|||||||
|
|
||||||
void ModelDownloadWorker::download_model()
|
void ModelDownloadWorker::download_model()
|
||||||
{
|
{
|
||||||
std::string module_data_dir = obs_get_module_data_path(obs_current_module());
|
char *module_config_path = obs_module_get_config_path(obs_current_module(), "models");
|
||||||
// join the directory and the filename using the platform-specific separator
|
// Check if the config folder exists
|
||||||
std::string model_save_path = module_data_dir + "/" + this->model_name;
|
if (!std::filesystem::exists(module_config_path)) {
|
||||||
|
obs_log(LOG_WARNING, "Config folder does not exist: %s", module_config_path);
|
||||||
|
// Create the config folder
|
||||||
|
if (!std::filesystem::create_directories(module_config_path)) {
|
||||||
|
obs_log(LOG_ERROR, "Failed to create config folder: %s",
|
||||||
|
module_config_path);
|
||||||
|
emit download_error("Failed to create config folder.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *model_save_path_str =
|
||||||
|
obs_module_get_config_path(obs_current_module(), this->model_name.c_str());
|
||||||
|
std::string model_save_path(model_save_path_str);
|
||||||
|
bfree(model_save_path_str);
|
||||||
obs_log(LOG_INFO, "Model save path: %s", model_save_path.c_str());
|
obs_log(LOG_INFO, "Model save path: %s", model_save_path.c_str());
|
||||||
|
|
||||||
// extract filename from path in this->modle_name
|
// extract filename from path in this->modle_name
|
||||||
@ -143,11 +170,11 @@ void ModelDownloadWorker::download_model()
|
|||||||
}
|
}
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
emit download_finished(model_save_path);
|
||||||
} else {
|
} else {
|
||||||
obs_log(LOG_ERROR, "Failed to initialize curl.");
|
obs_log(LOG_ERROR, "Failed to initialize curl.");
|
||||||
emit download_error("Failed to initialize curl.");
|
emit download_error("Failed to initialize curl.");
|
||||||
}
|
}
|
||||||
emit download_finished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModelDownloadWorker::progress_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
|
int ModelDownloadWorker::progress_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
|
||||||
@ -168,9 +195,13 @@ int ModelDownloadWorker::progress_callback(void *clientp, curl_off_t dltotal, cu
|
|||||||
|
|
||||||
ModelDownloader::~ModelDownloader()
|
ModelDownloader::~ModelDownloader()
|
||||||
{
|
{
|
||||||
|
if (this->download_thread != nullptr) {
|
||||||
|
if (this->download_thread->isRunning()) {
|
||||||
this->download_thread->quit();
|
this->download_thread->quit();
|
||||||
this->download_thread->wait();
|
this->download_thread->wait();
|
||||||
|
}
|
||||||
delete this->download_thread;
|
delete this->download_thread;
|
||||||
|
}
|
||||||
delete this->download_worker;
|
delete this->download_worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#include "model-downloader-types.h"
|
||||||
|
|
||||||
class ModelDownloadWorker : public QObject {
|
class ModelDownloadWorker : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -20,7 +22,7 @@ public slots:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void download_progress(int progress);
|
void download_progress(int progress);
|
||||||
void download_finished();
|
void download_finished(const std::string &path);
|
||||||
void download_error(const std::string &reason);
|
void download_error(const std::string &reason);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -33,22 +35,27 @@ class ModelDownloader : public QDialog {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ModelDownloader(const std::string &model_name,
|
ModelDownloader(const std::string &model_name,
|
||||||
std::function<void(int download_status)> download_finished_callback,
|
download_finished_callback_t download_finished_callback,
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
~ModelDownloader();
|
~ModelDownloader();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void update_progress(int progress);
|
void update_progress(int progress);
|
||||||
void download_finished();
|
void download_finished(const std::string &path);
|
||||||
void show_error(const std::string &reason);
|
void show_error(const std::string &reason);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVBoxLayout *layout;
|
QVBoxLayout *layout;
|
||||||
QProgressBar *progress_bar;
|
QProgressBar *progress_bar;
|
||||||
QThread *download_thread;
|
QThread *download_thread;
|
||||||
ModelDownloadWorker *download_worker;
|
ModelDownloadWorker *download_worker;
|
||||||
// Callback for when the download is finished
|
// Callback for when the download is finished
|
||||||
std::function<void(int download_status)> download_finished_callback;
|
download_finished_callback_t download_finished_callback;
|
||||||
|
bool mPrepareToClose;
|
||||||
|
void close();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MODEL_DOWNLOADER_UI_H
|
#endif // MODEL_DOWNLOADER_UI_H
|
||||||
|
@ -12,28 +12,43 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
bool check_if_model_exists(const std::string &model_name)
|
std::string find_model_file(const std::string &model_name)
|
||||||
{
|
{
|
||||||
obs_log(LOG_INFO, "Checking if model %s exists...", model_name.c_str());
|
const char *model_name_cstr = model_name.c_str();
|
||||||
char *model_file_path = obs_module_file(model_name.c_str());
|
obs_log(LOG_INFO, "Checking if model %s exists in data...", model_name_cstr);
|
||||||
obs_log(LOG_INFO, "Model file path: %s", model_file_path);
|
|
||||||
|
char *model_file_path = obs_module_file(model_name_cstr);
|
||||||
if (model_file_path == nullptr) {
|
if (model_file_path == nullptr) {
|
||||||
obs_log(LOG_INFO, "Model %s does not exist.", model_name.c_str());
|
obs_log(LOG_INFO, "Model %s not found in data.", model_name_cstr);
|
||||||
return false;
|
} else {
|
||||||
|
std::string model_file_path_str(model_file_path);
|
||||||
|
bfree(model_file_path);
|
||||||
|
if (!std::filesystem::exists(model_file_path_str)) {
|
||||||
|
obs_log(LOG_INFO, "Model not found in data: %s",
|
||||||
|
model_file_path_str.c_str());
|
||||||
|
} else {
|
||||||
|
obs_log(LOG_INFO, "Model found in data: %s", model_file_path_str.c_str());
|
||||||
|
return model_file_path_str;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!std::filesystem::exists(model_file_path)) {
|
// Check if model exists in the config folder
|
||||||
obs_log(LOG_INFO, "Model %s does not exist.", model_file_path);
|
char *model_config_path_str =
|
||||||
bfree(model_file_path);
|
obs_module_get_config_path(obs_current_module(), model_name_cstr);
|
||||||
return false;
|
std::string model_config_path(model_config_path_str);
|
||||||
}
|
bfree(model_config_path_str);
|
||||||
bfree(model_file_path);
|
obs_log(LOG_INFO, "Model path in config: %s", model_config_path.c_str());
|
||||||
return true;
|
if (std::filesystem::exists(model_config_path)) {
|
||||||
|
obs_log(LOG_INFO, "Model exists in config folder: %s", model_config_path.c_str());
|
||||||
|
return model_config_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void download_model_with_ui_dialog(
|
obs_log(LOG_INFO, "Model %s not found.", model_name_cstr);
|
||||||
const std::string &model_name,
|
return "";
|
||||||
std::function<void(int download_status)> download_finished_callback)
|
}
|
||||||
|
|
||||||
|
void download_model_with_ui_dialog(const std::string &model_name,
|
||||||
|
download_finished_callback_t download_finished_callback)
|
||||||
{
|
{
|
||||||
// Start the model downloader UI
|
// Start the model downloader UI
|
||||||
ModelDownloader *model_downloader = new ModelDownloader(
|
ModelDownloader *model_downloader = new ModelDownloader(
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
bool check_if_model_exists(const std::string &model_name);
|
#include "model-downloader-types.h"
|
||||||
|
|
||||||
|
std::string find_model_file(const std::string &model_name);
|
||||||
|
|
||||||
// Start the model downloader UI dialog with a callback for when the download is finished
|
// Start the model downloader UI dialog with a callback for when the download is finished
|
||||||
void download_model_with_ui_dialog(
|
void download_model_with_ui_dialog(const std::string &model_name,
|
||||||
const std::string &model_name,
|
download_finished_callback_t download_finished_callback);
|
||||||
std::function<void(int download_status)> download_finished_callback);
|
|
||||||
|
|
||||||
#endif // MODEL_DOWNLOADER_H
|
#endif // MODEL_DOWNLOADER_H
|
||||||
|
@ -42,7 +42,7 @@ struct transcription_filter_data {
|
|||||||
audio_resampler_t *resampler = nullptr;
|
audio_resampler_t *resampler = nullptr;
|
||||||
|
|
||||||
/* whisper */
|
/* whisper */
|
||||||
std::string whisper_model_path = "models/ggml-tiny.en.bin";
|
std::string whisper_model_path;
|
||||||
struct whisper_context *whisper_context = nullptr;
|
struct whisper_context *whisper_context = nullptr;
|
||||||
whisper_full_params whisper_params;
|
whisper_full_params whisper_params;
|
||||||
|
|
||||||
|
@ -313,14 +313,15 @@ void transcription_filter_update(void *data, obs_data_t *s)
|
|||||||
gf->whisper_model_path = new_model_path;
|
gf->whisper_model_path = new_model_path;
|
||||||
|
|
||||||
// check if the model exists, if not, download it
|
// check if the model exists, if not, download it
|
||||||
if (!check_if_model_exists(gf->whisper_model_path)) {
|
std::string model_file_found = find_model_file(gf->whisper_model_path);
|
||||||
obs_log(LOG_ERROR, "Whisper model does not exist");
|
if (model_file_found == "") {
|
||||||
|
obs_log(LOG_WARNING, "Whisper model does not exist");
|
||||||
download_model_with_ui_dialog(
|
download_model_with_ui_dialog(
|
||||||
gf->whisper_model_path, [gf](int download_status) {
|
gf->whisper_model_path,
|
||||||
|
[gf](int download_status, const std::string &path) {
|
||||||
if (download_status == 0) {
|
if (download_status == 0) {
|
||||||
obs_log(LOG_INFO, "Model download complete");
|
obs_log(LOG_INFO, "Model download complete");
|
||||||
gf->whisper_context = init_whisper_context(
|
gf->whisper_context = init_whisper_context(path);
|
||||||
gf->whisper_model_path);
|
|
||||||
std::thread new_whisper_thread(whisper_loop, gf);
|
std::thread new_whisper_thread(whisper_loop, gf);
|
||||||
gf->whisper_thread.swap(new_whisper_thread);
|
gf->whisper_thread.swap(new_whisper_thread);
|
||||||
} else {
|
} else {
|
||||||
@ -329,7 +330,7 @@ void transcription_filter_update(void *data, obs_data_t *s)
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Model exists, just load it
|
// Model exists, just load it
|
||||||
gf->whisper_context = init_whisper_context(gf->whisper_model_path);
|
gf->whisper_context = init_whisper_context(model_file_found);
|
||||||
std::thread new_whisper_thread(whisper_loop, gf);
|
std::thread new_whisper_thread(whisper_loop, gf);
|
||||||
gf->whisper_thread.swap(new_whisper_thread);
|
gf->whisper_thread.swap(new_whisper_thread);
|
||||||
}
|
}
|
||||||
@ -374,8 +375,8 @@ void transcription_filter_update(void *data, obs_data_t *s)
|
|||||||
|
|
||||||
void *transcription_filter_create(obs_data_t *settings, obs_source_t *filter)
|
void *transcription_filter_create(obs_data_t *settings, obs_source_t *filter)
|
||||||
{
|
{
|
||||||
struct transcription_filter_data *gf = static_cast<struct transcription_filter_data *>(
|
void *p = bzalloc(sizeof(struct transcription_filter_data));
|
||||||
bzalloc(sizeof(struct transcription_filter_data)));
|
struct transcription_filter_data *gf = new (p) transcription_filter_data;
|
||||||
|
|
||||||
// Get the number of channels for the input source
|
// Get the number of channels for the input source
|
||||||
gf->channels = audio_output_get_channels(obs_get_audio());
|
gf->channels = audio_output_get_channels(obs_get_audio());
|
||||||
@ -400,12 +401,7 @@ void *transcription_filter_create(obs_data_t *settings, obs_source_t *filter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gf->context = filter;
|
gf->context = filter;
|
||||||
gf->whisper_model_path = std::string(obs_data_get_string(settings, "whisper_model_path"));
|
gf->whisper_model_path = ""; // The update function will set the model path
|
||||||
gf->whisper_context = init_whisper_context(gf->whisper_model_path);
|
|
||||||
if (gf->whisper_context == nullptr) {
|
|
||||||
obs_log(LOG_ERROR, "Failed to load whisper model");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
gf->overlap_ms = OVERLAP_SIZE_MSEC;
|
gf->overlap_ms = OVERLAP_SIZE_MSEC;
|
||||||
gf->overlap_frames = (size_t)((float)gf->sample_rate / (1000.0f / (float)gf->overlap_ms));
|
gf->overlap_frames = (size_t)((float)gf->sample_rate / (1000.0f / (float)gf->overlap_ms));
|
||||||
@ -437,11 +433,6 @@ void *transcription_filter_create(obs_data_t *settings, obs_source_t *filter)
|
|||||||
// get the settings updated on the filter data struct
|
// get the settings updated on the filter data struct
|
||||||
transcription_filter_update(gf, settings);
|
transcription_filter_update(gf, settings);
|
||||||
|
|
||||||
obs_log(gf->log_level, "transcription_filter: start whisper thread");
|
|
||||||
// start the thread
|
|
||||||
std::thread new_whisper_thread(whisper_loop, gf);
|
|
||||||
gf->whisper_thread.swap(new_whisper_thread);
|
|
||||||
|
|
||||||
gf->active = true;
|
gf->active = true;
|
||||||
|
|
||||||
obs_log(gf->log_level, "transcription_filter: filter created.");
|
obs_log(gf->log_level, "transcription_filter: filter created.");
|
||||||
|
@ -73,7 +73,7 @@ bool vad_simple(float *pcmf32, size_t pcm32f_size, uint32_t sample_rate, float v
|
|||||||
struct whisper_context *init_whisper_context(const std::string &model_path)
|
struct whisper_context *init_whisper_context(const std::string &model_path)
|
||||||
{
|
{
|
||||||
obs_log(LOG_INFO, "Loading whisper model from %s", model_path.c_str());
|
obs_log(LOG_INFO, "Loading whisper model from %s", model_path.c_str());
|
||||||
struct whisper_context *ctx = whisper_init_from_file(obs_module_file(model_path.c_str()));
|
struct whisper_context *ctx = whisper_init_from_file(model_path.c_str());
|
||||||
if (ctx == nullptr) {
|
if (ctx == nullptr) {
|
||||||
obs_log(LOG_ERROR, "Failed to load whisper model");
|
obs_log(LOG_ERROR, "Failed to load whisper model");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user