Browse Source

Make zynaddsubfx get/setState more resilient, shouldn't lock now

tags/1.9.7
falkTX 8 years ago
parent
commit
8d304b885b
1 changed files with 91 additions and 31 deletions
  1. +91
    -31
      source/native-plugins/zynaddsubfx-synth.cpp

+ 91
- 31
source/native-plugins/zynaddsubfx-synth.cpp View File

@@ -35,6 +35,7 @@

using juce::roundToIntAccurate;
using juce::FloatVectorOperations;
using juce::ScopedPointer;

// #define ZYN_MSG_ANYWHERE

@@ -188,8 +189,80 @@ static ZynAddSubFxPrograms sPrograms;

// -----------------------------------------------------------------------

class ZynAddSubFxPlugin : public NativePluginAndUiClass,
private CarlaThread
class MiddleWareThread : public CarlaThread
{
public:
class ScopedStopper
{
public:
ScopedStopper(MiddleWareThread& mwt) noexcept
: wasRunning(mwt.isThreadRunning()),
thread(mwt),
middleWare(mwt.fMiddleWare)
{
if (wasRunning)
thread.stop();
}

~ScopedStopper() noexcept
{
if (wasRunning)
thread.start(middleWare);
}

void updateMiddleWare(MiddleWare* const mw) noexcept
{
middleWare = mw;
}

private:
const bool wasRunning;
MiddleWareThread& thread;
MiddleWare* middleWare;

CARLA_PREVENT_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPY_CLASS(ScopedStopper)
};

MiddleWareThread()
: CarlaThread("ZynMiddleWare"),
fMiddleWare(nullptr) {}

void start(MiddleWare* const mw) noexcept
{
fMiddleWare = mw;
startThread();
}

void stop() noexcept
{
stopThread(1000);
fMiddleWare = nullptr;
}

private:
MiddleWare* fMiddleWare;

void run() noexcept override
{
for (; ! shouldThreadExit();)
{
CARLA_SAFE_ASSERT_RETURN(fMiddleWare != nullptr,);

try {
fMiddleWare->tick();
} CARLA_SAFE_EXCEPTION("ZynAddSubFX MiddleWare tick");

carla_msleep(1);
}
}

CARLA_DECLARE_NON_COPY_CLASS(MiddleWareThread)
};

// -----------------------------------------------------------------------

class ZynAddSubFxPlugin : public NativePluginAndUiClass
{
public:
enum Parameters {
@@ -210,12 +283,12 @@ public:

ZynAddSubFxPlugin(const NativeHostDescriptor* const host)
: NativePluginAndUiClass(host, "zynaddsubfx-ui"),
CarlaThread("ZynAddSubFxPlugin"),
fMiddleWare(nullptr),
fMaster(nullptr),
fSynth(),
fIsActive(false),
fMutex()
fMutex(),
fMiddleWareThread(new MiddleWareThread())
{
sPrograms.initIfNeeded();
fConfig.init();
@@ -249,10 +322,13 @@ public:

_initMaster();
_setMasterParameters();

fMiddleWareThread->start(fMiddleWare);
}

~ZynAddSubFxPlugin() override
{
fMiddleWareThread->stop();
_deleteMaster();
}

@@ -687,19 +763,10 @@ protected:

char* getState() const override
{
char* data = nullptr;

if (fIsActive)
{
fMiddleWare->doReadOnlyOp([this, &data]{
fMaster->getalldata(&data);
});
}
else
{
fMaster->getalldata(&data);
}
const MiddleWareThread::ScopedStopper mwss(*fMiddleWareThread);

char* data = nullptr;
fMaster->getalldata(&data);
return data;
}

@@ -707,6 +774,7 @@ protected:
{
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);

const MiddleWareThread::ScopedStopper mwss(*fMiddleWareThread);
const CarlaMutexLocker cml(fMutex);

fMaster->putalldata(data);
@@ -723,6 +791,8 @@ protected:

void bufferSizeChanged(const uint32_t bufferSize) final
{
MiddleWareThread::ScopedStopper mwss(*fMiddleWareThread);

char* const state(getState());

_deleteMaster();
@@ -735,6 +805,7 @@ protected:
fSynth.alias();

_initMaster();
mwss.updateMiddleWare(fMiddleWare);

setState(state);
std::free(state);
@@ -742,6 +813,8 @@ protected:

void sampleRateChanged(const double sampleRate) final
{
MiddleWareThread::ScopedStopper mwss(*fMiddleWareThread);

char* const state(getState());

_deleteMaster();
@@ -750,6 +823,7 @@ protected:
fSynth.alias();

_initMaster();
mwss.updateMiddleWare(fMiddleWare);

setState(state);
std::free(state);
@@ -767,6 +841,7 @@ private:
float fParameters[kParamCount];

CarlaMutex fMutex;
ScopedPointer<MiddleWareThread> fMiddleWareThread;

static MidiControllers getZynControlFromIndex(const uint index)
{
@@ -810,18 +885,6 @@ private:
}
}

void run() noexcept override
{
for (; ! shouldThreadExit();)
{
try {
fMiddleWare->tick();
} CARLA_SAFE_EXCEPTION("ZynAddSubFX MiddleWare tick");

carla_msleep(1);
}
}

// -------------------------------------------------------------------

void _initMaster()
@@ -830,7 +893,6 @@ private:
fMiddleWare->setUiCallback(__uiCallback, this);
fMiddleWare->setIdleCallback(_idleCallback, this);
_masterChangedCallback(fMiddleWare->spawnMaster());
startThread();
}

void _setMasterParameters()
@@ -887,8 +949,6 @@ private:

void _deleteMaster()
{
stopThread(1000);

fMaster = nullptr;
delete fMiddleWare;
fMiddleWare = nullptr;


Loading…
Cancel
Save