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.

457 lines
12KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2014 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. // -----------------------------------------------------------------------
  28. // Plugin private data
  29. struct Plugin::PrivateData {
  30. bool isProcessing;
  31. uint32_t parameterCount;
  32. Parameter* parameters;
  33. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  34. uint32_t programCount;
  35. d_string* programNames;
  36. #endif
  37. #if DISTRHO_PLUGIN_WANT_STATE
  38. uint32_t stateCount;
  39. d_string* stateKeys;
  40. #endif
  41. #if DISTRHO_PLUGIN_WANT_LATENCY
  42. uint32_t latency;
  43. #endif
  44. #if DISTRHO_PLUGIN_WANT_TIMEPOS
  45. TimePos timePos;
  46. #endif
  47. uint32_t bufferSize;
  48. double sampleRate;
  49. PrivateData() noexcept
  50. : isProcessing(false),
  51. parameterCount(0),
  52. parameters(nullptr),
  53. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  54. programCount(0),
  55. programNames(nullptr),
  56. #endif
  57. #if DISTRHO_PLUGIN_WANT_STATE
  58. stateCount(0),
  59. stateKeys(nullptr),
  60. #endif
  61. #if DISTRHO_PLUGIN_WANT_LATENCY
  62. latency(0),
  63. #endif
  64. bufferSize(d_lastBufferSize),
  65. sampleRate(d_lastSampleRate)
  66. {
  67. DISTRHO_SAFE_ASSERT(bufferSize != 0);
  68. DISTRHO_SAFE_ASSERT(sampleRate != 0.0);
  69. }
  70. ~PrivateData() noexcept
  71. {
  72. if (parameters != nullptr)
  73. {
  74. delete[] parameters;
  75. parameters = nullptr;
  76. }
  77. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  78. if (programNames != nullptr)
  79. {
  80. delete[] programNames;
  81. programNames = nullptr;
  82. }
  83. #endif
  84. #if DISTRHO_PLUGIN_WANT_STATE
  85. if (stateKeys != nullptr)
  86. {
  87. delete[] stateKeys;
  88. stateKeys = nullptr;
  89. }
  90. #endif
  91. }
  92. };
  93. // -----------------------------------------------------------------------
  94. // Plugin exporter class
  95. class PluginExporter
  96. {
  97. public:
  98. PluginExporter()
  99. : fPlugin(createPlugin()),
  100. fData((fPlugin != nullptr) ? fPlugin->pData : nullptr),
  101. fIsActive(false)
  102. {
  103. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  104. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  105. for (uint32_t i=0, count=fData->parameterCount; i < count; ++i)
  106. fPlugin->d_initParameter(i, fData->parameters[i]);
  107. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  108. for (uint32_t i=0, count=fData->programCount; i < count; ++i)
  109. fPlugin->d_initProgramName(i, fData->programNames[i]);
  110. #endif
  111. #if DISTRHO_PLUGIN_WANT_STATE
  112. for (uint32_t i=0, count=fData->stateCount; i < count; ++i)
  113. fPlugin->d_initStateKey(i, fData->stateKeys[i]);
  114. #endif
  115. }
  116. ~PluginExporter()
  117. {
  118. delete fPlugin;
  119. }
  120. // -------------------------------------------------------------------
  121. const char* getName() const noexcept
  122. {
  123. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");
  124. return fPlugin->d_getName();
  125. }
  126. const char* getLabel() const noexcept
  127. {
  128. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");
  129. return fPlugin->d_getLabel();
  130. }
  131. const char* getMaker() const noexcept
  132. {
  133. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");
  134. return fPlugin->d_getMaker();
  135. }
  136. const char* getLicense() const noexcept
  137. {
  138. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, "");
  139. return fPlugin->d_getLicense();
  140. }
  141. uint32_t getVersion() const noexcept
  142. {
  143. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0);
  144. return fPlugin->d_getVersion();
  145. }
  146. long getUniqueId() const noexcept
  147. {
  148. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0);
  149. return fPlugin->d_getUniqueId();
  150. }
  151. void* getInstancePointer() const noexcept
  152. {
  153. return fPlugin;
  154. }
  155. // -------------------------------------------------------------------
  156. #if DISTRHO_PLUGIN_WANT_LATENCY
  157. uint32_t getLatency() const noexcept
  158. {
  159. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
  160. return fData->latency;
  161. }
  162. #endif
  163. uint32_t getParameterCount() const noexcept
  164. {
  165. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
  166. return fData->parameterCount;
  167. }
  168. uint32_t getParameterHints(const uint32_t index) const noexcept
  169. {
  170. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0x0);
  171. return fData->parameters[index].hints;
  172. }
  173. bool isParameterOutput(const uint32_t index) const noexcept
  174. {
  175. return (getParameterHints(index) & kParameterIsOutput);
  176. }
  177. const d_string& getParameterName(const uint32_t index) const noexcept
  178. {
  179. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);
  180. return fData->parameters[index].name;
  181. }
  182. const d_string& getParameterSymbol(const uint32_t index) const noexcept
  183. {
  184. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);
  185. return fData->parameters[index].symbol;
  186. }
  187. const d_string& getParameterUnit(const uint32_t index) const noexcept
  188. {
  189. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);
  190. return fData->parameters[index].unit;
  191. }
  192. const ParameterRanges& getParameterRanges(const uint32_t index) const noexcept
  193. {
  194. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackRanges);
  195. return fData->parameters[index].ranges;
  196. }
  197. float getParameterValue(const uint32_t index) const
  198. {
  199. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0.0f);
  200. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0.0f);
  201. return fPlugin->d_getParameterValue(index);
  202. }
  203. void setParameterValue(const uint32_t index, const float value)
  204. {
  205. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  206. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount,);
  207. fPlugin->d_setParameterValue(index, value);
  208. }
  209. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  210. uint32_t getProgramCount() const noexcept
  211. {
  212. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
  213. return fData->programCount;
  214. }
  215. const d_string& getProgramName(const uint32_t index) const noexcept
  216. {
  217. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->programCount, sFallbackString);
  218. return fData->programNames[index];
  219. }
  220. void setProgram(const uint32_t index)
  221. {
  222. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  223. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->programCount,);
  224. fPlugin->d_setProgram(index);
  225. }
  226. #endif
  227. #if DISTRHO_PLUGIN_WANT_STATE
  228. uint32_t getStateCount() const noexcept
  229. {
  230. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
  231. return fData->stateCount;
  232. }
  233. const d_string& getStateKey(const uint32_t index) const noexcept
  234. {
  235. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->stateCount, sFallbackString);
  236. return fData->stateKeys[index];
  237. }
  238. void setState(const char* const key, const char* const value)
  239. {
  240. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  241. DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  242. DISTRHO_SAFE_ASSERT_RETURN(value != nullptr,);
  243. fPlugin->d_setState(key, value);
  244. }
  245. bool wantStateKey(const char* const key) const noexcept
  246. {
  247. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, false);
  248. DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', false);
  249. for (uint32_t i=0; i < fData->stateCount; ++i)
  250. {
  251. if (fData->stateKeys[i] == key)
  252. return true;
  253. }
  254. return false;
  255. }
  256. #endif
  257. #if DISTRHO_PLUGIN_WANT_TIMEPOS
  258. void setTimePos(const TimePos& timePos) noexcept
  259. {
  260. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  261. std::memcpy(&fData->timePos, &timePos, sizeof(TimePos));
  262. }
  263. #endif
  264. // -------------------------------------------------------------------
  265. void activate()
  266. {
  267. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  268. fIsActive = true;
  269. fPlugin->d_activate();
  270. }
  271. void deactivate()
  272. {
  273. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  274. fIsActive = false;
  275. fPlugin->d_deactivate();
  276. }
  277. #if DISTRHO_PLUGIN_IS_SYNTH
  278. void run(const float** const inputs, float** const outputs, const uint32_t frames,
  279. const MidiEvent* const midiEvents, const uint32_t midiEventCount)
  280. {
  281. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  282. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  283. fData->isProcessing = true;
  284. fPlugin->d_run(inputs, outputs, frames, midiEvents, midiEventCount);
  285. fData->isProcessing = false;
  286. }
  287. #else
  288. void run(const float** const inputs, float** const outputs, const uint32_t frames)
  289. {
  290. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  291. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  292. fData->isProcessing = true;
  293. fPlugin->d_run(inputs, outputs, frames);
  294. fData->isProcessing = false;
  295. }
  296. #endif
  297. // -------------------------------------------------------------------
  298. uint32_t getBufferSize() const noexcept
  299. {
  300. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
  301. return fData->bufferSize;
  302. }
  303. double getSampleRate() const noexcept
  304. {
  305. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0.0);
  306. return fData->sampleRate;
  307. }
  308. void setBufferSize(const uint32_t bufferSize, const bool doCallback = false)
  309. {
  310. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  311. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  312. DISTRHO_SAFE_ASSERT(bufferSize >= 2);
  313. if (fData->bufferSize == bufferSize)
  314. return;
  315. fData->bufferSize = bufferSize;
  316. if (doCallback)
  317. {
  318. if (fIsActive) fPlugin->d_deactivate();
  319. fPlugin->d_bufferSizeChanged(bufferSize);
  320. if (fIsActive) fPlugin->d_activate();
  321. }
  322. }
  323. void setSampleRate(const double sampleRate, const bool doCallback = false)
  324. {
  325. DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);
  326. DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  327. DISTRHO_SAFE_ASSERT(sampleRate > 0.0);
  328. if (fData->sampleRate == sampleRate)
  329. return;
  330. fData->sampleRate = sampleRate;
  331. if (doCallback)
  332. {
  333. if (fIsActive) fPlugin->d_deactivate();
  334. fPlugin->d_sampleRateChanged(sampleRate);
  335. if (fIsActive) fPlugin->d_activate();
  336. }
  337. }
  338. private:
  339. // -------------------------------------------------------------------
  340. // Plugin and DistrhoPlugin data
  341. Plugin* const fPlugin;
  342. Plugin::PrivateData* const fData;
  343. bool fIsActive;
  344. // -------------------------------------------------------------------
  345. // Static fallback data, see DistrhoPlugin.cpp
  346. static const d_string sFallbackString;
  347. static const ParameterRanges sFallbackRanges;
  348. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginExporter)
  349. DISTRHO_PREVENT_HEAP_ALLOCATION
  350. };
  351. // -----------------------------------------------------------------------
  352. END_NAMESPACE_DISTRHO
  353. #endif // DISTRHO_PLUGIN_INTERNAL_HPP_INCLUDED