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.

265 lines
7.9KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2015 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. #include "DistrhoPlugin.hpp"
  17. START_NAMESPACE_DISTRHO
  18. // -----------------------------------------------------------------------------------------------------------
  19. /**
  20. Plugin that demonstrates the latency API in DPF.
  21. */
  22. class LatencyExamplePlugin : public Plugin
  23. {
  24. public:
  25. LatencyExamplePlugin()
  26. : Plugin(1, 0, 0), // 1 parameter
  27. fLatency(1.0f),
  28. fLatencyInFrames(0),
  29. fBuffer(nullptr),
  30. fBufferPos(0)
  31. {
  32. // allocates buffer
  33. sampleRateChanged(getSampleRate());
  34. }
  35. ~LatencyExamplePlugin() override
  36. {
  37. delete[] fBuffer;
  38. }
  39. protected:
  40. /* --------------------------------------------------------------------------------------------------------
  41. * Information */
  42. /**
  43. Get the plugin label.
  44. This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters.
  45. */
  46. const char* getLabel() const override
  47. {
  48. return "Latency";
  49. }
  50. /**
  51. Get an extensive comment/description about the plugin.
  52. */
  53. const char* getDescription() const override
  54. {
  55. return "Plugin that demonstrates the latency API in DPF.";
  56. }
  57. /**
  58. Get the plugin author/maker.
  59. */
  60. const char* getMaker() const override
  61. {
  62. return "DISTRHO";
  63. }
  64. /**
  65. Get the plugin homepage.
  66. */
  67. const char* getHomePage() const override
  68. {
  69. return "https://github.com/DISTRHO/DPF";
  70. }
  71. /**
  72. Get the plugin license name (a single line of text).
  73. For commercial plugins this should return some short copyright information.
  74. */
  75. const char* getLicense() const override
  76. {
  77. return "ISC";
  78. }
  79. /**
  80. Get the plugin version, in hexadecimal.
  81. */
  82. uint32_t getVersion() const override
  83. {
  84. return d_version(1, 0, 0);
  85. }
  86. /**
  87. Get the plugin unique Id.
  88. This value is used by LADSPA, DSSI and VST plugin formats.
  89. */
  90. int64_t getUniqueId() const override
  91. {
  92. return d_cconst('d', 'L', 'a', 't');
  93. }
  94. /* --------------------------------------------------------------------------------------------------------
  95. * Init */
  96. /**
  97. Initialize the audio port @a index.@n
  98. This function will be called once, shortly after the plugin is created.
  99. */
  100. void initAudioPort(bool input, uint32_t index, AudioPort& port) override
  101. {
  102. // treat meter audio ports as stereo
  103. port.groupId = kPortGroupMono;
  104. // everything else is as default
  105. Plugin::initAudioPort(input, index, port);
  106. }
  107. /**
  108. Initialize the parameter @a index.
  109. This function will be called once, shortly after the plugin is created.
  110. */
  111. void initParameter(uint32_t index, Parameter& parameter) override
  112. {
  113. if (index != 0)
  114. return;
  115. parameter.hints = kParameterIsAutomatable;
  116. parameter.name = "Latency";
  117. parameter.symbol = "latency";
  118. parameter.unit = "s";
  119. parameter.ranges.def = 1.0f;
  120. parameter.ranges.min = 0.0f;
  121. parameter.ranges.max = 5.0f;
  122. }
  123. /* --------------------------------------------------------------------------------------------------------
  124. * Internal data */
  125. /**
  126. Get the current value of a parameter.
  127. The host may call this function from any context, including realtime processing.
  128. */
  129. float getParameterValue(uint32_t index) const override
  130. {
  131. if (index != 0)
  132. return 0.0f;
  133. return fLatency;
  134. }
  135. /**
  136. Change a parameter value.
  137. The host may call this function from any context, including realtime processing.
  138. When a parameter is marked as automatable, you must ensure no non-realtime operations are performed.
  139. @note This function will only be called for parameter inputs.
  140. */
  141. void setParameterValue(uint32_t index, float value) override
  142. {
  143. if (index != 0)
  144. return;
  145. fLatency = value;
  146. fLatencyInFrames = value*getSampleRate();
  147. setLatency(fLatencyInFrames);
  148. }
  149. /* --------------------------------------------------------------------------------------------------------
  150. * Audio/MIDI Processing */
  151. /**
  152. Run/process function for plugins without MIDI input.
  153. @note Some parameters might be null if there are no audio inputs or outputs.
  154. */
  155. void run(const float** inputs, float** outputs, uint32_t frames) override
  156. {
  157. const float* const in = inputs[0];
  158. /* */ float* const out = outputs[0];
  159. if (fLatencyInFrames == 0)
  160. {
  161. if (out != in)
  162. std::memcpy(out, in, sizeof(float)*frames);
  163. return;
  164. }
  165. // Put the new audio in the buffer.
  166. std::memcpy(fBuffer+fBufferPos, in, sizeof(float)*frames);
  167. fBufferPos += frames;
  168. // buffer is not filled enough yet
  169. if (fBufferPos < fLatencyInFrames+frames)
  170. {
  171. // silence output
  172. std::memset(out, 0, sizeof(float)*frames);
  173. }
  174. // buffer is ready to copy
  175. else
  176. {
  177. // copy latency buffer to output
  178. const uint32_t readPos = fBufferPos-fLatencyInFrames-frames;
  179. std::memcpy(out, fBuffer+readPos, sizeof(float)*frames);
  180. // move latency buffer back by some frames
  181. std::memmove(fBuffer, fBuffer+frames, sizeof(float)*fBufferPos);
  182. fBufferPos -= frames;
  183. }
  184. }
  185. /* --------------------------------------------------------------------------------------------------------
  186. * Callbacks (optional) */
  187. /**
  188. Optional callback to inform the plugin about a sample rate change.
  189. This function will only be called when the plugin is deactivated.
  190. */
  191. void sampleRateChanged(double newSampleRate) override
  192. {
  193. if (fBuffer != nullptr)
  194. delete[] fBuffer;
  195. const uint32_t maxFrames = newSampleRate*6; // 6 seconds
  196. fBuffer = new float[maxFrames];
  197. std::memset(fBuffer, 0, sizeof(float)*maxFrames);
  198. fLatencyInFrames = fLatency*newSampleRate;
  199. fBufferPos = 0;
  200. }
  201. // -------------------------------------------------------------------------------------------------------
  202. private:
  203. // Parameters
  204. float fLatency;
  205. uint32_t fLatencyInFrames;
  206. // Buffer for previous audio, size depends on sample rate
  207. float* fBuffer;
  208. uint32_t fBufferPos;
  209. /**
  210. Set our plugin class as non-copyable and add a leak detector just in case.
  211. */
  212. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LatencyExamplePlugin)
  213. };
  214. /* ------------------------------------------------------------------------------------------------------------
  215. * Plugin entry point, called by DPF to create a new plugin instance. */
  216. Plugin* createPlugin()
  217. {
  218. return new LatencyExamplePlugin();
  219. }
  220. // -----------------------------------------------------------------------------------------------------------
  221. END_NAMESPACE_DISTRHO