mirror of
https://github.com/mikeoliphant/neural-amp-modeler-lv2.git
synced 2026-06-20 19:03:59 +02:00
Load models using LV2 work scheduler
This commit is contained in:
+3
-27
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user