@@ -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) | |||