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.

240 lines
7.4KB

  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. Simple plugin to demonstrate how to modify input/output port type in DPF.
  21. The plugin outputs sample & hold (S&H) value of input signal.
  22. User can specify hold time via parameter and/or Hold Time CV port.
  23. */
  24. class ExamplePluginCVPort : public Plugin
  25. {
  26. public:
  27. ExamplePluginCVPort()
  28. : Plugin(1, 0, 0) {} // 1 parameters, 0 programs, 0 states
  29. protected:
  30. /* --------------------------------------------------------------------------------------------------------
  31. * Information */
  32. /**
  33. Get the plugin label.
  34. A plugin label follows the same rules as Parameter::symbol, with the exception that it can start with numbers.
  35. */
  36. const char* getLabel() const override
  37. {
  38. return "CVPort";
  39. }
  40. /**
  41. Get an extensive comment/description about the plugin.
  42. */
  43. const char* getDescription() const override
  44. {
  45. return "Simple plugin with CVPort.\n\
  46. The plugin does sample & hold processing.";
  47. }
  48. /**
  49. Get the plugin author/maker.
  50. */
  51. const char* getMaker() const override
  52. {
  53. return "DISTRHO";
  54. }
  55. /**
  56. Get the plugin homepage.
  57. */
  58. const char* getHomePage() const override
  59. {
  60. return "https://github.com/DISTRHO/DPF";
  61. }
  62. /**
  63. Get the plugin license name (a single line of text).
  64. For commercial plugins this should return some short copyright information.
  65. */
  66. const char* getLicense() const override
  67. {
  68. return "ISC";
  69. }
  70. /**
  71. Get the plugin version, in hexadecimal.
  72. */
  73. uint32_t getVersion() const override
  74. {
  75. return d_version(1, 0, 0);
  76. }
  77. /**
  78. Get the plugin unique Id.
  79. This value is used by LADSPA, DSSI and VST plugin formats.
  80. */
  81. int64_t getUniqueId() const override
  82. {
  83. return d_cconst('d', 'C', 'V', 'P');
  84. }
  85. /* --------------------------------------------------------------------------------------------------------
  86. * Init */
  87. /**
  88. Initialize the audio port @a index.@n
  89. This function will be called once, shortly after the plugin is created.
  90. */
  91. void initAudioPort(bool input, uint32_t index, AudioPort& port) override
  92. {
  93. /**
  94. Note that index is independent for input and output.
  95. In other words, input port index starts from 0 and output port index also starts from 0.
  96. */
  97. if (input)
  98. {
  99. if (index == 0) {
  100. // Audio port doesn't need to specify port.hints.
  101. port.name = "Audio Input";
  102. port.symbol = "audio_in";
  103. return;
  104. }
  105. else if (index == 1) {
  106. port.hints = kAudioPortIsCV;
  107. port.name = "Hold Time";
  108. port.symbol = "hold_time";
  109. return;
  110. }
  111. // Add more condition here when increasing DISTRHO_PLUGIN_NUM_INPUTS.
  112. }
  113. else
  114. {
  115. if (index == 0) {
  116. port.hints = kAudioPortIsCV;
  117. port.name = "CV Output";
  118. port.symbol = "cv_out";
  119. return;
  120. }
  121. // Add more condition here when increasing DISTRHO_PLUGIN_NUM_OUTPUTS.
  122. }
  123. /**
  124. It shouldn't reach here, but just in case if index is greater than 0.
  125. */
  126. Plugin::initAudioPort(input, index, port);
  127. }
  128. /**
  129. Initialize the parameter @a index.
  130. This function will be called once, shortly after the plugin is created.
  131. */
  132. void initParameter(uint32_t index, Parameter& parameter) override
  133. {
  134. if (index != 0) return;
  135. parameter.name = "Hold Time";
  136. parameter.symbol = "hold_time";
  137. parameter.hints = kParameterIsAutomable|kParameterIsLogarithmic;
  138. parameter.ranges.min = 0.0f;
  139. parameter.ranges.max = maxHoldTime;
  140. parameter.ranges.def = 0.1f;
  141. }
  142. /* --------------------------------------------------------------------------------------------------------
  143. * Internal data */
  144. /**
  145. Get the current value of a parameter.
  146. */
  147. inline float getParameterValue(uint32_t index) const override
  148. {
  149. return index == 0 ? holdTime : 0.0f;
  150. }
  151. /**
  152. Change a parameter value.
  153. */
  154. void setParameterValue(uint32_t index, float value) override
  155. {
  156. if (index != 0) return;
  157. holdTime = value;
  158. counter = uint32_t(holdTime * sampleRate);
  159. }
  160. /* --------------------------------------------------------------------------------------------------------
  161. * Process */
  162. /**
  163. Run/process function for plugins without MIDI input.
  164. */
  165. void run(const float** inputs, float** outputs, uint32_t frames) override
  166. {
  167. /**
  168. - inputs[0] is input audio port.
  169. - inputs[1] is hold time CV port.
  170. - outputs[0] is output CV port.
  171. */
  172. for (uint32_t i = 0; i < frames; ++i) {
  173. if (counter == 0) {
  174. float cv = inputs[1][i] > 0.0f ? inputs[1][i] : 0.0f;
  175. float time = holdTime + cv;
  176. if (time > maxHoldTime)
  177. time = maxHoldTime;
  178. counter = uint32_t(time * sampleRate);
  179. holdValue = inputs[0][i]; // Refresh hold value.
  180. } else {
  181. --counter;
  182. }
  183. outputs[0][i] = holdValue;
  184. }
  185. }
  186. // -------------------------------------------------------------------------------------------------------
  187. private:
  188. const float maxHoldTime = 1.0f;
  189. float sampleRate = 44100.0f;
  190. uint32_t counter = 0; // Hold time in samples. Used to count hold time.
  191. float holdTime = 0.0f; // Hold time in seconds.
  192. float holdValue = 0.0f;
  193. /**
  194. Set our plugin class as non-copyable and add a leak detector just in case.
  195. */
  196. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExamplePluginCVPort)
  197. };
  198. /* ------------------------------------------------------------------------------------------------------------
  199. * Plugin entry point, called by DPF to create a new plugin instance. */
  200. Plugin* createPlugin()
  201. {
  202. return new ExamplePluginCVPort();
  203. }
  204. // -----------------------------------------------------------------------------------------------------------
  205. END_NAMESPACE_DISTRHO