Load models using LV2 work scheduler

This commit is contained in:
Mike Oliphant
2023-03-13 12:48:35 -07:00
parent 4ea184cf05
commit 73975aeef6
3 changed files with 94 additions and 43 deletions
+3 -27
View File
@@ -12,11 +12,7 @@
#include "nam_plugin.h" #include "nam_plugin.h"
// LV2 Functions // LV2 Functions
static LV2_Handle instantiate( static LV2_Handle instantiate(const LV2_Descriptor*, double rate, const char*, const LV2_Feature* const* features
const LV2_Descriptor*,
double rate,
const char*,
const LV2_Feature* const* features
) { ) {
try try
{ {
@@ -55,29 +51,9 @@ static void cleanup(LV2_Handle instance)
delete static_cast<NAM::Plugin*>(instance); delete static_cast<NAM::Plugin*>(instance);
} }
static LV2_Worker_Status static const void* extension_data(const char* uri)
work(LV2_Handle instance,
LV2_Worker_Respond_Function respond,
LV2_Worker_Respond_Handle handle,
uint32_t size,
const void* data)
{ {
static const LV2_Worker_Interface worker = { NAM::Plugin::work, NAM::Plugin::work_response, NULL };
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 };
if (!strcmp(uri, LV2_WORKER__interface)) if (!strcmp(uri, LV2_WORKER__interface))
return &worker; return &worker;
+74 -15
View File
@@ -52,10 +52,71 @@ namespace NAM {
return true; return true;
} }
void Plugin::process(uint32_t n_samples) noexcept { LV2_Worker_Status Plugin::work(LV2_Handle instance, LV2_Worker_Respond_Function respond, LV2_Worker_Respond_Handle handle,
if (ports.control) { uint32_t size, const void* data)
LV2_ATOM_SEQUENCE_FOREACH(ports.control, event) { {
if (event->body.type == uris.atom_Object) { switch (*((const uint32_t*)data))
{
case kWorkTypeLoad:
try
{
auto msg = reinterpret_cast<const LV2LoadModelMsg*>(data);
auto nam = static_cast<NAM::Plugin*>(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<NAM::Plugin*>(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<LV2_Atom_Object*>(&event->body); const auto obj = reinterpret_cast<LV2_Atom_Object*>(&event->body);
if (obj->body.otype == uris.patch_Set) if (obj->body.otype == uris.patch_Set)
@@ -71,15 +132,13 @@ namespace NAM {
{ {
lv2_atom_object_get(obj, uris.patch_value, &file_path, 0); 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 LV2LoadModelMsg msg = { kWorkTypeLoad, {} };
{
namModel = get_dsp((const char*)LV2_ATOM_BODY_CONST(file_path)); memcpy(msg.path, (const char*)LV2_ATOM_BODY_CONST(file_path), file_path->size);
}
catch (std::exception& e) 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++) for (unsigned int i = 0; i < n_samples; i++)
{ {
@@ -97,8 +156,8 @@ namespace NAM {
} }
else else
{ {
namModel->process(ports.audio_in, ports.audio_out, n_samples, 1.0, 1.0, mNAMParams); currentModel->process(ports.audio_in, ports.audio_out, n_samples, 1.0, 1.0, mNAMParams);
namModel->finalize_(n_samples); currentModel->finalize_(n_samples);
} }
} }
} }
+17 -1
View File
@@ -23,6 +23,16 @@
namespace NAM { namespace NAM {
enum LV2WorkType {
kWorkTypeLoad,
kWorkTypeSwitch
};
struct LV2LoadModelMsg {
LV2WorkType type;
char path[1024];
};
class Plugin { class Plugin {
public: public:
struct Ports { struct Ports {
@@ -38,7 +48,8 @@ namespace NAM {
LV2_Log_Logger logger; LV2_Log_Logger logger;
LV2_Worker_Schedule* schedule; LV2_Worker_Schedule* schedule;
std::unique_ptr<::DSP> namModel; std::unique_ptr<::DSP> currentModel;
std::unique_ptr<::DSP> stagedModel;
std::unordered_map<std::string, double> mNAMParams = std::unordered_map<std::string, double> mNAMParams =
{ {
@@ -53,6 +64,11 @@ namespace NAM {
bool initialize(double rate, const LV2_Feature* const* features) noexcept; bool initialize(double rate, const LV2_Feature* const* features) noexcept;
void process(uint32_t n_samples) 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: private:
struct URIs { struct URIs {
LV2_URID atom_Object; LV2_URID atom_Object;