Browse Source

add USE_LOG_PRINTF; use recursive mutex (Linux) (fixes BWS plugin re-loading)

pull/1639/head
bsp2 6 years ago
parent
commit
b46ccdd88e
3 changed files with 122 additions and 14 deletions
  1. +1
    -0
      setenv_linux.sh
  2. +72
    -0
      src/app/RackWidget.cpp
  3. +49
    -14
      src/vst2_main.cpp

+ 1
- 0
setenv_linux.sh View File

@@ -23,6 +23,7 @@ fi


# Extra C compiler flags # Extra C compiler flags
export EXTRA_CFLAGS=-march=${CPU_ARCH} export EXTRA_CFLAGS=-march=${CPU_ARCH}
#-DUSE_LOG_PRINTF


# Extra C++ compiler flags # Extra C++ compiler flags
export EXTRA_CPPFLAGS=-march=${CPU_ARCH} export EXTRA_CPPFLAGS=-march=${CPU_ARCH}


+ 72
- 0
src/app/RackWidget.cpp View File

@@ -27,6 +27,14 @@ extern void vst2_idle_detect_mode_get (int *_mode);
#endif // USE_VST2 #endif // USE_VST2




#define Dprintf printf

#ifdef USE_LOG_PRINTF
extern void log_printf(const char *logData, ...);
#undef Dprintf
#define Dprintf log_printf
#endif // USE_LOG_PRINTF

namespace rack { namespace rack {




@@ -213,17 +221,23 @@ bool RackWidget::loadPatchFromString(const char *_string) {
} }
json_error_t error; json_error_t error;
Dprintf("call json_loads\n");
json_t *rootJ = json_loads(_string, 0/*flags*/, &error); json_t *rootJ = json_loads(_string, 0/*flags*/, &error);
Dprintf("json_loads returned rootJ=%p\n", rootJ);
if (rootJ) { if (rootJ) {
clear(); clear();
#ifdef USE_VST2 #ifdef USE_VST2
global->vst2.b_patch_loading = true; global->vst2.b_patch_loading = true;
#endif #endif
Dprintf("call fromJson\n");
fromJson(rootJ); fromJson(rootJ);
// Dprintf("fromJson returned\n");
#ifdef USE_VST2 #ifdef USE_VST2
global->vst2.b_patch_loading = false; global->vst2.b_patch_loading = false;
#endif // USE_VST2 #endif // USE_VST2
Dprintf("call json_decref\n");
json_decref(rootJ); json_decref(rootJ);
Dprintf("json_decref returned\n");
return true; return true;
} }
else { else {
@@ -364,8 +378,11 @@ json_t *RackWidget::toJson() {
void RackWidget::fromJson(json_t *rootJ) { void RackWidget::fromJson(json_t *rootJ) {
std::string message; std::string message;


// Dprintf("fromJson: 1\n");
vst2_set_shared_plugin_tls_globals(); // update JSON hashtable seed vst2_set_shared_plugin_tls_globals(); // update JSON hashtable seed


// Dprintf("fromJson: 2\n");

// version // version
std::string version; std::string version;
json_t *versionJ = json_object_get(rootJ, "version"); json_t *versionJ = json_object_get(rootJ, "version");
@@ -373,6 +390,8 @@ void RackWidget::fromJson(json_t *rootJ) {
version = json_string_value(versionJ); version = json_string_value(versionJ);
} }


// Dprintf("fromJson: 3\n");

// Detect old patches with ModuleWidget::params/inputs/outputs indices. // Detect old patches with ModuleWidget::params/inputs/outputs indices.
// (We now use Module::params/inputs/outputs indices.) // (We now use Module::params/inputs/outputs indices.)
int legacy = 0; int legacy = 0;
@@ -383,6 +402,8 @@ void RackWidget::fromJson(json_t *rootJ) {
info("Loading patch using legacy mode %d", legacy); info("Loading patch using legacy mode %d", legacy);
} }


// Dprintf("fromJson: 4\n");

#ifdef RACK_HOST #ifdef RACK_HOST
float oversampleFactor = -1.0f; float oversampleFactor = -1.0f;
int oversampleQuality = -1; int oversampleQuality = -1;
@@ -395,6 +416,8 @@ void RackWidget::fromJson(json_t *rootJ) {
} }
} }


// Dprintf("fromJson: 5\n");

// Oversample quality (0..10) // Oversample quality (0..10)
{ {
json_t *oversampleJ = json_object_get(rootJ, "oversampleQuality"); json_t *oversampleJ = json_object_get(rootJ, "oversampleQuality");
@@ -403,8 +426,12 @@ void RackWidget::fromJson(json_t *rootJ) {
} }
} }


