T11: IPC param sync 2 chieu native<->JS (setParamNormalized/setParameter, vst_param_changed event, guard chong loop)

This commit is contained in:
2026-08-11 16:27:30 +07:00
parent aaf21ddf89
commit 9eec33cc79
7 changed files with 650 additions and 41 deletions
+94 -2
View File
@@ -26,6 +26,10 @@
namespace {
// Callback param (T11): plugin đổi param (audioMasterAutomate) → host.
typedef void (VSTCALLBACK* SF_ParamChangedCallback)(int32 handle, int32 paramIndex,
double valueNormalized, void* userdata);
struct Instance
{
HMODULE module = nullptr;
@@ -38,9 +42,14 @@ struct Instance
ERect* editorRect = nullptr;
bool editorOpen = false;
bool active = false;
int32 handle = 0;
SF_ParamChangedCallback paramCb = nullptr;
void* paramCbUserdata = nullptr;
};
std::mutex g_mutex;
std::mutex g_effect_map_mutex; // riêng: audioMasterAutomate gọi từ audio thread
std::map<AEffect*, Instance*> g_effect_map;
std::map<int32, std::unique_ptr<Instance>> g_instances;
int32 g_next_handle = 1;
@@ -59,10 +68,9 @@ thread_local Instance* tls_loading = nullptr;
VstIntPtr VSTCALLBACK hostAudioMasterImpl (AEffect* effect, int32 opcode, int32 index,
VstIntPtr value, void* ptr, float opt)
{
(void) effect;
(void) index;
(void) value;
(void) opt;
(void) ptr;
Instance* inst = tls_loading;
switch (opcode)
{
@@ -72,6 +80,22 @@ VstIntPtr VSTCALLBACK hostAudioMasterImpl (AEffect* effect, int32 opcode, int32
return inst ? inst->sampleRate : 44100;
case audioMasterGetBlockSize:
return inst ? inst->blockSize : 512;
case audioMasterAutomate:
{
// Plugin đổi param (user kéo knob trong editor) → callback lên host.
// Effect → instance qua map riêng (audio thread, không giữ g_mutex).
Instance* owner = nullptr;
{
std::lock_guard<std::mutex> lock (g_effect_map_mutex);
auto it = g_effect_map.find (effect);
if (it != g_effect_map.end ())
owner = it->second;
}
if (owner && owner->paramCb)
owner->paramCb (owner->handle, index, static_cast<double> (opt),
owner->paramCbUserdata);
return 1;
}
case audioMasterCurrentId:
case audioMasterGetLanguage:
return 0;
@@ -200,6 +224,11 @@ __declspec (dllexport) int32 SF_VST2_Load (const char* module_path_utf8,
}
int32 handle = g_next_handle++;
inst->handle = handle;
{
std::lock_guard<std::mutex> lock (g_effect_map_mutex);
g_effect_map[inst->effect] = inst.get ();
}
g_instances[handle] = std::move (inst);
return handle;
}
@@ -217,6 +246,10 @@ __declspec (dllexport) int32 SF_VST2_Close (int32 handle, char* err, int32 err_c
Instance* inst = it->second.get ();
if (inst->effect)
{
{
std::lock_guard<std::mutex> lock (g_effect_map_mutex);
g_effect_map.erase (inst->effect);
}
if (inst->active)
{
inst->effect->dispatcher (inst->effect, effStopProcess, 0, 0, nullptr, 0.0f);
@@ -372,4 +405,63 @@ __declspec (dllexport) int32 SF_VST2_Process (int32 handle, float* buffers, int3
return -4;
}
// Đăng ký callback param (T11): plugin đổi param (audioMasterAutomate) →
// cb(handle, paramIndex, valueNormalized, userdata).
__declspec (dllexport) int32 SF_VST2_SetParamCallback (int32 handle,
SF_ParamChangedCallback cb,
void* userdata)
{
std::lock_guard<std::mutex> lock (g_mutex);
auto it = g_instances.find (handle);
if (it == g_instances.end ())
return -1;
it->second->paramCb = cb;
it->second->paramCbUserdata = userdata;
return 0;
}
// JS automation → setParameter (T11).
__declspec (dllexport) int32 SF_VST2_SetParam (int32 handle, int32 paramIndex,
double valueNormalized)
{
std::lock_guard<std::mutex> lock (g_mutex);
auto it = g_instances.find (handle);
if (it == g_instances.end ())
return -1;
Instance* inst = it->second.get ();
if (!inst->effect || !inst->effect->setParameter)
return -2;
inst->effect->setParameter (inst->effect, paramIndex,
static_cast<float> (valueNormalized));
return 0;
}
// Số tham số plugin.
__declspec (dllexport) int32 SF_VST2_GetParamCount (int32 handle)
{
std::lock_guard<std::mutex> lock (g_mutex);
auto it = g_instances.find (handle);
if (it == g_instances.end ())
return -1;
Instance* inst = it->second.get ();
if (!inst->effect || !inst->effect->numParams)
return -2;
return inst->effect->numParams (inst->effect);
}
// Giá trị param (0..1) — JS đọc để dựng UI.
__declspec (dllexport) int32 SF_VST2_GetParam (int32 handle, int32 paramIndex, double* out_value)
{
std::lock_guard<std::mutex> lock (g_mutex);
auto it = g_instances.find (handle);
if (it == g_instances.end ())
return -1;
Instance* inst = it->second.get ();
if (!inst->effect || !inst->effect->getParameter)
return -2;
if (out_value)
*out_value = static_cast<double> (inst->effect->getParameter (inst->effect, paramIndex));
return 0;
}
} // extern "C"