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.

252 lines
7.5KB

  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 parameter @a index.
  98. This function will be called once, shortly after the plugin is created.
  99. */
  100. void initParameter(uint32_t index, Parameter& parameter) override
  101. {
  102. if (index != 0)
  103. return;
  104. parameter.hints = kParameterIsAutomable;
  105. parameter.name = "Latency";
  106. parameter.symbol = "latency";
  107. parameter.unit = "s";
  108. parameter.ranges.def = 1.0f;
  109. parameter.ranges.min = 0.0f;
  110. parameter.ranges.max = 5.0f;
  111. }
  112. /* --------------------------------------------------------------------------------------------------------
  113. * Internal data */
  114. /**
  115. Get the current value of a parameter.
  116. The host may call this function from any context, including realtime processing.
  117. */
  118. float getParameterValue(uint32_t index) const override
  119. {
  120. if (index != 0)
  121. return 0.0f;
  122. return fLatency;
  123. }
  124. /**
  125. Change a parameter value.
  126. The host may call this function from any context, including realtime processing.
  127. When a parameter is marked as automable, you must ensure no non-realtime operations are performed.
  128. @note This function will only be called for parameter inputs.
  129. */
  130. void setParameterValue(uint32_t index, float value) override
  131. {
  132. if (index != 0)
  133. return;
  134. fLatency = value;
  135. fLatencyInFrames = value*getSampleRate();
  136. setLatency(fLatencyInFrames);
  137. }
  138. /* --------------------------------------------------------------------------------------------------------
  139. * Audio/MIDI Processing */
  140. /**
  141. Run/process function for plugins without MIDI input.
  142. @note Some parameters might be null if there are no audio inputs or outputs.
  143. */
  144. void run(const float** inputs, float** outputs, uint32_t frames) override
  145. {
  146. const float* const in = inputs[0];
  147. /* */ float* const out = outputs[0];
  148. if (fLatencyInFrames == 0)
  149. {
  150. if (out != in)
  151. std::memcpy(out, in, sizeof(float)*frames);
  152. return;
  153. }
  154. // Put the new audio in the buffer.
  155. std::memcpy(fBuffer+fBufferPos, in, sizeof(float)*frames);
  156. fBufferPos += frames;
  157. // buffer is not filled enough yet
  158. if (fBufferPos < fLatencyInFrames+frames)
  159. {
  160. // silence output
  161. std::memset(out, 0, sizeof(float)*frames);
  162. }
  163. // buffer is ready to copy
  164. else
  165. {
  166. // copy latency buffer to output
  167. const uint32_t readPos = fBufferPos-fLatencyInFrames-frames;
  168. std::memcpy(out, fBuffer+readPos, sizeof(float)*frames);
  169. // move latency buffer back by some frames
  170. std::memmove(fBuffer, fBuffer+frames, sizeof(float)*fBufferPos);
  171. fBufferPos -= frames;
  172. }
  173. }
  174. /* --------------------------------------------------------------------------------------------------------
  175. * Callbacks (optional) */
  176. /**
  177. Optional callback to inform the plugin about a sample rate change.
  178. This function will only be called when the plugin is deactivated.
  179. */
  180. void sampleRateChanged(double newSampleRate) override
  181. {
  182. if (fBuffer != nullptr)
  183. delete[] fBuffer;
  184. const uint32_t maxFrames = newSampleRate*6; // 6 seconds
  185. fBuffer = new float[maxFrames];
  186. std::memset(fBuffer, 0, sizeof(float)*maxFrames);
  187. fLatencyInFrames = fLatency*newSampleRate;
  188. fBufferPos = 0;
  189. }
  190. // -------------------------------------------------------------------------------------------------------
  191. private:
  192. // Parameters
  193. float fLatency;
  194. uint32_t fLatencyInFrames;
  195. // Buffer for previous audio, size depends on sample rate
  196. float* fBuffer;
  197. uint32_t fBufferPos;
  198. /**
  199. Set our plugin class as non-copyable and add a leak detector just in case.
  200. */
  201. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LatencyExamplePlugin)
  202. };
  203. /* ------------------------------------------------------------------------------------------------------------
  204. * Plugin entry point, called by DPF to create a new plugin instance. */
  205. Plugin* createPlugin()
  206. {
  207. return new LatencyExamplePlugin();
  208. }
  209. // -----------------------------------------------------------------------------------------------------------
  210. END_NAMESPACE_DISTRHO