// Dprintf("fromJson: 6\n");

vst2_oversample_realtime_set(oversampleFactor, oversampleQuality); vst2_oversample_realtime_set(oversampleFactor, oversampleQuality);


// Dprintf("fromJson: 7\n");

// Oversample channel limit // Oversample channel limit
int oversampleNumIn = -1; int oversampleNumIn = -1;
int oversampleNumOut = -1; int oversampleNumOut = -1;
@@ -417,6 +444,8 @@ void RackWidget::fromJson(json_t *rootJ) {
} }
} }


// Dprintf("fromJson: 8\n");

// Oversample output channel limit // Oversample output channel limit
{ {
json_t *oversampleJ = json_object_get(rootJ, "oversampleNumOut"); json_t *oversampleJ = json_object_get(rootJ, "oversampleNumOut");
@@ -425,8 +454,12 @@ void RackWidget::fromJson(json_t *rootJ) {
} }
} }


// Dprintf("fromJson: 9\n");

vst2_oversample_channels_set(oversampleNumIn, oversampleNumOut); vst2_oversample_channels_set(oversampleNumIn, oversampleNumOut);


// Dprintf("fromJson: 10\n");

// Idle detection mode // Idle detection mode
{ {
json_t *idleJ = json_object_get(rootJ, "idleDetect"); json_t *idleJ = json_object_get(rootJ, "idleDetect");
@@ -436,6 +469,8 @@ void RackWidget::fromJson(json_t *rootJ) {
} }
#endif // RACK_HOST #endif // RACK_HOST


// Dprintf("fromJson: 11\n");

// modules // modules
std::map<int, ModuleWidget*> moduleWidgets; std::map<int, ModuleWidget*> moduleWidgets;
json_t *modulesJ = json_object_get(rootJ, "modules"); json_t *modulesJ = json_object_get(rootJ, "modules");
@@ -444,22 +479,30 @@ void RackWidget::fromJson(json_t *rootJ) {
json_t *moduleJ; json_t *moduleJ;
json_array_foreach(modulesJ, moduleId, moduleJ) { json_array_foreach(modulesJ, moduleId, moduleJ) {
// Add "legacy" property if in legacy mode // Add "legacy" property if in legacy mode
// Dprintf("fromJson: 12.1\n");
if (legacy) { if (legacy) {
json_object_set(moduleJ, "legacy", json_integer(legacy)); json_object_set(moduleJ, "legacy", json_integer(legacy));
} }
// Dprintf("fromJson: 12.2\n");


json_t *pluginSlugJ = json_object_get(moduleJ, "plugin"); json_t *pluginSlugJ = json_object_get(moduleJ, "plugin");
if (!pluginSlugJ) continue; if (!pluginSlugJ) continue;
// Dprintf("fromJson: 12.3\n");
json_t *modelSlugJ = json_object_get(moduleJ, "model"); json_t *modelSlugJ = json_object_get(moduleJ, "model");
if (!modelSlugJ) continue; if (!modelSlugJ) continue;
// Dprintf("fromJson: 12.4\n");
std::string pluginSlug = json_string_value(pluginSlugJ); std::string pluginSlug = json_string_value(pluginSlugJ);
// Dprintf("fromJson: 12.5\n");
std::string modelSlug = json_string_value(modelSlugJ); std::string modelSlug = json_string_value(modelSlugJ);
// Dprintf("fromJson: 12.6\n");


Model *model = pluginGetModel(pluginSlug, modelSlug); Model *model = pluginGetModel(pluginSlug, modelSlug);
// Dprintf("fromJson: 12.7\n");
if (!model) { if (!model) {
message += stringf("Could not find module \"%s\" of plugin \"%s\"\n", modelSlug.c_str(), pluginSlug.c_str()); message += stringf("Could not find module \"%s\" of plugin \"%s\"\n", modelSlug.c_str(), pluginSlug.c_str());
continue; continue;
} }
// Dprintf("fromJson: 12.8\n");


// Create ModuleWidget // Create ModuleWidget
// // #ifdef USE_VST2 // // #ifdef USE_VST2
@@ -467,29 +510,47 @@ void RackWidget::fromJson(json_t *rootJ) {
// // model->plugin->set_tls_globals_fxn(model->plugin); // // model->plugin->set_tls_globals_fxn(model->plugin);
// // } // // }
// // #endif // USE_VST2 // // #endif // USE_VST2
// Dprintf("fromJson: 12.9\n");
ModuleWidget *moduleWidget = model->createModuleWidget(); ModuleWidget *moduleWidget = model->createModuleWidget();
// Dprintf("fromJson: 12.10\n");
assert(moduleWidget); assert(moduleWidget);
// Dprintf("fromJson: 12.11\n");
moduleWidget->fromJson(moduleJ); moduleWidget->fromJson(moduleJ);
// Dprintf("fromJson: 12.12\n");
moduleContainer->addChild(moduleWidget); moduleContainer->addChild(moduleWidget);
// Dprintf("fromJson: 12.13\n");
moduleWidgets[moduleId] = moduleWidget; moduleWidgets[moduleId] = moduleWidget;
// Dprintf("fromJson: 12.14\n");
} }


// Dprintf("fromJson: 13\n");

// wires // wires
json_t *wiresJ = json_object_get(rootJ, "wires"); json_t *wiresJ = json_object_get(rootJ, "wires");
if (!wiresJ) return; if (!wiresJ) return;
// Dprintf("fromJson: 14\n");
size_t wireId; size_t wireId;
json_t *wireJ; json_t *wireJ;
json_array_foreach(wiresJ, wireId, wireJ) { json_array_foreach(wiresJ, wireId, wireJ) {
// Dprintf("fromJson: 14.1\n");
int outputModuleId = json_integer_value(json_object_get(wireJ, "outputModuleId")); int outputModuleId = json_integer_value(json_object_get(wireJ, "outputModuleId"));
// Dprintf("fromJson: 14.2\n");
int outputId = json_integer_value(json_object_get(wireJ, "outputId")); int outputId = json_integer_value(json_object_get(wireJ, "outputId"));
// Dprintf("fromJson: 14.3\n");
int inputModuleId = json_integer_value(json_object_get(wireJ, "inputModuleId")); int inputModuleId = json_integer_value(json_object_get(wireJ, "inputModuleId"));
// Dprintf("fromJson: 14.4\n");
int inputId = json_integer_value(json_object_get(wireJ, "inputId")); int inputId = json_integer_value(json_object_get(wireJ, "inputId"));
// Dprintf("fromJson: 14.5\n");


// Get module widgets // Get module widgets
ModuleWidget *outputModuleWidget = moduleWidgets[outputModuleId]; ModuleWidget *outputModuleWidget = moduleWidgets[outputModuleId];
// Dprintf("fromJson: 14.6\n");
if (!outputModuleWidget) continue; if (!outputModuleWidget) continue;
// Dprintf("fromJson: 14.7\n");
ModuleWidget *inputModuleWidget = moduleWidgets[inputModuleId]; ModuleWidget *inputModuleWidget = moduleWidgets[inputModuleId];
// Dprintf("fromJson: 14.8\n");
if (!inputModuleWidget) continue; if (!inputModuleWidget) continue;
// Dprintf("fromJson: 14.9\n");


// Get port widgets // Get port widgets
Port *outputPort = NULL; Port *outputPort = NULL;
@@ -516,26 +577,37 @@ void RackWidget::fromJson(json_t *rootJ) {
} }
if (!outputPort || !inputPort) if (!outputPort || !inputPort)
continue; continue;
// Dprintf("fromJson: 14.10\n");


// Create WireWidget // Create WireWidget
WireWidget *wireWidget = new WireWidget(); WireWidget *wireWidget = new WireWidget();
// Dprintf("fromJson: 14.11\n");
wireWidget->fromJson(wireJ); wireWidget->fromJson(wireJ);
// Dprintf("fromJson: 14.12\n");
wireWidget->outputPort = outputPort; wireWidget->outputPort = outputPort;
wireWidget->inputPort = inputPort; wireWidget->inputPort = inputPort;
wireWidget->updateWire(); wireWidget->updateWire();
// Dprintf("fromJson: 14.13\n");
// Add wire to rack // Add wire to rack
wireContainer->addChild(wireWidget); wireContainer->addChild(wireWidget);
// Dprintf("fromJson: 14.14\n");
} }


// Dprintf("fromJson: 15\n");

// Display a message if we have something to say // Display a message if we have something to say
if (!message.empty()) { if (!message.empty()) {
osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, message.c_str()); osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, message.c_str());
} }


