From 9f8839e90744070390574b5bd2d03925117a855b Mon Sep 17 00:00:00 2001 From: falkTX Date: Thu, 4 Apr 2013 16:42:41 +0100 Subject: [PATCH] Small Native API rework, fix zynaddsubfx state --- source/backend/CarlaNative.h | 8 +- source/backend/CarlaNative.hpp | 29 +++--- source/backend/native/audiofile.c | 4 +- source/backend/native/bypass.c | 4 +- source/backend/native/lfo.c | 4 +- source/backend/native/midi-split.c | 4 +- source/backend/native/midi-through.c | 4 +- source/backend/native/midi-transpose.c | 4 +- source/backend/native/nekofilter.c | 4 +- source/backend/native/zynaddsubfx.cpp | 18 ++-- source/backend/plugin/NativePlugin.cpp | 119 ++++++++++--------------- 11 files changed, 92 insertions(+), 110 deletions(-) diff --git a/source/backend/CarlaNative.h b/source/backend/CarlaNative.h index 6b629cb84..ffba51b2e 100644 --- a/source/backend/CarlaNative.h +++ b/source/backend/CarlaNative.h @@ -55,8 +55,8 @@ typedef enum _PluginHints { PLUGIN_IS_RTSAFE = 1 << 0, PLUGIN_IS_SYNTH = 1 << 1, PLUGIN_HAS_GUI = 1 << 2, - PLUGIN_USES_CHUNKS = 1 << 3, - PLUGIN_USES_SINGLE_THREAD = 1 << 4 + PLUGIN_USES_SINGLE_THREAD = 1 << 3, + PLUGIN_USES_STATE = 1 << 4 } PluginHints; typedef enum _ParameterHints { @@ -192,8 +192,8 @@ typedef struct _PluginDescriptor { void (*deactivate)(PluginHandle handle); void (*process)(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents); - size_t (*get_chunk)(PluginHandle handle, void** data); - void (*set_chunk)(PluginHandle handle, void* data, size_t size); + char* (*get_state)(PluginHandle handle); + void (*set_state)(PluginHandle handle, const char* data); } PluginDescriptor; diff --git a/source/backend/CarlaNative.hpp b/source/backend/CarlaNative.hpp index 29b01cc08..25f5ea102 100644 --- a/source/backend/CarlaNative.hpp +++ b/source/backend/CarlaNative.hpp @@ -281,21 +281,20 @@ protected: } // ------------------------------------------------------------------- - // Plugin chunk calls + // Plugin state calls - virtual size_t getChunk(void** const data) + virtual char* getState() { - CARLA_ASSERT(data != nullptr); - return 0; - - // unused - (void)data; + return nullptr; } - virtual void setChunk(void* const data, const size_t size) + virtual void setState(const char* const data) { CARLA_ASSERT(data != nullptr); - CARLA_ASSERT(size > 0); + return; + + // unused + (void)data; } // ------------------------------------------------------------------- @@ -394,14 +393,14 @@ public: return handlePtr->process(inBuffer, outBuffer, frames, midiEventCount, midiEvents); } - static size_t _get_chunk(PluginHandle handle, void** data) + static char* _get_state(PluginHandle handle) { - return handlePtr->getChunk(data); + return handlePtr->getState(); } - static void _set_chunk(PluginHandle handle, void* data, size_t size) + static void _set_state(PluginHandle handle, const char* data) { - handlePtr->setChunk(data, size); + handlePtr->setState(data); } #undef handlePtr @@ -445,7 +444,7 @@ public: className::_activate, \ className::_deactivate, \ className::_process, \ - className::_get_chunk, \ - className::_set_chunk + className::_get_state, \ + className::_set_state #endif // __CARLA_NATIVE_HPP__ diff --git a/source/backend/native/audiofile.c b/source/backend/native/audiofile.c index 806a15209..627277f07 100644 --- a/source/backend/native/audiofile.c +++ b/source/backend/native/audiofile.c @@ -665,8 +665,8 @@ static const PluginDescriptor audiofileDesc = { .deactivate = NULL, .process = audiofile_process, - .get_chunk = NULL, - .set_chunk = NULL + .get_state = NULL, + .set_state = NULL }; // ----------------------------------------------------------------------- diff --git a/source/backend/native/bypass.c b/source/backend/native/bypass.c index 30157a2e6..f1daab632 100644 --- a/source/backend/native/bypass.c +++ b/source/backend/native/bypass.c @@ -85,8 +85,8 @@ static const PluginDescriptor bypassDesc = { .deactivate = NULL, .process = bypass_process, - .get_chunk = NULL, - .set_chunk = NULL + .get_state = NULL, + .set_state = NULL }; // ----------------------------------------------------------------------- diff --git a/source/backend/native/lfo.c b/source/backend/native/lfo.c index 139a07c2e..1143f2ce0 100644 --- a/source/backend/native/lfo.c +++ b/source/backend/native/lfo.c @@ -295,8 +295,8 @@ static const PluginDescriptor lfoDesc = { .deactivate = NULL, .process = lfo_process, - .get_chunk = NULL, - .set_chunk = NULL + .get_state = NULL, + .set_state = NULL }; // ----------------------------------------------------------------------- diff --git a/source/backend/native/midi-split.c b/source/backend/native/midi-split.c index 956261c27..80e9343ff 100644 --- a/source/backend/native/midi-split.c +++ b/source/backend/native/midi-split.c @@ -121,8 +121,8 @@ static const PluginDescriptor midiSplitDesc = { .deactivate = NULL, .process = midiSplit_process, - .get_chunk = NULL, - .set_chunk = NULL + .get_state = NULL, + .set_state = NULL }; // ----------------------------------------------------------------------- diff --git a/source/backend/native/midi-through.c b/source/backend/native/midi-through.c index 04e61e78a..1586e7aa3 100644 --- a/source/backend/native/midi-through.c +++ b/source/backend/native/midi-through.c @@ -102,8 +102,8 @@ static const PluginDescriptor midiThroughDesc = { .deactivate = NULL, .process = midiThrough_process, - .get_chunk = NULL, - .set_chunk = NULL + .get_state = NULL, + .set_state = NULL }; // ----------------------------------------------------------------------- diff --git a/source/backend/native/midi-transpose.c b/source/backend/native/midi-transpose.c index 38eba795a..deda0ebeb 100644 --- a/source/backend/native/midi-transpose.c +++ b/source/backend/native/midi-transpose.c @@ -184,8 +184,8 @@ static const PluginDescriptor midiTransposeDesc = { .deactivate = NULL, .process = midiTranspose_process, - .get_chunk = NULL, - .set_chunk = NULL + .get_state = NULL, + .set_state = NULL }; // ----------------------------------------------------------------------- diff --git a/source/backend/native/nekofilter.c b/source/backend/native/nekofilter.c index a5101acb7..8e3538330 100644 --- a/source/backend/native/nekofilter.c +++ b/source/backend/native/nekofilter.c @@ -64,8 +64,8 @@ static const PluginDescriptor nekofilterDesc = { .deactivate = NULL, .process = nekofilter_process, - .get_chunk = NULL, - .set_chunk = NULL + .get_state = NULL, + .set_state = NULL }; // ----------------------------------------------------------------------- diff --git a/source/backend/native/zynaddsubfx.cpp b/source/backend/native/zynaddsubfx.cpp index 9173c1a36..c687bf7dd 100644 --- a/source/backend/native/zynaddsubfx.cpp +++ b/source/backend/native/zynaddsubfx.cpp @@ -105,6 +105,7 @@ public: pthread_mutex_lock(&kMaster->mutex); pthread_mutex_unlock(&kMaster->mutex); fThread.stop(); + fThread.wait(); delete kMaster; } @@ -289,18 +290,21 @@ protected: #endif // ------------------------------------------------------------------- - // Plugin chunk calls + // Plugin state calls - size_t getChunk(void** const data) + char* getState() { config.save(); - return kMaster->getalldata((char**)data); + + char* data = nullptr; + kMaster->getalldata(&data); + return data; } - void setChunk(void* const data, const size_t size) + void setState(const char* const data) { fThread.stopLoadLater(); - kMaster->putalldata((char*)data, size); + kMaster->putalldata((char*)data, 0); kMaster->applyparameters(true); } @@ -655,9 +659,9 @@ struct ProgramsDestructor { static const PluginDescriptor zynAddSubFxDesc = { /* category */ PLUGIN_CATEGORY_SYNTH, #ifdef WANT_ZYNADDSUBFX_UI - /* hints */ static_cast(PLUGIN_IS_SYNTH | PLUGIN_HAS_GUI | PLUGIN_USES_CHUNKS | PLUGIN_USES_SINGLE_THREAD), + /* hints */ static_cast(PLUGIN_IS_SYNTH|PLUGIN_HAS_GUI/*|PLUGIN_USES_SINGLE_THREAD*/|PLUGIN_USES_STATE), #else - /* hints */ static_cast(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS), + /* hints */ static_cast(PLUGIN_IS_SYNTH|PLUGIN_USES_STATE), #endif /* audioIns */ 2, /* audioOuts */ 2, diff --git a/source/backend/plugin/NativePlugin.cpp b/source/backend/plugin/NativePlugin.cpp index ac84db627..677ff4edb 100644 --- a/source/backend/plugin/NativePlugin.cpp +++ b/source/backend/plugin/NativePlugin.cpp @@ -265,24 +265,6 @@ public: return 0; } - // ------------------------------------------------------------------- - // Information (current data) - - int32_t chunkData(void** const dataPtr) - { - CARLA_ASSERT(fOptions & PLUGIN_OPTION_USE_CHUNKS); - CARLA_ASSERT(fDescriptor != nullptr); - CARLA_ASSERT(fDescriptor->get_chunk != nullptr); - CARLA_ASSERT(fHandle != nullptr); - CARLA_ASSERT(fHandle2 == nullptr); - CARLA_ASSERT(dataPtr != nullptr); - - if (fDescriptor->get_chunk != nullptr) - return fDescriptor->get_chunk(fHandle, dataPtr); - - return 0; - } - // ------------------------------------------------------------------- // Information (per-plugin data) @@ -298,9 +280,6 @@ public: options |= PLUGIN_OPTION_FIXED_BUFFER; options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES; - if (fDescriptor->hints & ::PLUGIN_USES_CHUNKS) - options |= PLUGIN_OPTION_USE_CHUNKS; - if (kData->engine->getProccessMode() != PROCESS_MODE_CONTINUOUS_RACK) { if (fOptions & PLUGIN_OPTION_FORCE_STEREO) @@ -475,6 +454,26 @@ public: CarlaPlugin::getParameterScalePointLabel(parameterId, scalePointId, strBuf); } + // ------------------------------------------------------------------- + // Set data (state) + + void prepareForSave() + { + CARLA_ASSERT(fDescriptor != nullptr); + CARLA_ASSERT(fHandle != nullptr); + + if (fDescriptor->get_state == nullptr) + return; + if ((fDescriptor->hints & ::PLUGIN_USES_STATE) == 0) + return; + + if (char* data = fDescriptor->get_state(fHandle)) + { + CarlaPlugin::setCustomData(CUSTOM_DATA_CHUNK, "State", data, false); + std::free(data); + } + } + // ------------------------------------------------------------------- // Set data (plugin-specific stuff) @@ -507,10 +506,10 @@ public: carla_debug("DssiPlugin::setCustomData(%s, %s, %s, %s)", type, key, value, bool2str(sendGui)); if (type == nullptr) - return carla_stderr2("NativePlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is not string", type, key, value, bool2str(sendGui)); + return carla_stderr2("NativePlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is null", type, key, value, bool2str(sendGui)); - if (std::strcmp(type, CUSTOM_DATA_STRING) != 0) - return carla_stderr2("NativePlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is not string", type, key, value, bool2str(sendGui)); + if (std::strcmp(type, CUSTOM_DATA_STRING) != 0 && std::strcmp(type, CUSTOM_DATA_CHUNK) != 0) + return carla_stderr2("NativePlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is invalid", type, key, value, bool2str(sendGui)); if (key == nullptr) return carla_stderr2("NativePlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - key is null", type, key, value, bool2str(sendGui)); @@ -518,54 +517,39 @@ public: if (value == nullptr) return carla_stderr2("Nativelugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - value is null", type, key, value, bool2str(sendGui)); - if (fDescriptor->set_custom_data != nullptr) + if (std::strcmp(type, CUSTOM_DATA_CHUNK) == 0) { - fDescriptor->set_custom_data(fHandle, key, value); - - if (fHandle2 != nullptr) - fDescriptor->set_custom_data(fHandle2, key, value); - } + if (fDescriptor->set_state != nullptr && (fDescriptor->hints & ::PLUGIN_USES_STATE) != 0) + { + const ScopedSingleProcessLocker spl(this, true); - if (sendGui && fIsUiVisible && fDescriptor->ui_set_custom_data != nullptr) - fDescriptor->ui_set_custom_data(fHandle, key, value); + fDescriptor->set_state(fHandle, value); - if (std::strlen(key) == 6 && std::strncmp(key, "file", 4) == 0) - { - const ScopedDisabler sd(this); - reloadPrograms(false); + if (fHandle2 != nullptr) + fDescriptor->set_state(fHandle2, value); + } } - - CarlaPlugin::setCustomData(type, key, value, sendGui); - } - - void setChunkData(const char* const stringData) - { - CARLA_ASSERT(fOptions & PLUGIN_OPTION_USE_CHUNKS); - CARLA_ASSERT(fDescriptor != nullptr); - CARLA_ASSERT(fDescriptor->set_chunk != nullptr); - CARLA_ASSERT(fHandle != nullptr); - CARLA_ASSERT(fHandle2 == nullptr); - CARLA_ASSERT(stringData != nullptr); - - if (fDescriptor->set_chunk == nullptr) - return; - - if (fLastChunk != nullptr) + else { - delete[] fLastChunk; - fLastChunk = nullptr; - } + if (fDescriptor->set_custom_data != nullptr) + { + fDescriptor->set_custom_data(fHandle, key, value); - const size_t size(CarlaString(stringData).exportAsBase64Binary(&fLastChunk)); + if (fHandle2 != nullptr) + fDescriptor->set_custom_data(fHandle2, key, value); + } - CARLA_ASSERT(size > 0); - CARLA_ASSERT(fLastChunk != nullptr); + if (sendGui && fIsUiVisible && fDescriptor->ui_set_custom_data != nullptr) + fDescriptor->ui_set_custom_data(fHandle, key, value); - if (size > 0 && fLastChunk != nullptr) - { - const ScopedSingleProcessLocker spl(this, true); - fDescriptor->set_chunk(fHandle, fLastChunk, size); + if (std::strlen(key) == 6 && std::strncmp(key, "file", 4) == 0) + { + const ScopedDisabler sd(this); + reloadPrograms(false); + } } + + CarlaPlugin::setCustomData(type, key, value, sendGui); } void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) @@ -618,9 +602,8 @@ public: { const CustomData& cData(*it); - CARLA_ASSERT(std::strcmp(cData.type, CUSTOM_DATA_STRING) == 0); - - fDescriptor->ui_set_custom_data(fHandle, cData.key, cData.value); + if (std::strcmp(cData.type, CUSTOM_DATA_STRING) == 0) + fDescriptor->ui_set_custom_data(fHandle, cData.key, cData.value); } } @@ -2100,9 +2083,6 @@ public: if (kData->engine->getOptions().forceStereo) fOptions |= PLUGIN_OPTION_FORCE_STEREO; - if (fDescriptor->hints & ::PLUGIN_USES_CHUNKS) - fOptions |= PLUGIN_OPTION_USE_CHUNKS; - if (fDescriptor->midiIns > 0) { fOptions |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE; @@ -2143,7 +2123,6 @@ private: bool fIsProcessing; bool fIsUiVisible; - QByteArray fChunk; float** fAudioInBuffers; float** fAudioOutBuffers; uint8_t* fLastChunk;