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.

179 lines
7.3KB

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