diff --git a/src/nam_lv2.cpp b/src/nam_lv2.cpp index 06299bb..dcf505c 100644 --- a/src/nam_lv2.cpp +++ b/src/nam_lv2.cpp @@ -12,11 +12,7 @@ #include "nam_plugin.h" // LV2 Functions -static LV2_Handle instantiate( - const LV2_Descriptor*, - double rate, - const char*, - const LV2_Feature* const* features +static LV2_Handle instantiate(const LV2_Descriptor*, double rate, const char*, const LV2_Feature* const* features ) { try { @@ -55,29 +51,9 @@ static void cleanup(LV2_Handle instance) delete static_cast(instance); } -static LV2_Worker_Status -work(LV2_Handle instance, - LV2_Worker_Respond_Function respond, - LV2_Worker_Respond_Handle handle, - uint32_t size, - const void* data) +static const void* extension_data(const char* uri) { - - return LV2_WORKER_SUCCESS; -} - -static LV2_Worker_Status -work_response(LV2_Handle instance, - uint32_t size, - const void* data) -{ - return LV2_WORKER_SUCCESS; -} - -static const void* -extension_data(const char* uri) -{ - static const LV2_Worker_Interface worker = { work, work_response, NULL }; + static const LV2_Worker_Interface worker = { NAM::Plugin::work, NAM::Plugin::work_response, NULL }; if (!strcmp(uri, LV2_WORKER__interface)) return &worker; diff --git a/src/nam_plugin.cpp b/src/nam_plugin.cpp index 8ed19f9..b6753d0 100644 --- a/src/nam_plugin.cpp +++ b/src/nam_plugin.cpp @@ -52,10 +52,71 @@ namespace NAM { return true; } - void Plugin::process(uint32_t n_samples) noexcept { - if (ports.control) { - LV2_ATOM_SEQUENCE_FOREACH(ports.control, event) { - if (event->body.type == uris.atom_Object) { + LV2_Worker_Status Plugin::work(LV2_Handle instance, LV2_Worker_Respond_Function respond, LV2_Worker_Respond_Handle handle, + uint32_t size, const void* data) + { + switch (*((const uint32_t*)data)) + { + case kWorkTypeLoad: + try + { + auto msg = reinterpret_cast(data); + + auto nam = static_cast(instance); + + //nam->currentModel = get_dsp("C://Users//oliph//AppData//Roaming//GuitarSim//NAM//JCM2000Crunch.nam"); + + nam->stagedModel = get_dsp(msg->path); + + LV2WorkType response = kWorkTypeSwitch; + + respond(handle, sizeof(response), &response); + + return LV2_WORKER_SUCCESS; + } + catch (std::exception& e) + { + } + + break; + } + + return LV2_WORKER_ERR_UNKNOWN; + } + + LV2_Worker_Status Plugin::work_response(LV2_Handle instance, uint32_t size, const void* data) + { + switch (*((const uint32_t*)data)) + { + case kWorkTypeSwitch: + try + { + auto nam = static_cast(instance); + + nam->currentModel = std::move(nam->stagedModel); + nam->stagedModel = nullptr; + + return LV2_WORKER_SUCCESS; + } + catch (std::exception& e) + { + } + + break; + } + + return LV2_WORKER_ERR_UNKNOWN; + } + + + void Plugin::process(uint32_t n_samples) noexcept + { + if (ports.control) + { + LV2_ATOM_SEQUENCE_FOREACH(ports.control, event) + { + if (event->body.type == uris.atom_Object) + { const auto obj = reinterpret_cast(&event->body); if (obj->body.otype == uris.patch_Set) @@ -71,15 +132,13 @@ namespace NAM { { lv2_atom_object_get(obj, uris.patch_value, &file_path, 0); - if (file_path && (file_path->size > 0)) + if (file_path && (file_path->size > 0) && (file_path->size < 1024)) { - try - { - namModel = get_dsp((const char*)LV2_ATOM_BODY_CONST(file_path)); - } - catch (std::exception& e) - { - } + LV2LoadModelMsg msg = { kWorkTypeLoad, {} }; + + memcpy(msg.path, (const char*)LV2_ATOM_BODY_CONST(file_path), file_path->size); + + schedule->schedule_work(schedule->handle, sizeof(msg), &msg); } } } @@ -88,7 +147,7 @@ namespace NAM { } } - if (namModel == nullptr) + if (currentModel == nullptr) { for (unsigned int i = 0; i < n_samples; i++) { @@ -97,8 +156,8 @@ namespace NAM { } else { - namModel->process(ports.audio_in, ports.audio_out, n_samples, 1.0, 1.0, mNAMParams); - namModel->finalize_(n_samples); + currentModel->process(ports.audio_in, ports.audio_out, n_samples, 1.0, 1.0, mNAMParams); + currentModel->finalize_(n_samples); } } } diff --git a/src/nam_plugin.h b/src/nam_plugin.h index 7eaad3f..483056e 100644 --- a/src/nam_plugin.h +++ b/src/nam_plugin.h @@ -23,6 +23,16 @@ namespace NAM { + enum LV2WorkType { + kWorkTypeLoad, + kWorkTypeSwitch + }; + + struct LV2LoadModelMsg { + LV2WorkType type; + char path[1024]; + }; + class Plugin { public: struct Ports { @@ -38,7 +48,8 @@ namespace NAM { LV2_Log_Logger logger; LV2_Worker_Schedule* schedule; - std::unique_ptr<::DSP> namModel; + std::unique_ptr<::DSP> currentModel; + std::unique_ptr<::DSP> stagedModel; std::unordered_map mNAMParams = { @@ -53,6 +64,11 @@ namespace NAM { bool initialize(double rate, const LV2_Feature* const* features) noexcept; void process(uint32_t n_samples) noexcept; + + static LV2_Worker_Status work(LV2_Handle instance, LV2_Worker_Respond_Function respond, LV2_Worker_Respond_Handle handle, + uint32_t size, const void* data); + static LV2_Worker_Status work_response(LV2_Handle instance, uint32_t size, const void* data); + private: struct URIs { LV2_URID atom_Object;