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.

202 lines
6.1KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2021 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 */
  90. /**
  91. Initialize the audio port @a index.@n
  92. This function will be called once, shortly after the plugin is created.
  93. */
  94. void initAudioPort(bool input, uint32_t index, AudioPort& port) override
  95. {
  96. // treat meter audio ports as stereo
  97. port.groupId = kPortGroupMono;
  98. // everything else is as default
  99. Plugin::initAudioPort(input, index, port);
  100. }
  101. /* --------------------------------------------------------------------------------------------------------
  102. * Audio/MIDI Processing */
  103. /**
  104. Run/process function for plugins with MIDI input.
  105. This synthesizes the MIDI voices with a sum of sine waves.
  106. */
  107. void run(const float**, float** outputs, uint32_t frames,
  108. const MidiEvent* midiEvents, uint32_t midiEventCount) override
  109. {
  110. for (uint32_t i = 0; i < midiEventCount; ++i)
  111. {
  112. if (midiEvents[i].size <= 3)
  113. {
  114. uint8_t status = midiEvents[i].data[0];
  115. uint8_t note = midiEvents[i].data[1] & 127;
  116. uint8_t velocity = midiEvents[i].data[2] & 127;
  117. switch (status & 0xf0)
  118. {
  119. case 0x90:
  120. if (velocity != 0)
  121. {
  122. fNotesPlayed[note] = velocity;
  123. break;
  124. }
  125. /* fall through */
  126. case 0x80:
  127. fNotesPlayed[note] = 0;
  128. fOscillatorPhases[note] = 0;
  129. break;
  130. }
  131. }
  132. }
  133. float* const output = outputs[0];
  134. std::memset(output, 0, frames * sizeof(float));
  135. for (uint32_t noteNumber = 0; noteNumber < 128; ++noteNumber)
  136. {
  137. if (fNotesPlayed[noteNumber] == 0)
  138. continue;
  139. float notePitch = 8.17579891564 * std::exp(0.0577622650 * noteNumber);
  140. float phase = fOscillatorPhases[noteNumber];
  141. float timeStep = notePitch / getSampleRate();
  142. float k2pi = 2.0 * M_PI;
  143. float gain = 0.1;
  144. for (uint32_t i = 0; i < frames; ++i)
  145. {
  146. output[i] += gain * std::sin(k2pi * phase);
  147. phase += timeStep;
  148. phase -= (int)phase;
  149. }
  150. fOscillatorPhases[noteNumber] = phase;
  151. }
  152. }
  153. // -------------------------------------------------------------------------------------------------------
  154. private:
  155. uint8_t fNotesPlayed[128];
  156. float fOscillatorPhases[128];
  157. /**
  158. Set our plugin class as non-copyable and add a leak detector just in case.
  159. */
  160. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SendNoteExamplePlugin)
  161. };
  162. /* ------------------------------------------------------------------------------------------------------------
  163. * Plugin entry point, called by DPF to create a new plugin instance. */
  164. Plugin* createPlugin()
  165. {
  166. return new SendNoteExamplePlugin();
  167. }
  168. // -----------------------------------------------------------------------------------------------------------
  169. END_NAMESPACE_DISTRHO