Browse Source

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

tags/1.9.7
falkTX 9 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::roundToIntAccurate;
using juce::FloatVectorOperations; using juce::FloatVectorOperations;
using juce::ScopedPointer;


// #define ZYN_MSG_ANYWHERE // #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: public:
enum Parameters { enum Parameters {
@@ -210,12 +283,12 @@ public:


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


_initMaster(); _initMaster();
_setMasterParameters(); _setMasterParameters();

fMiddleWareThread->start(fMiddleWare);
} }


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


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


char* getState() const override 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; return data;
} }


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


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


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


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

char* const state(getState()); char* const state(getState());


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


_initMaster(); _initMaster();
mwss.updateMiddleWare(fMiddleWare);


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


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

char* const state(getState()); char* const state(getState());


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


_initMaster(); _initMaster();
mwss.updateMiddleWare(fMiddleWare);


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


CarlaMutex fMutex; CarlaMutex fMutex;
ScopedPointer<MiddleWareThread> fMiddleWareThread;


static MidiControllers getZynControlFromIndex(const uint index) 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() void _initMaster()
@@ -830,7 +893,6 @@ private:
fMiddleWare->setUiCallback(__uiCallback, this); fMiddleWare->setUiCallback(__uiCallback, this);
fMiddleWare->setIdleCallback(_idleCallback, this); fMiddleWare->setIdleCallback(_idleCallback, this);
_masterChangedCallback(fMiddleWare->spawnMaster()); _masterChangedCallback(fMiddleWare->spawnMaster());
startThread();
} }


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


void _deleteMaster() void _deleteMaster()
{ {
stopThread(1000);

fMaster = nullptr; fMaster = nullptr;
delete fMiddleWare; delete fMiddleWare;
fMiddleWare = nullptr; fMiddleWare = nullptr;


Loading…
Cancel
Save