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.

388 lines
11KB

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