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.

176 lines
6.9KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. #include "../JuceLibraryCode/JuceHeader.h"
  18. #include "../../GenericEditor.h"
  19. //==============================================================================
  20. /**
  21. */
  22. class MultiOutSynth : public AudioProcessor
  23. {
  24. public:
  25. enum
  26. {
  27. maxMidiChannel = 16,
  28. maxNumberOfVoices = 5
  29. };
  30. //==============================================================================
  31. MultiOutSynth()
  32. {
  33. // The base class constructor will already add a main stereo output bus
  34. // If you want to add your own main channel then simply call clear the
  35. // output buses (busArrangement.outputBuses.clear()) and then add your own
  36. // Add additional output buses but disable these by default
  37. for (int busNr = 1; busNr < maxMidiChannel; ++busNr)
  38. busArrangement.outputBuses.add (AudioProcessorBus (String ("Output #") += String (busNr + 1), AudioChannelSet::disabled()));
  39. // initialize other stuff (not related to buses)
  40. formatManager.registerBasicFormats();
  41. for (int midiChannel = 0; midiChannel < maxMidiChannel; ++midiChannel)
  42. {
  43. synth.add (new Synthesiser());
  44. for (int i = 0; i < maxNumberOfVoices; ++i)
  45. synth[midiChannel]->addVoice (new SamplerVoice());
  46. }
  47. loadNewSample (BinaryData::singing_ogg, BinaryData::singing_oggSize);
  48. }
  49. ~MultiOutSynth() {}
  50. //==============================================================================
  51. bool setPreferredBusArrangement (bool isInputBus, int busIndex,
  52. const AudioChannelSet& preferred) override
  53. {
  54. const int numChannels = preferred.size();
  55. const bool isMainBus = (busIndex == 0);
  56. // do not allow disabling the main output bus
  57. if (isMainBus && preferred.isDisabled()) return false;
  58. // only support mono or stereo (or disabling) buses
  59. if (numChannels > 2) return false;
  60. // pass the call on to the base class
  61. return AudioProcessor::setPreferredBusArrangement (isInputBus, busIndex, preferred);
  62. }
  63. //==============================================================================
  64. void prepareToPlay (double newSampleRate, int samplesPerBlock) override
  65. {
  66. ignoreUnused (samplesPerBlock);
  67. for (int midiChannel = 0; midiChannel < maxMidiChannel; ++midiChannel)
  68. synth[midiChannel]->setCurrentPlaybackSampleRate (newSampleRate);
  69. }
  70. void releaseResources() override {}
  71. void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiBuffer) override
  72. {
  73. buffer.clear();
  74. for (int busNr = 0; busNr < maxMidiChannel; ++busNr)
  75. {
  76. MidiBuffer midiChannelBuffer = filterMidiMessagesForChannel (midiBuffer, busNr + 1);
  77. AudioSampleBuffer audioBusBuffer = busArrangement.getBusBuffer (buffer, false, busNr);
  78. synth [busNr]->renderNextBlock (audioBusBuffer, midiChannelBuffer, 0, audioBusBuffer.getNumSamples());
  79. }
  80. }
  81. //==============================================================================
  82. AudioProcessorEditor* createEditor() override { return new GenericEditor (*this); }
  83. bool hasEditor() const override { return true; }
  84. //==============================================================================
  85. const String getName() const override { return "Gain PlugIn"; }
  86. bool acceptsMidi() const override { return false; }
  87. bool producesMidi() const override { return false; }
  88. double getTailLengthSeconds() const override { return 0; }
  89. int getNumPrograms() override { return 1; }
  90. int getCurrentProgram() override { return 0; }
  91. void setCurrentProgram (int) override {}
  92. const String getProgramName (int) override { return String(); }
  93. void changeProgramName (int , const String& ) override { }
  94. //==============================================================================
  95. void getStateInformation (MemoryBlock&) override {}
  96. void setStateInformation (const void*, int) override {}
  97. private:
  98. //==============================================================================
  99. static MidiBuffer filterMidiMessagesForChannel (const MidiBuffer& input, int channel)
  100. {
  101. MidiMessage msg;
  102. int samplePosition;
  103. MidiBuffer output;
  104. for (MidiBuffer::Iterator it (input); it.getNextEvent (msg, samplePosition);)
  105. if (msg.getChannel() == channel) output.addEvent (msg, samplePosition);
  106. return output;
  107. }
  108. void loadNewSample (const void* data, int dataSize)
  109. {
  110. MemoryInputStream* soundBuffer = new MemoryInputStream (data, static_cast<std::size_t> (dataSize), false);
  111. ScopedPointer<AudioFormatReader> formatReader (formatManager.findFormatForFileExtension ("ogg")->createReaderFor (soundBuffer, true));
  112. BigInteger midiNotes;
  113. midiNotes.setRange (0, 126, true);
  114. SynthesiserSound::Ptr newSound = new SamplerSound ("Voice", *formatReader, midiNotes, 0x40, 0.0, 0.0, 10.0);
  115. for (int channel = 0; channel < maxMidiChannel; ++channel)
  116. synth[channel]->removeSound (0);
  117. sound = newSound;
  118. for (int channel = 0; channel < maxMidiChannel; ++channel)
  119. synth[channel]->addSound (sound);
  120. }
  121. //==============================================================================
  122. AudioFormatManager formatManager;
  123. OwnedArray<Synthesiser> synth;
  124. SynthesiserSound::Ptr sound;
  125. //==============================================================================
  126. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultiOutSynth)
  127. };
  128. //==============================================================================
  129. // This creates new instances of the plugin..
  130. AudioProcessor* JUCE_CALLTYPE createPluginFilter()
  131. {
  132. return new MultiOutSynth();
  133. }