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.

197 lines
6.1KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2018 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. #include <cmath>
  18. #include <cstring>
  19. START_NAMESPACE_DISTRHO
  20. // -----------------------------------------------------------------------------------------------------------
  21. /**
  22. Plugin that demonstrates sending notes from the editor in DPF.
  23. */
  24. class SendNoteExamplePlugin : public Plugin
  25. {
  26. public:
  27. SendNoteExamplePlugin()
  28. : Plugin(0, 0, 0)
  29. {
  30. std::memset(fNotesPlayed, 0, sizeof(fNotesPlayed));
  31. std::memset(fOscillatorPhases, 0, sizeof(fOscillatorPhases));
  32. }
  33. protected:
  34. /* --------------------------------------------------------------------------------------------------------
  35. * Information */
  36. /**
  37. Get the plugin label.
  38. This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters.
  39. */
  40. const char* getLabel() const override
  41. {
  42. return "SendNote";
  43. }
  44. /**
  45. Get an extensive comment/description about the plugin.
  46. */
  47. const char* getDescription() const override
  48. {
  49. return "Plugin that demonstrates sending notes from the editor in DPF.";
  50. }
  51. /**
  52. Get the plugin author/maker.
  53. */
  54. const char* getMaker() const override
  55. {
  56. return "DISTRHO";
  57. }
  58. /**
  59. Get the plugin homepage.
  60. */
  61. const char* getHomePage() const override
  62. {
  63. return "https://github.com/DISTRHO/DPF";
  64. }
  65. /**
  66. Get the plugin license name (a single line of text).
  67. For commercial plugins this should return some short copyright information.
  68. */
  69. const char* getLicense() const override
  70. {
  71. return "ISC";
  72. }
  73. /**
  74. Get the plugin version, in hexadecimal.
  75. */
  76. uint32_t getVersion() const override
  77. {
  78. return d_version(1, 0, 0);
  79. }
  80. /**
  81. Get the plugin unique Id.
  82. This value is used by LADSPA, DSSI and VST plugin formats.
  83. */
  84. int64_t getUniqueId() const override
  85. {
  86. return d_cconst('d', 'S', 'N', 'o');
  87. }
  88. /* --------------------------------------------------------------------------------------------------------
  89. * Init and Internal data, unused in this plugin */
  90. void initParameter(uint32_t, Parameter&) override {}
  91. float getParameterValue(uint32_t) const override { return 0.0f;}
  92. void setParameterValue(uint32_t, float) override {}
  93. /* --------------------------------------------------------------------------------------------------------
  94. * Audio/MIDI Processing */
  95. /**
  96. Run/process function for plugins with MIDI input.
  97. This synthesizes the MIDI voices with a sum of sine waves.
  98. */
  99. void run(const float**, float** outputs, uint32_t frames,
  100. const MidiEvent* midiEvents, uint32_t midiEventCount) override
  101. {
  102. for (uint32_t i = 0; i < midiEventCount; ++i)
  103. {
  104. if (midiEvents[i].size <= 3)
  105. {
  106. uint8_t status = midiEvents[i].data[0];
  107. uint8_t note = midiEvents[i].data[1] & 127;
  108. uint8_t velocity = midiEvents[i].data[2] & 127;
  109. switch (status & 0xf0)
  110. {
  111. case 0x90:
  112. if (velocity != 0)
  113. {
  114. fNotesPlayed[note] = velocity;
  115. break;
  116. }
  117. /* fall through */
  118. case 0x80:
  119. fNotesPlayed[note] = 0;
  120. fOscillatorPhases[note] = 0;
  121. break;
  122. }
  123. }
  124. }
  125. float* outputLeft = outputs[0];
  126. float* outputRight = outputs[1];
  127. std::memset(outputLeft, 0, frames * sizeof(float));
  128. for (uint32_t noteNumber = 0; noteNumber < 128; ++noteNumber)
  129. {
  130. if (fNotesPlayed[noteNumber] == 0)
  131. continue;
  132. float notePitch = 8.17579891564 * std::exp(0.0577622650 * noteNumber);
  133. float phase = fOscillatorPhases[noteNumber];
  134. float timeStep = notePitch / getSampleRate();
  135. float k2pi = 2.0 * M_PI;
  136. float gain = 0.1;
  137. for (uint32_t i = 0; i < frames; ++i)
  138. {
  139. outputLeft[i] += gain * std::sin(k2pi * phase);
  140. phase += timeStep;
  141. phase -= (int)phase;
  142. }
  143. fOscillatorPhases[noteNumber] = phase;
  144. }
  145. std::memcpy(outputRight, outputLeft, frames * sizeof(float));
  146. }
  147. // -------------------------------------------------------------------------------------------------------
  148. private:
  149. uint8_t fNotesPlayed[128];
  150. float fOscillatorPhases[128];
  151. /**
  152. Set our plugin class as non-copyable and add a leak detector just in case.
  153. */
  154. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SendNoteExamplePlugin)
  155. };
  156. /* ------------------------------------------------------------------------------------------------------------
  157. * Plugin entry point, called by DPF to create a new plugin instance. */
  158. Plugin* createPlugin()
  159. {
  160. return new SendNoteExamplePlugin();
  161. }
  162. // -----------------------------------------------------------------------------------------------------------
  163. END_NAMESPACE_DISTRHO