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.

173 lines
7.1KB

  1. /*
  2. ==============================================================================
  3. Copyright (c) 2015 - ROLI Ltd.
  4. ==============================================================================
  5. */
  6. #include "../JuceLibraryCode/JuceHeader.h"
  7. #include "AUv3SynthEditor.h"
  8. class AUv3SynthProcessor : public AudioProcessor
  9. {
  10. public:
  11. AUv3SynthProcessor ()
  12. : currentRecording (1, 1), currentProgram (0)
  13. {
  14. // initialize parameters
  15. addParameter (isRecordingParam = new AudioParameterBool ("isRecording", "Is Recording", false));
  16. addParameter (roomSizeParam = new AudioParameterFloat ("roomSize", "Room Size", 0.0f, 1.0f, 0.5f));
  17. formatManager.registerBasicFormats();
  18. for (int i = 0; i < maxNumVoices; ++i)
  19. synth.addVoice (new SamplerVoice());
  20. loadNewSample (BinaryData::singing_ogg, BinaryData::singing_oggSize, "ogg");
  21. }
  22. //==============================================================================
  23. void prepareToPlay (double sampleRate, int estimatedMaxSizeOfBuffer) override
  24. {
  25. ignoreUnused (estimatedMaxSizeOfBuffer);
  26. lastSampleRate = sampleRate;
  27. currentRecording.setSize (1, static_cast<int> (std::ceil (kMaxDurationOfRecording * lastSampleRate)));
  28. samplesRecorded = 0;
  29. synth.setCurrentPlaybackSampleRate (lastSampleRate);
  30. reverb.setSampleRate (lastSampleRate);
  31. }
  32. void processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages) override
  33. {
  34. Reverb::Parameters reverbParameters;
  35. reverbParameters.roomSize = roomSizeParam->get();
  36. reverb.setParameters (reverbParameters);
  37. synth.renderNextBlock (buffer, midiMessages, 0, buffer.getNumSamples());
  38. if (getMainBusNumOutputChannels() == 1)
  39. reverb.processMono (buffer.getWritePointer (0), buffer.getNumSamples());
  40. else if (getMainBusNumOutputChannels() == 2)
  41. reverb.processStereo (buffer.getWritePointer (0), buffer.getWritePointer (1), buffer.getNumSamples());
  42. }
  43. //==============================================================================
  44. void releaseResources() override { currentRecording.setSize (1, 1); }
  45. //==============================================================================
  46. bool acceptsMidi() const override { return true; }
  47. bool producesMidi() const override { return false; }
  48. bool silenceInProducesSilenceOut() const override { return false; }
  49. double getTailLengthSeconds() const override { return 0.0; }
  50. //==============================================================================
  51. AudioProcessorEditor* createEditor() override { return new AUv3SynthEditor (*this); }
  52. bool hasEditor() const override { return true; }
  53. //==============================================================================
  54. const String getName() const override { return "AUv3 Synth"; }
  55. int getNumPrograms() override { return 4; }
  56. int getCurrentProgram() override { return currentProgram; }
  57. void setCurrentProgram (int index) override { currentProgram = index; }
  58. const String getProgramName (int index) override
  59. {
  60. switch (index)
  61. {
  62. case 0:
  63. return "Piano";
  64. case 1:
  65. return "Singing";
  66. case 2:
  67. return "Pinched Balloon";
  68. case 3:
  69. return "Gazeebo";
  70. }
  71. return "<Unknown>";
  72. }
  73. //==============================================================================
  74. void changeProgramName (int /*index*/, const String& /*name*/) override {}
  75. //==============================================================================
  76. void getStateInformation (MemoryBlock& destData) override
  77. {
  78. MemoryOutputStream stream (destData, true);
  79. stream.writeFloat (*isRecordingParam);
  80. stream.writeFloat (*roomSizeParam);
  81. }
  82. void setStateInformation (const void* data, int sizeInBytes) override
  83. {
  84. MemoryInputStream stream (data, static_cast<size_t> (sizeInBytes), false);
  85. isRecordingParam->setValueNotifyingHost (stream.readFloat());
  86. roomSizeParam->setValueNotifyingHost (stream.readFloat());
  87. }
  88. private:
  89. //==============================================================================
  90. void loadNewSample (const void* data, int dataSize, const char* format)
  91. {
  92. MemoryInputStream* soundBuffer = new MemoryInputStream (data, static_cast<std::size_t> (dataSize), false);
  93. ScopedPointer<AudioFormatReader> formatReader (formatManager.findFormatForFileExtension (format)->createReaderFor (soundBuffer, true));
  94. BigInteger midiNotes;
  95. midiNotes.setRange (0, 126, true);
  96. SynthesiserSound::Ptr newSound = new SamplerSound ("Voice", *formatReader, midiNotes, 0x40, 0.0, 0.0, 10.0);
  97. synth.removeSound (0);
  98. sound = newSound;
  99. synth.addSound (sound);
  100. }
  101. void swapSamples()
  102. {
  103. MemoryBlock mb;
  104. MemoryOutputStream* stream = new MemoryOutputStream (mb, true);
  105. {
  106. ScopedPointer<AudioFormatWriter> writer (formatManager.findFormatForFileExtension ("wav")->createWriterFor (stream, lastSampleRate, 1, 16,
  107. StringPairArray(), 0));
  108. writer->writeFromAudioSampleBuffer (currentRecording, 0, currentRecording.getNumSamples());
  109. writer->flush();
  110. stream->flush();
  111. }
  112. loadNewSample (mb.getData(), static_cast<int> (mb.getSize()), "wav");
  113. }
  114. //==============================================================================
  115. static constexpr int maxNumVoices = 5;
  116. static constexpr double kMaxDurationOfRecording = 1.0;
  117. //==============================================================================
  118. AudioFormatManager formatManager;
  119. int samplesRecorded;
  120. double lastSampleRate;
  121. AudioBuffer<float> currentRecording;
  122. Reverb reverb;
  123. Synthesiser synth;
  124. SynthesiserSound::Ptr sound;
  125. AudioParameterBool* isRecordingParam;
  126. AudioParameterFloat* roomSizeParam;
  127. int currentProgram;
  128. //==============================================================================
  129. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AUv3SynthProcessor)
  130. };
  131. //==============================================================================
  132. // This creates new instances of the plugin..
  133. AudioProcessor* JUCE_CALLTYPE createPluginFilter()
  134. {
  135. return new AUv3SynthProcessor();
  136. }