The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

283 lines
7.8KB

  1. #ifndef OSCILLATORS_H_INCLUDED
  2. #define OSCILLATORS_H_INCLUDED
  3. #include "../JuceLibraryCode/JuceHeader.h"
  4. /**
  5. Base class for oscillators
  6. */
  7. class Oscillator : public SynthesiserVoice
  8. {
  9. public:
  10. Oscillator()
  11. {
  12. amplitude.reset (getSampleRate(), 0.1);
  13. phaseIncrement.reset (getSampleRate(), 0.1);
  14. }
  15. virtual ~Oscillator()
  16. {
  17. }
  18. void startNote (int midiNoteNumber, float velocity, SynthesiserSound*, int) override
  19. {
  20. frequency = MidiMessage::getMidiNoteInHertz (midiNoteNumber);
  21. phaseIncrement.setValue (((2.0 * double_Pi) * frequency) / sampleRate);
  22. amplitude.setValue (velocity);
  23. // Store the initial note and work out the maximum frequency deviations for pitch bend
  24. initialNote = midiNoteNumber;
  25. maxFreq = MidiMessage::getMidiNoteInHertz (initialNote + 4) - frequency;
  26. minFreq = frequency - MidiMessage::getMidiNoteInHertz (initialNote - 4);
  27. }
  28. void stopNote (float, bool) override
  29. {
  30. clearCurrentNote();
  31. amplitude.setValue (0.0);
  32. }
  33. void pitchWheelMoved (int newValue) override
  34. {
  35. // Change the phase increment based on pitch bend amount
  36. if (newValue > 0)
  37. phaseIncrement.setValue (((2.0 * double_Pi) * (frequency + (maxFreq * (newValue / 127.0)))) / sampleRate);
  38. else
  39. phaseIncrement.setValue (((2.0 * double_Pi) * (frequency + (minFreq * (newValue / 127.0)))) / sampleRate);
  40. }
  41. void controllerMoved (int, int) override
  42. {
  43. }
  44. void channelPressureChanged (int newChannelPressureValue) override
  45. {
  46. // Set the amplitude based on pressure value
  47. amplitude.setValue (newChannelPressureValue / 127.0);
  48. }
  49. void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples) override
  50. {
  51. while(--numSamples >= 0)
  52. {
  53. double output = getSample() * amplitude.getNextValue();
  54. for (int i = outputBuffer.getNumChannels(); --i >= 0;)
  55. outputBuffer.addSample (i, startSample, static_cast<float> (output));
  56. ++startSample;
  57. }
  58. }
  59. /** Returns the next sample */
  60. double getSample()
  61. {
  62. double output = renderWaveShape (phasePos);
  63. phasePos += phaseIncrement.getNextValue();
  64. if (phasePos > (2.0 * double_Pi))
  65. phasePos -= (2.0 * double_Pi);
  66. return output;
  67. }
  68. /** Subclasses should override this to say whether they can play the given sound */
  69. virtual bool canPlaySound (SynthesiserSound* sound) override = 0;
  70. /** Subclasses should override this to render a waveshape */
  71. virtual double renderWaveShape (const double currentPhase) = 0;
  72. private:
  73. LinearSmoothedValue<double> amplitude;
  74. LinearSmoothedValue<double> phaseIncrement;
  75. double frequency;
  76. double phasePos = 0.0f;
  77. double sampleRate = 44100.0;
  78. int initialNote;
  79. double maxFreq;
  80. double minFreq;
  81. //==============================================================================
  82. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Oscillator)
  83. };
  84. //==============================================================================
  85. /**
  86. Sine sound struct - applies to MIDI channel 1
  87. */
  88. struct SineSound : public SynthesiserSound
  89. {
  90. SineSound () {}
  91. bool appliesToNote (int) override { return true; }
  92. bool appliesToChannel (int midiChannel) override
  93. {
  94. if (midiChannel == 1)
  95. return true;
  96. return false;
  97. }
  98. //==============================================================================
  99. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SineSound)
  100. };
  101. /**
  102. Sine voice struct that renders a sin waveshape
  103. */
  104. struct SineVoice : public Oscillator
  105. {
  106. SineVoice() {};
  107. bool canPlaySound (SynthesiserSound* sound) override
  108. {
  109. return dynamic_cast<SineSound*> (sound) != nullptr;
  110. }
  111. double renderWaveShape (const double currentPhase) override
  112. {
  113. return sin (currentPhase);
  114. }
  115. //==============================================================================
  116. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SineVoice)
  117. };
  118. //==============================================================================
  119. /**
  120. Square sound struct - applies to MIDI channel 2
  121. */
  122. struct SquareSound : public SynthesiserSound
  123. {
  124. SquareSound() {}
  125. bool appliesToNote (int) override { return true; }
  126. bool appliesToChannel (int midiChannel) override
  127. {
  128. if (midiChannel == 2)
  129. return true;
  130. return false;
  131. }
  132. //==============================================================================
  133. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SquareSound)
  134. };
  135. /**
  136. Square voice struct that renders a square waveshape
  137. */
  138. struct SquareVoice : public Oscillator
  139. {
  140. SquareVoice() {};
  141. bool canPlaySound (SynthesiserSound* sound) override
  142. {
  143. return dynamic_cast<SquareSound*> (sound) != nullptr;
  144. }
  145. double renderWaveShape (const double currentPhase) override
  146. {
  147. if (currentPhase < (double_Pi))
  148. return 0.0;
  149. else
  150. return 1.0;
  151. }
  152. //==============================================================================
  153. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SquareVoice)
  154. };
  155. //==============================================================================
  156. /**
  157. Sawtooth sound - applies to MIDI channel 3
  158. */
  159. struct SawSound : public SynthesiserSound
  160. {
  161. SawSound() {}
  162. bool appliesToNote (int) override { return true; }
  163. bool appliesToChannel (int midiChannel) override
  164. {
  165. if (midiChannel == 3)
  166. return true;
  167. return false;
  168. }
  169. //==============================================================================
  170. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SawSound)
  171. };
  172. /**
  173. Sawtooth voice that renders a sawtooth waveshape
  174. */
  175. struct SawVoice : public Oscillator
  176. {
  177. SawVoice() {}
  178. bool canPlaySound (SynthesiserSound* sound) override
  179. {
  180. return dynamic_cast<SawSound*> (sound) != nullptr;
  181. }
  182. double renderWaveShape (const double currentPhase) override
  183. {
  184. return (1.0 / double_Pi) * currentPhase - 1.0;
  185. }
  186. //==============================================================================
  187. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SawVoice)
  188. };
  189. //==============================================================================
  190. /**
  191. Triangle sound - applies to MIDI channel 4
  192. */
  193. struct TriangleSound : public SynthesiserSound
  194. {
  195. TriangleSound() {}
  196. bool appliesToNote (int) override { return true; }
  197. bool appliesToChannel (int midiChannel) override
  198. {
  199. if (midiChannel == 4)
  200. return true;
  201. return false;
  202. }
  203. //==============================================================================
  204. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TriangleSound)
  205. };
  206. /**
  207. Triangle voice that renders a triangle waveshape
  208. */
  209. struct TriangleVoice : public Oscillator
  210. {
  211. TriangleVoice() {}
  212. bool canPlaySound (SynthesiserSound* sound) override
  213. {
  214. return dynamic_cast<TriangleSound*> (sound) != nullptr;
  215. }
  216. double renderWaveShape (const double currentPhase) override
  217. {
  218. if (currentPhase < double_Pi)
  219. return -1.0 + (2.0 / double_Pi) * currentPhase;
  220. else
  221. return 3.0 - (2.0 / double_Pi) * currentPhase;
  222. }
  223. //==============================================================================
  224. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TriangleVoice)
  225. };
  226. #endif // OSCILLATORS_H_INCLUDED