DISTRHO Plugin Framework
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

708 lines
20KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #ifndef DISTRHO_PLUGIN_INTERNAL_HPP_INCLUDED
  17. #define DISTRHO_PLUGIN_INTERNAL_HPP_INCLUDED
  18. #include "../DistrhoPlugin.hpp"
  19. START_NAMESPACE_DISTRHO
  20. // -----------------------------------------------------------------------
  21. // Maxmimum values
  22. static const uint32_t kMaxMidiEvents = 512;
  23. // -----------------------------------------------------------------------
  24. // Static data, see DistrhoPlugin.cpp
  25. extern uint32_t d_lastBufferSize;
  26. extern double d_lastSampleRate;
  27. extern bool d_lastCanRequestParameterValueChanges;
  28. // -----------------------------------------------------------------------
  29. // DSP callbacks
  30. typedef bool (*writeMidiFunc) (void* ptr, const MidiEvent& midiEvent);
  31. typedef bool (*requestParameterValueChangeFunc) (void* ptr, uint32_t index, float value);
  32. // -----------------------------------------------------------------------
  33. // Plugin private data
  34. struct Plugin::PrivateData {
  35. bool isProcessing;
  36. #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
  37. AudioPort* audioPorts;
  38. #endif
  39. uint32_t parameterCount;
  40. uint32_t parameterOffset;
  41. Parameter* parameters;
  42. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  43. uint32_t programCount;
  44. String* programNames;
  45. #endif
  46. #if DISTRHO_PLUGIN_WANT_STATE
  47. uint32_t stateCount;
  48. String* stateKeys;
  49. String* stateDefValues;
  50. #endif
  51. #if DISTRHO_PLUGIN_WANT_LATENCY
  52. uint32_t latency;
  53. #endif
  54. #if DISTRHO_PLUGIN_WANT_TIMEPOS
  55. TimePosition timePosition;
  56. #endif
  57. // Callbacks
  58. void* callbacksPtr;
  59. writeMidiFunc writeMidiCallbackFunc;
  60. requestParameterValueChangeFunc requestParameterValueChangeCallbackFunc;
  61. uint32_t bufferSize;
  62. double sampleRate;
  63. bool canRequestParameterValueChanges;
  64. PrivateData() noexcept
  65. : isProcessing(false),
  66. #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
  67. audioPorts(nullptr),
  68. #endif
  69. parameterCount(0),
  70. parameterOffset(0),
  71. parameters(nullptr),
  72. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  73. programCount(0),
  74. programNames(nullptr),
  75. #endif
  76. #if DISTRHO_PLUGIN_WANT_STATE
  77. stateCount(0),
  78. stateKeys(nullptr),
  79. stateDefValues(nullptr),
  80. #endif
  81. #if DISTRHO_PLUGIN_WANT_LATENCY
  82. latency(0),
  83. #endif
  84. callbacksPtr(nullptr),
  85. writeMidiCallbackFunc(nullptr),
  86. requestParameterValueChangeCallbackFunc(nullptr),
  87. bufferSize(d_lastBufferSize),
  88. sampleRate(d_lastSampleRate),
  89. canRequestParameterValueChanges(d_lastCanRequestParameterValueChanges)
  90. {
  91. DISTRHO_SAFE_ASSERT(bufferSize != 0);
  92. DISTRHO_SAFE_ASSERT(d_isNotZero(sampleRate));
  93. #if defined(DISTRHO_PLUGIN_TARGET_DSSI) || defined(DISTRHO_PLUGIN_TARGET_LV2)
  94. parameterOffset += DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS;
  95. # if DISTRHO_PLUGIN_WANT_LATENCY
  96. parameterOffset += 1;
  97. # endif
  98. #endif
  99. #ifdef DISTRHO_PLUGIN_TARGET_LV2
  100. # if (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_TIMEPOS || DISTRHO_PLUGIN_WANT_STATE)
  101. parameterOffset += 1;
  102. # if DISTRHO_PLUGIN_WANT_STATE
  103. parameterOffset += 1;
  104. # endif
  105. # endif
  106. #endif
  107. }
  108. ~PrivateData() noexcept
  109. {
  110. #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
  111. if (audioPorts != nullptr)
  112. {
  113. delete[] audioPorts;
  114. audioPorts = nullptr;
  115. }
  116. #endif
  117. if (parameters != nullptr)
  118. {
  119. delete[] parameters;
  120. parameters = nullptr;
  121. }
  122. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  123. if (programNames != nullptr)
  124. {
  125. delete[] programNames;
  126. programNames = nullptr;
  127. }
  128. #endif
  129. #if DISTRHO_PLUGIN_WANT_STATE
  130. if (stateKeys != nullptr)
  131. {
  132. delete[] stateKeys;
  133. stateKeys = nullptr;
  134. }
  135. if (stateDefValues != nullptr)
  136. {
  137. delete[] stateDefValues;
  138. stateDefValues = nullptr;
  139. }
  140. #endif
  141. }
  142. #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
  143. bool writeMidiCallback(const MidiEvent& midiEvent)
  144. {
  145. if (writeMidiCallbackFunc != nullptr)
  146. return writeMidiCallbackFunc(callbacksPtr, midiEvent);
  147. return false;
  148. }
  149. #endif
  150. #if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST
  151. bool requestParameterValueChangeCallback(const uint32_t index, const float value)
  152. {
  153. if (requestParameterValueChangeCallbackFunc != nullptr)
  154. return requestParameterValueChangeCallbackFunc(callbacksPtr, index, value);
  155. return false;
  156. }
  157. #endif
  158. };
  159. // -----------------------------------------------------------------------
  160. // Plugin exporter class
  161. class PluginExporter
  162. {
  163. public:
  164. PluginExporter(void* const callbacksPtr,
  165. const writeMidiFunc writeMidiCall,
  166. const requestParameterValueChangeFunc requestParameterValueChangeCall)
  167. : fPlugin(createPlugin()),
  168. fData((fPlugin != nullptr) ? fPlugin->pData : nullptr),
  169. fIsActive(false)
  170. {
  171. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  172. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  173. #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
  174. {
  175. uint32_t j=0;
  176. # if DISTRHO_PLUGIN_NUM_INPUTS > 0
  177. for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i, ++j)
  178. fPlugin->initAudioPort(true, i, fData->audioPorts[j]);
  179. # endif
  180. # if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
  181. for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i, ++j)
  182. fPlugin->initAudioPort(false, i, fData->audioPorts[j]);
  183. # endif
  184. }
  185. #endif
  186. for (uint32_t i=0, count=fData->parameterCount; i < count; ++i)
  187. fPlugin->initParameter(i, fData->parameters[i]);
  188. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  189. for (uint32_t i=0, count=fData->programCount; i < count; ++i)
  190. fPlugin->initProgramName(i, fData->programNames[i]);
  191. #endif
  192. #if DISTRHO_PLUGIN_WANT_STATE
  193. for (uint32_t i=0, count=fData->stateCount; i < count; ++i)
  194. fPlugin->initState(i, fData->stateKeys[i], fData->stateDefValues[i]);
  195. #endif
  196. fData->callbacksPtr = callbacksPtr;
  197. fData->writeMidiCallbackFunc = writeMidiCall;
  198. fData->requestParameterValueChangeCallbackFunc = requestParameterValueChangeCall;
  199. }
  200. ~PluginExporter()
  201. {
  202. delete fPlugin;
  203. }
  204. // -------------------------------------------------------------------
  205. const char* getName() const noexcept
  206. {
  207. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");
  208. return fPlugin->getName();
  209. }
  210. const char* getLabel() const noexcept
  211. {
  212. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");
  213. return fPlugin->getLabel();
  214. }
  215. const char* getDescription() const noexcept
  216. {
  217. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");
  218. return fPlugin->getDescription();
  219. }
  220. const char* getMaker() const noexcept
  221. {
  222. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");
  223. return fPlugin->getMaker();
  224. }
  225. const char* getHomePage() const noexcept
  226. {
  227. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");
  228. return fPlugin->getHomePage();
  229. }
  230. const char* getLicense() const noexcept
  231. {
  232. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");
  233. return fPlugin->getLicense();
  234. }
  235. uint32_t getVersion() const noexcept
  236. {
  237. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0);
  238. return fPlugin->getVersion();
  239. }
  240. long getUniqueId() const noexcept
  241. {
  242. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0);
  243. return fPlugin->getUniqueId();
  244. }
  245. void* getInstancePointer() const noexcept
  246. {
  247. return fPlugin;
  248. }
  249. // -------------------------------------------------------------------
  250. #if DISTRHO_PLUGIN_WANT_LATENCY
  251. uint32_t getLatency() const noexcept
  252. {
  253. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
  254. return fData->latency;
  255. }
  256. #endif
  257. #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
  258. const AudioPort& getAudioPort(const bool input, const uint32_t index) const noexcept
  259. {
  260. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, sFallbackAudioPort);
  261. if (input)
  262. {
  263. # if DISTRHO_PLUGIN_NUM_INPUTS > 0
  264. DISTRHO_SAFE_ASSERT_RETURN(index < DISTRHO_PLUGIN_NUM_INPUTS, sFallbackAudioPort);
  265. # endif
  266. }
  267. else
  268. {
  269. # if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
  270. DISTRHO_SAFE_ASSERT_RETURN(index < DISTRHO_PLUGIN_NUM_OUTPUTS, sFallbackAudioPort);
  271. # endif
  272. }
  273. return fData->audioPorts[index + (input ? 0 : DISTRHO_PLUGIN_NUM_INPUTS)];
  274. }
  275. #endif
  276. uint32_t getParameterCount() const noexcept
  277. {
  278. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
  279. return fData->parameterCount;
  280. }
  281. uint32_t getParameterOffset() const noexcept
  282. {
  283. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
  284. return fData->parameterOffset;
  285. }
  286. uint32_t getParameterHints(const uint32_t index) const noexcept
  287. {
  288. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0x0);
  289. return fData->parameters[index].hints;
  290. }
  291. ParameterDesignation getParameterDesignation(const uint32_t index) const noexcept
  292. {
  293. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, kParameterDesignationNull);
  294. return fData->parameters[index].designation;
  295. }
  296. bool isParameterInput(const uint32_t index) const noexcept
  297. {
  298. return (getParameterHints(index) & kParameterIsOutput) == 0x0;
  299. }
  300. bool isParameterOutput(const uint32_t index) const noexcept
  301. {
  302. return (getParameterHints(index) & kParameterIsOutput) != 0x0;
  303. }
  304. bool isParameterOutputOrTrigger(const uint32_t index) const noexcept
  305. {
  306. const uint32_t hints = getParameterHints(index);
  307. if (hints & kParameterIsOutput)
  308. return true;
  309. if ((hints & kParameterIsTrigger) == kParameterIsTrigger)
  310. return true;
  311. return false;
  312. }
  313. const String& getParameterName(const uint32_t index) const noexcept
  314. {
  315. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);
  316. return fData->parameters[index].name;
  317. }
  318. const String& getParameterShortName(const uint32_t index) const noexcept
  319. {
  320. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);
  321. return fData->parameters[index].shortName;
  322. }
  323. const String& getParameterSymbol(const uint32_t index) const noexcept
  324. {
  325. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);
  326. return fData->parameters[index].symbol;
  327. }
  328. const String& getParameterUnit(const uint32_t index) const noexcept
  329. {
  330. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);
  331. return fData->parameters[index].unit;
  332. }
  333. const String& getParameterDescription(const uint32_t index) const noexcept
  334. {
  335. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);
  336. return fData->parameters[index].description;
  337. }
  338. const ParameterEnumerationValues& getParameterEnumValues(const uint32_t index) const noexcept
  339. {
  340. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackEnumValues);
  341. return fData->parameters[index].enumValues;
  342. }
  343. const ParameterRanges& getParameterRanges(const uint32_t index) const noexcept
  344. {
  345. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackRanges);
  346. return fData->parameters[index].ranges;
  347. }
  348. uint8_t getParameterMidiCC(const uint32_t index) const noexcept
  349. {
  350. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0);
  351. return fData->parameters[index].midiCC;
  352. }
  353. float getParameterValue(const uint32_t index) const
  354. {
  355. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0.0f);
  356. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0.0f);
  357. return fPlugin->getParameterValue(index);
  358. }
  359. void setParameterValue(const uint32_t index, const float value)
  360. {
  361. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  362. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount,);
  363. fPlugin->setParameterValue(index, value);
  364. }
  365. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  366. uint32_t getProgramCount() const noexcept
  367. {
  368. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
  369. return fData->programCount;
  370. }
  371. const String& getProgramName(const uint32_t index) const noexcept
  372. {
  373. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->programCount, sFallbackString);
  374. return fData->programNames[index];
  375. }
  376. void loadProgram(const uint32_t index)
  377. {
  378. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  379. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->programCount,);
  380. fPlugin->loadProgram(index);
  381. }
  382. #endif
  383. #if DISTRHO_PLUGIN_WANT_STATE
  384. uint32_t getStateCount() const noexcept
  385. {
  386. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
  387. return fData->stateCount;
  388. }
  389. const String& getStateKey(const uint32_t index) const noexcept
  390. {
  391. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->stateCount, sFallbackString);
  392. return fData->stateKeys[index];
  393. }
  394. const String& getStateDefaultValue(const uint32_t index) const noexcept
  395. {
  396. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->stateCount, sFallbackString);
  397. return fData->stateDefValues[index];
  398. }
  399. # if DISTRHO_PLUGIN_WANT_STATEFILES
  400. bool isStateFile(const uint32_t index) const
  401. {
  402. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->stateCount, false);
  403. return fPlugin->isStateFile(index);
  404. }
  405. # endif
  406. # if DISTRHO_PLUGIN_WANT_FULL_STATE
  407. String getState(const char* key) const
  408. {
  409. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, sFallbackString);
  410. DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', sFallbackString);
  411. return fPlugin->getState(key);
  412. }
  413. # endif
  414. void setState(const char* const key, const char* const value)
  415. {
  416. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  417. DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  418. DISTRHO_SAFE_ASSERT_RETURN(value != nullptr,);
  419. fPlugin->setState(key, value);
  420. }
  421. bool wantStateKey(const char* const key) const noexcept
  422. {
  423. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, false);
  424. DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', false);
  425. for (uint32_t i=0; i < fData->stateCount; ++i)
  426. {
  427. if (fData->stateKeys[i] == key)
  428. return true;
  429. }
  430. return false;
  431. }
  432. #endif
  433. #if DISTRHO_PLUGIN_WANT_TIMEPOS
  434. void setTimePosition(const TimePosition& timePosition) noexcept
  435. {
  436. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  437. std::memcpy(&fData->timePosition, &timePosition, sizeof(TimePosition));
  438. }
  439. #endif
  440. // -------------------------------------------------------------------
  441. bool isActive() const noexcept
  442. {
  443. return fIsActive;
  444. }
  445. void activate()
  446. {
  447. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  448. DISTRHO_SAFE_ASSERT_RETURN(! fIsActive,);
  449. fIsActive = true;
  450. fPlugin->activate();
  451. }
  452. void deactivate()
  453. {
  454. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  455. DISTRHO_SAFE_ASSERT_RETURN(fIsActive,);
  456. fIsActive = false;
  457. fPlugin->deactivate();
  458. }
  459. void deactivateIfNeeded()
  460. {
  461. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  462. if (fIsActive)
  463. {
  464. fIsActive = false;
  465. fPlugin->deactivate();
  466. }
  467. }
  468. #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
  469. void run(const float** const inputs, float** const outputs, const uint32_t frames,
  470. const MidiEvent* const midiEvents, const uint32_t midiEventCount)
  471. {
  472. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  473. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  474. if (! fIsActive)
  475. {
  476. fIsActive = true;
  477. fPlugin->activate();
  478. }
  479. fData->isProcessing = true;
  480. fPlugin->run(inputs, outputs, frames, midiEvents, midiEventCount);
  481. fData->isProcessing = false;
  482. }
  483. #else
  484. void run(const float** const inputs, float** const outputs, const uint32_t frames)
  485. {
  486. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  487. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  488. if (! fIsActive)
  489. {
  490. fIsActive = true;
  491. fPlugin->activate();
  492. }
  493. fData->isProcessing = true;
  494. fPlugin->run(inputs, outputs, frames);
  495. fData->isProcessing = false;
  496. }
  497. #endif
  498. // -------------------------------------------------------------------
  499. uint32_t getBufferSize() const noexcept
  500. {
  501. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
  502. return fData->bufferSize;
  503. }
  504. double getSampleRate() const noexcept
  505. {
  506. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0.0);
  507. return fData->sampleRate;
  508. }
  509. void setBufferSize(const uint32_t bufferSize, const bool doCallback = false)
  510. {
  511. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  512. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  513. DISTRHO_SAFE_ASSERT(bufferSize >= 2);
  514. if (fData->bufferSize == bufferSize)
  515. return;
  516. fData->bufferSize = bufferSize;
  517. if (doCallback)
  518. {
  519. if (fIsActive) fPlugin->deactivate();
  520. fPlugin->bufferSizeChanged(bufferSize);
  521. if (fIsActive) fPlugin->activate();
  522. }
  523. }
  524. void setSampleRate(const double sampleRate, const bool doCallback = false)
  525. {
  526. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  527. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  528. DISTRHO_SAFE_ASSERT(sampleRate > 0.0);
  529. if (d_isEqual(fData->sampleRate, sampleRate))
  530. return;
  531. fData->sampleRate = sampleRate;
  532. if (doCallback)
  533. {
  534. if (fIsActive) fPlugin->deactivate();
  535. fPlugin->sampleRateChanged(sampleRate);
  536. if (fIsActive) fPlugin->activate();
  537. }
  538. }
  539. private:
  540. // -------------------------------------------------------------------
  541. // Plugin and DistrhoPlugin data
  542. Plugin* const fPlugin;
  543. Plugin::PrivateData* const fData;
  544. bool fIsActive;
  545. // -------------------------------------------------------------------
  546. // Static fallback data, see DistrhoPlugin.cpp
  547. static const String sFallbackString;
  548. static const AudioPort sFallbackAudioPort;
  549. static const ParameterRanges sFallbackRanges;
  550. static const ParameterEnumerationValues sFallbackEnumValues;
  551. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginExporter)
  552. DISTRHO_PREVENT_HEAP_ALLOCATION
  553. };
  554. // -----------------------------------------------------------------------
  555. END_NAMESPACE_DISTRHO
  556. #endif // DISTRHO_PLUGIN_INTERNAL_HPP_INCLUDED