// Dprintf("fromJson: 16\n");

#ifdef USE_VST2 #ifdef USE_VST2
global_ui->param_info.placeholder_framecount = (30*30)-10; global_ui->param_info.placeholder_framecount = (30*30)-10;
global_ui->param_info.last_param_widget = NULL; global_ui->param_info.last_param_widget = NULL;
#endif // USE_VST2 #endif // USE_VST2

// Dprintf("fromJson: LEAVE\n");
} }


void RackWidget::addModule(ModuleWidget *m) { void RackWidget::addModule(ModuleWidget *m) {


+ 49
- 14
src/vst2_main.cpp View File

@@ -150,11 +150,14 @@ struct PluginMutex {
#include <fenv.h> // fesetround() #include <fenv.h> // fesetround()
#include <stdarg.h> #include <stdarg.h>


// #define USE_LOG_PRINTF defined

#ifdef USE_LOG_PRINTF
static FILE *logfile; static FILE *logfile;
#undef Dprintf #undef Dprintf
#define Dprintf log_printf #define Dprintf log_printf


static void log_printf(const char *logData, ...) {
void log_printf(const char *logData, ...) {
static char buf[16*1024]; static char buf[16*1024];
va_list va; va_list va;
va_start(va, logData); va_start(va, logData);
@@ -164,13 +167,14 @@ static void log_printf(const char *logData, ...) {
fputs(buf, logfile); fputs(buf, logfile);
fflush(logfile); fflush(logfile);
} }
#endif // USE_LOG_PRINTF




// #define _GNU_SOURCE // #define _GNU_SOURCE
#include <dlfcn.h> #include <dlfcn.h>


//static pthread_mutex_t loc_pthread_mutex_t_init = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static pthread_mutex_t loc_pthread_mutex_t_init = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t loc_pthread_mutex_t_init = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
//static pthread_mutex_t loc_pthread_mutex_t_init = PTHREAD_MUTEX_INITIALIZER;


struct PluginMutex { struct PluginMutex {
pthread_mutex_t handle; pthread_mutex_t handle;
@@ -768,6 +772,7 @@ public:
} }


void setOversampleRealtime(float _factor, int _quality) { void setOversampleRealtime(float _factor, int _quality) {
Dprintf("xxx setOversampleRealtime 1\n");
if(_factor < 0.0f) if(_factor < 0.0f)
_factor = oversample.realtime_factor; // keep _factor = oversample.realtime_factor; // keep


@@ -787,6 +792,8 @@ public:
oversample.realtime_factor = _factor; oversample.realtime_factor = _factor;
oversample.realtime_quality = _quality; oversample.realtime_quality = _quality;


Dprintf("xxx setOversampleRealtime 2 b_offline=%d\n", b_offline);

if(!b_offline) if(!b_offline)
{ {
setOversample(oversample.realtime_factor, oversample.realtime_quality); setOversample(oversample.realtime_factor, oversample.realtime_quality);
@@ -836,34 +843,52 @@ public:
else if(_numOut > NUM_OUTPUTS) else if(_numOut > NUM_OUTPUTS)
_numOut = NUM_OUTPUTS; _numOut = NUM_OUTPUTS;


// Dprintf("xxx setOversampleChannels: lockAudio\n");
lockAudio(); lockAudio();
// Dprintf("xxx setOversampleChannels: lockAudio done\n");
oversample.num_in = sUI(_numIn); oversample.num_in = sUI(_numIn);
oversample.num_out = sUI(_numOut); oversample.num_out = sUI(_numOut);
// Dprintf("xxx setOversampleChannels: unlockAudio\n");
unlockAudio(); unlockAudio();
// Dprintf("xxx setOversampleChannels: unlockAudio done\n");
} }


bool setSampleRate(float _rate, bool _bLock = true) { bool setSampleRate(float _rate, bool _bLock = true) {
bool r = false; bool r = false;


// Dprintf("xxx setSampleRate: 1 bLock=%d\n", _bLock);

if((_rate >= float(MIN_SAMPLE_RATE)) && (_rate <= float(MAX_SAMPLE_RATE))) if((_rate >= float(MIN_SAMPLE_RATE)) && (_rate <= float(MAX_SAMPLE_RATE)))
{ {
// Dprintf("xxx setSampleRate: 2\n");
if(_bLock) if(_bLock)
{ {
// Dprintf("xxx setSampleRate: 2.1\n");
setGlobals(); setGlobals();
// Dprintf("xxx setSampleRate: 2.2\n");
lockAudio(); lockAudio();
// Dprintf("xxx setSampleRate: 2.3\n");
} }


sample_rate = _rate; sample_rate = _rate;


// Dprintf("xxx setSampleRate: 3\n");

vst2_set_samplerate(sample_rate * oversample.factor); // see engine.cpp vst2_set_samplerate(sample_rate * oversample.factor); // see engine.cpp


// Dprintf("xxx setSampleRate: 4\n");

destroyResamplerStates(); destroyResamplerStates();


// Dprintf("xxx setSampleRate: 5\n");

// Lazy-alloc resampler state // Lazy-alloc resampler state
if(!Dfltequal(oversample.factor, 1.0f)) if(!Dfltequal(oversample.factor, 1.0f))
{ {
int err; int err;


// Dprintf("xxx setSampleRate: 6\n");

oversample.srs_in = speex_resampler_init(NUM_INPUTS, oversample.srs_in = speex_resampler_init(NUM_INPUTS,
sUI(sample_rate), // in rate sUI(sample_rate), // in rate
sUI(sample_rate * oversample.factor), // out rate sUI(sample_rate * oversample.factor), // out rate
@@ -871,6 +896,8 @@ public:
&err &err
); );


// Dprintf("xxx setSampleRate: 7\n");

oversample.srs_out = speex_resampler_init(NUM_OUTPUTS, oversample.srs_out = speex_resampler_init(NUM_OUTPUTS,
sUI(sample_rate * oversample.factor), // in rate sUI(sample_rate * oversample.factor), // in rate
sUI(sample_rate), // out rate sUI(sample_rate), // out rate
@@ -881,13 +908,21 @@ public:
Dprintf("xxx vstrack_plugin: initialize speex resampler (rate=%f factor=%f quality=%d)\n", sample_rate, oversample.factor, oversample.quality); Dprintf("xxx vstrack_plugin: initialize speex resampler (rate=%f factor=%f quality=%d)\n", sample_rate, oversample.factor, oversample.quality);
} }


// Dprintf("xxx setSampleRate: 8\n");

if(_bLock) if(_bLock)
{ {
// Dprintf("xxx setSampleRate: 8.1\n");
unlockAudio(); unlockAudio();
// Dprintf("xxx setSampleRate: 8.2\n");
} }

// Dprintf("xxx setSampleRate: 9\n");
r = true; r = true;
} }


// Dprintf("xxx setSampleRate: LEAVE\n");

return r; return r;
} }


@@ -1014,26 +1049,26 @@ public:
} }


bool setProgramChunk(size_t _size, uint8_t *_addr) { bool setProgramChunk(size_t _size, uint8_t *_addr) {
Dprintf("xxx vstrack_plugin:setProgramChunk: 1\n");
// Dprintf("xxx vstrack_plugin:setProgramChunk: 1\n");
setGlobals(); setGlobals();
Dprintf("xxx vstrack_plugin:setProgramChunk: 2\n");
// Dprintf("xxx vstrack_plugin:setProgramChunk: 2\n");
lockAudio(); lockAudio();
Dprintf("xxx vstrack_plugin:setProgramChunk: 3\n");
// Dprintf("xxx vstrack_plugin:setProgramChunk: 3\n");
vst2_set_shared_plugin_tls_globals(); vst2_set_shared_plugin_tls_globals();
Dprintf("xxx vstrack_plugin:setProgramChunk: 4\n");
// Dprintf("xxx vstrack_plugin:setProgramChunk: 4\n");
#if 0 #if 0
Dprintf("xxx vstrack_plugin:setProgramChunk: size=%u\n", _size); Dprintf("xxx vstrack_plugin:setProgramChunk: size=%u\n", _size);
#endif #endif
lglw_glcontext_push(rack::global_ui->window.lglw); lglw_glcontext_push(rack::global_ui->window.lglw);
Dprintf("xxx vstrack_plugin:setProgramChunk: 5\n");
// Dprintf("xxx vstrack_plugin:setProgramChunk: 5\n");
bool r = rack::global_ui->app.gRackWidget->loadPatchFromString((const char*)_addr); bool r = rack::global_ui->app.gRackWidget->loadPatchFromString((const char*)_addr);
Dprintf("xxx vstrack_plugin:setProgramChunk: 6\n");
// Dprintf("xxx vstrack_plugin:setProgramChunk: 6\n");
rack::global_ui->ui.gScene->step(); // w/o this the patch is bypassed rack::global_ui->ui.gScene->step(); // w/o this the patch is bypassed
Dprintf("xxx vstrack_plugin:setProgramChunk: 7\n");
// Dprintf("xxx vstrack_plugin:setProgramChunk: 7\n");
lglw_glcontext_pop(rack::global_ui->window.lglw); lglw_glcontext_pop(rack::global_ui->window.lglw);
Dprintf("xxx vstrack_plugin:setProgramChunk: 8 r=%d\n", r);
// Dprintf("xxx vstrack_plugin:setProgramChunk: 8 r=%d\n", r);
unlockAudio(); unlockAudio();
Dprintf("xxx vstrack_plugin:setProgramChunk: 9\n");
// Dprintf("xxx vstrack_plugin:setProgramChunk: 9\n");
return r; return r;
} }


@@ -2233,9 +2268,9 @@ void vst2_idle_detect_mode_get(int *_mode) {
*/ */
VST_EXPORT VSTPlugin *VSTPluginMain(VSTHostCallback vstHostCallback) { VST_EXPORT VSTPlugin *VSTPluginMain(VSTHostCallback vstHostCallback) {


#ifdef YAC_LINUX
#ifdef USE_LOG_PRINTF
logfile = fopen("/tmp/vst2_log.txt", "w"); logfile = fopen("/tmp/vst2_log.txt", "w");
#endif
#endif // USE_LOG_PRINTF


Dprintf("vstrack_plugin: called VSTPluginMain... \n"); Dprintf("vstrack_plugin: called VSTPluginMain... \n");




Loading…
Cancel
Save