| @@ -837,15 +837,10 @@ public: | |||
| */ | |||
| double getSampleRate() const noexcept; | |||
| /** | |||
| Get the absolute filename of the plugin binary. | |||
| Under certain systems or plugin formats the binary will be inside the plugin bundle. | |||
| */ | |||
| const char* getBinaryFilename() const noexcept; | |||
| /** | |||
| Get the bundle path where the plugin resides. | |||
| Can return null if the plugin is not available in a bundle (if it is a single binary). | |||
| @see getBinaryFilename | |||
| */ | |||
| const char* getBundlePath() const noexcept; | |||
| @@ -32,3 +32,10 @@ | |||
| #else | |||
| # error unsupported format | |||
| #endif | |||
| #if defined(DISTRHO_PLUGIN_TARGET_JACK) | |||
| # define DISTRHO_IS_STANDALONE 1 | |||
| #else | |||
| # define DISTRHO_IS_STANDALONE 0 | |||
| #endif | |||
| #include "src/DistrhoUtils.cpp" | |||
| @@ -22,7 +22,14 @@ | |||
| START_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| // misc functions | |||
| // plugin related utilities | |||
| /** | |||
| Get the absolute filename of the plugin DSP/UI binary.@n | |||
| Under certain systems or plugin formats the binary will be inside the plugin bundle.@n | |||
| Also, in some formats or setups, the DSP and UI binaries are in different files. | |||
| */ | |||
| const char* getBinaryFilename(); | |||
| /** | |||
| Get a string representation of the current plugin format we are building against.@n | |||
| @@ -131,16 +131,10 @@ public: | |||
| */ | |||
| double getSampleRate() const noexcept; | |||
| /** | |||
| Get the absolute filename of the UI binary.@n | |||
| Under certain systems or plugin formats the binary will be inside the plugin bundle.@n | |||
| Also, in some formats or setups, this file might not be the same as the DSP/plugin side (because of DSP/UI separation). | |||
| */ | |||
| const char* getBinaryFilename() const noexcept; | |||
| /** | |||
| Get the bundle path where the UI resides.@n | |||
| Can return null if the UI is not available in a bundle (if it is a single binary). | |||
| @see getBinaryFilename | |||
| */ | |||
| const char* getBundlePath() const noexcept; | |||
| @@ -31,3 +31,12 @@ | |||
| #else | |||
| # error unsupported format | |||
| #endif | |||
| #if !DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
| # if defined(DISTRHO_PLUGIN_TARGET_JACK) || defined(DISTRHO_PLUGIN_TARGET_DSSI) | |||
| # define DISTRHO_IS_STANDALONE 1 | |||
| # else | |||
| # define DISTRHO_IS_STANDALONE 0 | |||
| # endif | |||
| # include "src/DistrhoUtils.cpp" | |||
| #endif | |||
| @@ -21,9 +21,10 @@ START_NAMESPACE_DISTRHO | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Static data, see DistrhoPluginInternal.hpp */ | |||
| uint32_t d_lastBufferSize = 0; | |||
| double d_lastSampleRate = 0.0; | |||
| bool d_lastCanRequestParameterValueChanges = false; | |||
| uint32_t d_nextBufferSize = 0; | |||
| double d_nextSampleRate = 0.0; | |||
| const char* d_nextBundlePath = nullptr; | |||
| bool d_nextCanRequestParameterValueChanges = false; | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Static fallback data, see DistrhoPluginInternal.hpp */ | |||
| @@ -100,11 +101,6 @@ double Plugin::getSampleRate() const noexcept | |||
| return pData->sampleRate; | |||
| } | |||
| const char* Plugin::getBinaryFilename() const noexcept | |||
| { | |||
| return pData->binaryFilename; | |||
| } | |||
| const char* Plugin::getBundlePath() const noexcept | |||
| { | |||
| return pData->bundlePath; | |||
| @@ -31,9 +31,10 @@ static const uint32_t kMaxMidiEvents = 512; | |||
| // ----------------------------------------------------------------------- | |||
| // Static data, see DistrhoPlugin.cpp | |||
| extern uint32_t d_lastBufferSize; | |||
| extern double d_lastSampleRate; | |||
| extern bool d_lastCanRequestParameterValueChanges; | |||
| extern uint32_t d_nextBufferSize; | |||
| extern double d_nextSampleRate; | |||
| extern const char* d_nextBundlePath; | |||
| extern bool d_nextCanRequestParameterValueChanges; | |||
| // ----------------------------------------------------------------------- | |||
| // DSP callbacks | |||
| @@ -122,7 +123,6 @@ struct Plugin::PrivateData { | |||
| uint32_t bufferSize; | |||
| double sampleRate; | |||
| char* binaryFilename; | |||
| char* bundlePath; | |||
| bool canRequestParameterValueChanges; | |||
| @@ -151,11 +151,10 @@ struct Plugin::PrivateData { | |||
| callbacksPtr(nullptr), | |||
| writeMidiCallbackFunc(nullptr), | |||
| requestParameterValueChangeCallbackFunc(nullptr), | |||
| bufferSize(d_lastBufferSize), | |||
| sampleRate(d_lastSampleRate), | |||
| binaryFilename(nullptr), | |||
| bundlePath(nullptr), | |||
| canRequestParameterValueChanges(d_lastCanRequestParameterValueChanges) | |||
| bufferSize(d_nextBufferSize), | |||
| sampleRate(d_nextSampleRate), | |||
| bundlePath(d_nextBundlePath != nullptr ? strdup(d_nextBundlePath) : nullptr), | |||
| canRequestParameterValueChanges(d_nextCanRequestParameterValueChanges) | |||
| { | |||
| DISTRHO_SAFE_ASSERT(bufferSize != 0); | |||
| DISTRHO_SAFE_ASSERT(d_isNotZero(sampleRate)); | |||
| @@ -230,12 +229,6 @@ struct Plugin::PrivateData { | |||
| } | |||
| #endif | |||
| if (binaryFilename != nullptr) | |||
| { | |||
| std::free(binaryFilename); | |||
| binaryFilename = nullptr; | |||
| } | |||
| if (bundlePath != nullptr) | |||
| { | |||
| std::free(bundlePath); | |||
| @@ -115,7 +115,7 @@ public: | |||
| #if DISTRHO_PLUGIN_HAS_UI | |||
| fUI(this, | |||
| 0, // winId | |||
| d_lastSampleRate, | |||
| d_nextSampleRate, | |||
| nullptr, // edit param | |||
| setParameterValueCallback, | |||
| setStateCallback, | |||
| @@ -804,9 +804,9 @@ int main() | |||
| initSignalHandler(); | |||
| d_lastBufferSize = jackbridge_get_buffer_size(client); | |||
| d_lastSampleRate = jackbridge_get_sample_rate(client); | |||
| d_lastCanRequestParameterValueChanges = true; | |||
| d_nextBufferSize = jackbridge_get_buffer_size(client); | |||
| d_nextSampleRate = jackbridge_get_sample_rate(client); | |||
| d_nextCanRequestParameterValueChanges = true; | |||
| const PluginJack p(client); | |||
| @@ -418,9 +418,9 @@ private: | |||
| static LADSPA_Handle ladspa_instantiate(const LADSPA_Descriptor*, ulong sampleRate) | |||
| { | |||
| if (d_lastBufferSize == 0) | |||
| d_lastBufferSize = 2048; | |||
| d_lastSampleRate = sampleRate; | |||
| if (d_nextBufferSize == 0) | |||
| d_nextBufferSize = 2048; | |||
| d_nextSampleRate = sampleRate; | |||
| return new PluginLadspaDssi(); | |||
| } | |||
| @@ -551,11 +551,11 @@ static const struct DescriptorInitializer | |||
| DescriptorInitializer() | |||
| { | |||
| // Create dummy plugin to get data from | |||
| d_lastBufferSize = 512; | |||
| d_lastSampleRate = 44100.0; | |||
| d_nextBufferSize = 512; | |||
| d_nextSampleRate = 44100.0; | |||
| const PluginExporter plugin(nullptr, nullptr, nullptr); | |||
| d_lastBufferSize = 0; | |||
| d_lastSampleRate = 0.0; | |||
| d_nextBufferSize = 0; | |||
| d_nextSampleRate = 0.0; | |||
| // Get port count, init | |||
| ulong port = 0; | |||
| @@ -1296,7 +1296,7 @@ private: | |||
| // ----------------------------------------------------------------------- | |||
| static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, const char*, const LV2_Feature* const* features) | |||
| static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, const char* bundlePath, const LV2_Feature* const* features) | |||
| { | |||
| const LV2_Options_Option* options = nullptr; | |||
| const LV2_URID_Map* uridMap = nullptr; | |||
| @@ -1339,7 +1339,7 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, cons | |||
| mod_license_check(features, DISTRHO_PLUGIN_URI); | |||
| #endif | |||
| d_lastBufferSize = 0; | |||
| d_nextBufferSize = 0; | |||
| bool usingNominal = false; | |||
| for (int i=0; options[i].key != 0; ++i) | |||
| @@ -1348,7 +1348,7 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, cons | |||
| { | |||
| if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Int)) | |||
| { | |||
| d_lastBufferSize = *(const int*)options[i].value; | |||
| d_nextBufferSize = *(const int*)options[i].value; | |||
| usingNominal = true; | |||
| } | |||
| else | |||
| @@ -1361,7 +1361,7 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, cons | |||
| if (options[i].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__maxBlockLength)) | |||
| { | |||
| if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Int)) | |||
| d_lastBufferSize = *(const int*)options[i].value; | |||
| d_nextBufferSize = *(const int*)options[i].value; | |||
| else | |||
| d_stderr("Host provides maxBlockLength but has wrong value type"); | |||
| @@ -1369,14 +1369,15 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, cons | |||
| } | |||
| } | |||
| if (d_lastBufferSize == 0) | |||
| if (d_nextBufferSize == 0) | |||
| { | |||
| d_stderr("Host does not provide nominalBlockLength or maxBlockLength options"); | |||
| d_lastBufferSize = 2048; | |||
| d_nextBufferSize = 2048; | |||
| } | |||
| d_lastSampleRate = sampleRate; | |||
| d_lastCanRequestParameterValueChanges = ctrlInPortChangeReq != nullptr; | |||
| d_nextSampleRate = sampleRate; | |||
| d_nextBundlePath = bundlePath; | |||
| d_nextCanRequestParameterValueChanges = ctrlInPortChangeReq != nullptr; | |||
| return new PluginLv2(sampleRate, uridMap, worker, ctrlInPortChangeReq, usingNominal); | |||
| } | |||
| @@ -224,11 +224,11 @@ void lv2_generate_ttl(const char* const basename) | |||
| USE_NAMESPACE_DISTRHO | |||
| // Dummy plugin to get data from | |||
| d_lastBufferSize = 512; | |||
| d_lastSampleRate = 44100.0; | |||
| d_nextBufferSize = 512; | |||
| d_nextSampleRate = 44100.0; | |||
| PluginExporter plugin(nullptr, nullptr, nullptr); | |||
| d_lastBufferSize = 0; | |||
| d_lastSampleRate = 0.0; | |||
| d_nextBufferSize = 0; | |||
| d_nextSampleRate = 0.0; | |||
| const String pluginDLL(basename); | |||
| const String pluginTTL(pluginDLL + ".ttl"); | |||
| @@ -1403,9 +1403,9 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||
| if (doInternalInit) | |||
| { | |||
| // set valid but dummy values | |||
| d_lastBufferSize = 512; | |||
| d_lastSampleRate = 44100.0; | |||
| d_lastCanRequestParameterValueChanges = true; | |||
| d_nextBufferSize = 512; | |||
| d_nextSampleRate = 44100.0; | |||
| d_nextCanRequestParameterValueChanges = true; | |||
| } | |||
| // Create dummy plugin to get data from | |||
| @@ -1414,9 +1414,9 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||
| if (doInternalInit) | |||
| { | |||
| // unset | |||
| d_lastBufferSize = 0; | |||
| d_lastSampleRate = 0.0; | |||
| d_lastCanRequestParameterValueChanges = false; | |||
| d_nextBufferSize = 0; | |||
| d_nextSampleRate = 0.0; | |||
| d_nextCanRequestParameterValueChanges = false; | |||
| *(PluginExporter**)ptr = &plugin; | |||
| return 0; | |||
| @@ -1437,15 +1437,15 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||
| audioMasterCallback audioMaster = (audioMasterCallback)obj->audioMaster; | |||
| d_lastBufferSize = audioMaster(effect, audioMasterGetBlockSize, 0, 0, nullptr, 0.0f); | |||
| d_lastSampleRate = audioMaster(effect, audioMasterGetSampleRate, 0, 0, nullptr, 0.0f); | |||
| d_lastCanRequestParameterValueChanges = true; | |||
| d_nextBufferSize = audioMaster(effect, audioMasterGetBlockSize, 0, 0, nullptr, 0.0f); | |||
| d_nextSampleRate = audioMaster(effect, audioMasterGetSampleRate, 0, 0, nullptr, 0.0f); | |||
| d_nextCanRequestParameterValueChanges = true; | |||
| // some hosts are not ready at this point or return 0 buffersize/samplerate | |||
| if (d_lastBufferSize == 0) | |||
| d_lastBufferSize = 2048; | |||
| if (d_lastSampleRate <= 0.0) | |||
| d_lastSampleRate = 44100.0; | |||
| if (d_nextBufferSize == 0) | |||
| d_nextBufferSize = 2048; | |||
| if (d_nextSampleRate <= 0.0) | |||
| d_nextSampleRate = 44100.0; | |||
| obj->plugin = new PluginVst(audioMaster, effect); | |||
| return 1; | |||
| @@ -3094,8 +3094,8 @@ struct dpf_audio_processor : v3_audio_processor_cpp { | |||
| PluginVst3* const vst3 = processor->vst3; | |||
| DISTRHO_SAFE_ASSERT_RETURN(vst3 != nullptr, V3_NOT_INITIALIZED); | |||
| d_lastBufferSize = setup->max_block_size; | |||
| d_lastSampleRate = setup->sample_rate; | |||
| d_nextBufferSize = setup->max_block_size; | |||
| d_nextSampleRate = setup->sample_rate; | |||
| return processor->vst3->setupProcessing(setup); | |||
| } | |||
| @@ -3389,12 +3389,12 @@ struct dpf_component : v3_component_cpp { | |||
| host = component->hostContextFromFactory; | |||
| // default early values | |||
| if (d_lastBufferSize == 0) | |||
| d_lastBufferSize = 2048; | |||
| if (d_lastSampleRate <= 0.0) | |||
| d_lastSampleRate = 44100.0; | |||
| if (d_nextBufferSize == 0) | |||
| d_nextBufferSize = 2048; | |||
| if (d_nextSampleRate <= 0.0) | |||
| d_nextSampleRate = 44100.0; | |||
| d_lastCanRequestParameterValueChanges = true; | |||
| d_nextCanRequestParameterValueChanges = true; | |||
| component->vst3 = new PluginVst3(host); | |||
| return V3_OK; | |||
| @@ -3541,13 +3541,13 @@ struct dpf_component : v3_component_cpp { | |||
| static const PluginExporter& _getPluginInfo() | |||
| { | |||
| d_lastBufferSize = 512; | |||
| d_lastSampleRate = 44100.0; | |||
| d_lastCanRequestParameterValueChanges = true; | |||
| d_nextBufferSize = 512; | |||
| d_nextSampleRate = 44100.0; | |||
| d_nextCanRequestParameterValueChanges = true; | |||
| static const PluginExporter gPluginInfo(nullptr, nullptr, nullptr); | |||
| d_lastBufferSize = 0; | |||
| d_lastSampleRate = 0.0; | |||
| d_lastCanRequestParameterValueChanges = false; | |||
| d_nextBufferSize = 0; | |||
| d_nextSampleRate = 0.0; | |||
| d_nextCanRequestParameterValueChanges = false; | |||
| return gPluginInfo; | |||
| } | |||
| @@ -32,14 +32,16 @@ | |||
| START_NAMESPACE_DISTRHO | |||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Static data, see DistrhoUIInternal.hpp */ | |||
| const char* g_nextBundlePath = nullptr; | |||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| uintptr_t g_nextWindowId = 0; | |||
| double g_nextScaleFactor = 1.0; | |||
| const char* g_nextBundlePath = nullptr; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * get global scale factor */ | |||
| @@ -217,11 +219,6 @@ double UI::getSampleRate() const noexcept | |||
| return uiData->sampleRate; | |||
| } | |||
| const char* UI::getBinaryFilename() const noexcept | |||
| { | |||
| return uiData->binaryFilename; | |||
| } | |||
| const char* UI::getBundlePath() const noexcept | |||
| { | |||
| return uiData->bundlePath; | |||
| @@ -270,7 +267,7 @@ void* UI::getPluginInstancePointer() const noexcept | |||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * External UI helpers */ | |||
| * External UI helpers (static calls) */ | |||
| const char* UI::getNextBundlePath() noexcept | |||
| { | |||
| @@ -24,10 +24,10 @@ START_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| // Static data, see DistrhoUI.cpp | |||
| extern const char* g_nextBundlePath; | |||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| extern uintptr_t g_nextWindowId; | |||
| extern double g_nextScaleFactor; | |||
| extern const char* g_nextBundlePath; | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| @@ -77,19 +77,19 @@ public: | |||
| uiData->setSizeCallbackFunc = setSizeCall; | |||
| uiData->fileRequestCallbackFunc = fileRequestCall; | |||
| g_nextBundlePath = bundlePath; | |||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| g_nextWindowId = winId; | |||
| g_nextScaleFactor = scaleFactor; | |||
| g_nextBundlePath = bundlePath; | |||
| #endif | |||
| UI::PrivateData::s_nextPrivateData = uiData; | |||
| UI* const uiPtr = createUI(); | |||
| g_nextBundlePath = nullptr; | |||
| #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| g_nextWindowId = 0; | |||
| g_nextScaleFactor = 0.0; | |||
| g_nextBundlePath = nullptr; | |||
| #else | |||
| // enter context called in the PluginWindow constructor, see DistrhoUIPrivateData.hpp | |||
| uiData->window->leaveContext(); | |||
| @@ -308,7 +308,6 @@ struct UI::PrivateData { | |||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI && !defined(DGL_FILE_BROWSER_DISABLED) | |||
| char* uiStateFileKeyRequest; | |||
| #endif | |||
| char* binaryFilename; | |||
| char* bundlePath; | |||
| // Callbacks | |||
| @@ -333,7 +332,6 @@ struct UI::PrivateData { | |||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI && !defined(DGL_FILE_BROWSER_DISABLED) | |||
| uiStateFileKeyRequest(nullptr), | |||
| #endif | |||
| binaryFilename(nullptr), | |||
| bundlePath(nullptr), | |||
| callbacksPtr(nullptr), | |||
| editParamCallbackFunc(nullptr), | |||
| @@ -374,7 +372,6 @@ struct UI::PrivateData { | |||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI && !defined(DGL_FILE_BROWSER_DISABLED) | |||
| std::free(uiStateFileKeyRequest); | |||
| #endif | |||
| std::free(binaryFilename); | |||
| std::free(bundlePath); | |||
| } | |||
| @@ -14,6 +14,28 @@ | |||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| */ | |||
| #ifndef DISTRHO_IS_STANDALONE | |||
| # error Wrong build configuration | |||
| #endif | |||
| #include "extra/String.hpp" | |||
| #ifndef DISTRHO_OS_WINDOWS | |||
| # include <dlfcn.h> | |||
| #endif | |||
| #if defined(DISTRHO_OS_WINDOWS) && !DISTRHO_IS_STANDALONE | |||
| static HINSTANCE hInstance = nullptr; | |||
| DISTRHO_PLUGIN_EXPORT | |||
| BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) | |||
| { | |||
| if (reason == DLL_PROCESS_ATTACH) | |||
| hInstance = hInst; | |||
| return 1; | |||
| } | |||
| #endif | |||
| START_NAMESPACE_DISTRHO | |||
| #ifdef DISTRHO_PLUGIN_TARGET_JACK | |||
| @@ -21,6 +43,31 @@ START_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| const char* getBinaryFilename() | |||
| { | |||
| static String filename; | |||
| if (filename.isNotEmpty()) | |||
| return filename; | |||
| #ifdef DISTRHO_OS_WINDOWS | |||
| # if DISTRHO_IS_STANDALONE | |||
| // TODO | |||
| # else | |||
| CHAR filenameBuf[MAX_PATH + 256]; | |||
| filenameBuf[0] = '\0'; | |||
| GetModuleFileName(hInstance, filenameBuf, sizeof(filenameBuf)); | |||
| filename = filenameBuf; | |||
| # endif | |||
| #else | |||
| Dl_info info; | |||
| dladdr((void*)getBinaryFilename, &info); | |||
| filename = info.dli_fname; | |||
| #endif | |||
| return filename; | |||
| } | |||
| const char* getPluginFormatName() noexcept | |||
| { | |||
| #if defined(DISTRHO_PLUGIN_TARGET_CARLA) | |||