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.

163 lines
6.4KB

  1. /*
  2. ==============================================================================
  3. MultiOutSynth.cpp
  4. Created: 23 Nov 2015 3:08:33pm
  5. Author: Fabian Renn
  6. ==============================================================================
  7. */
  8. #include "../JuceLibraryCode/JuceHeader.h"
  9. #include "../../GenericEditor.h"
  10. //==============================================================================
  11. /**
  12. */
  13. class MultiOutSynth : public AudioProcessor
  14. {
  15. public:
  16. enum
  17. {
  18. maxMidiChannel = 16,
  19. maxNumberOfVoices = 5
  20. };
  21. //==============================================================================
  22. MultiOutSynth()
  23. {
  24. // The base class constructor will already add a main stereo output bus
  25. // If you want to add your own main channel then simply call clear the
  26. // output buses (busArrangement.outputBuses.clear()) and then add your own
  27. // Add additional output buses but disable these by default
  28. for (int busNr = 1; busNr < maxMidiChannel; ++busNr)
  29. busArrangement.outputBuses.add (AudioProcessorBus (String ("Output #") += String (busNr + 1), AudioChannelSet::disabled()));
  30. // initialize other stuff (not related to buses)
  31. formatManager.registerBasicFormats();
  32. for (int midiChannel = 0; midiChannel < maxMidiChannel; ++midiChannel)
  33. {
  34. synth.add (new Synthesiser());
  35. for (int i = 0; i < maxNumberOfVoices; ++i)
  36. synth[midiChannel]->addVoice (new SamplerVoice());
  37. }
  38. loadNewSample (BinaryData::singing_ogg, BinaryData::singing_oggSize);
  39. }
  40. ~MultiOutSynth() {}
  41. //==============================================================================
  42. bool setPreferredBusArrangement (bool isInputBus, int busIndex,
  43. const AudioChannelSet& preferred) override
  44. {
  45. const int numChannels = preferred.size();
  46. const bool isMainBus = (busIndex == 0);
  47. // do not allow disabling the main output bus
  48. if (isMainBus && preferred.isDisabled()) return false;
  49. // only support mono or stereo (or disabling) buses
  50. if (numChannels > 2) return false;
  51. // pass the call on to the base class
  52. return AudioProcessor::setPreferredBusArrangement (isInputBus, busIndex, preferred);
  53. }
  54. //==============================================================================
  55. void prepareToPlay (double newSampleRate, int samplesPerBlock) override
  56. {
  57. ignoreUnused (samplesPerBlock);
  58. for (int midiChannel = 0; midiChannel < maxMidiChannel; ++midiChannel)
  59. synth[midiChannel]->setCurrentPlaybackSampleRate (newSampleRate);
  60. }
  61. void releaseResources() override {}
  62. void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiBuffer) override
  63. {
  64. buffer.clear();
  65. for (int busNr = 0; busNr < maxMidiChannel; ++busNr)
  66. {
  67. MidiBuffer midiChannelBuffer = filterMidiMessagesForChannel (midiBuffer, busNr + 1);
  68. AudioSampleBuffer audioBusBuffer = busArrangement.getBusBuffer (buffer, false, busNr);
  69. synth [busNr]->renderNextBlock (audioBusBuffer, midiChannelBuffer, 0, audioBusBuffer.getNumSamples());
  70. }
  71. }
  72. //==============================================================================
  73. AudioProcessorEditor* createEditor() override { return new GenericEditor (*this); }
  74. bool hasEditor() const override { return true; }
  75. //==============================================================================
  76. const String getName() const override { return "Gain PlugIn"; }
  77. bool acceptsMidi() const override { return false; }
  78. bool producesMidi() const override { return false; }
  79. bool silenceInProducesSilenceOut() const override { return true; }
  80. double getTailLengthSeconds() const override { return 0; }
  81. int getNumPrograms() override { return 1; }
  82. int getCurrentProgram() override { return 0; }
  83. void setCurrentProgram (int) override {}
  84. const String getProgramName (int) override { return String(); }
  85. void changeProgramName (int , const String& ) override { }
  86. //==============================================================================
  87. void getStateInformation (MemoryBlock&) override {}
  88. void setStateInformation (const void*, int) override {}
  89. private:
  90. //==============================================================================
  91. static MidiBuffer filterMidiMessagesForChannel (const MidiBuffer& input, int channel)
  92. {
  93. MidiMessage msg;
  94. int samplePosition;
  95. MidiBuffer output;
  96. for (MidiBuffer::Iterator it (input); it.getNextEvent (msg, samplePosition);)
  97. if (msg.getChannel() == channel) output.addEvent (msg, samplePosition);
  98. return output;
  99. }
  100. void loadNewSample (const void* data, int dataSize)
  101. {
  102. MemoryInputStream* soundBuffer = new MemoryInputStream (data, static_cast<std::size_t> (dataSize), false);
  103. ScopedPointer<AudioFormatReader> formatReader (formatManager.findFormatForFileExtension ("ogg")->createReaderFor (soundBuffer, true));
  104. BigInteger midiNotes;
  105. midiNotes.setRange (0, 126, true);
  106. SynthesiserSound::Ptr newSound = new SamplerSound ("Voice", *formatReader, midiNotes, 0x40, 0.0, 0.0, 10.0);
  107. for (int channel = 0; channel < maxMidiChannel; ++channel)
  108. synth[channel]->removeSound (0);
  109. sound = newSound;
  110. for (int channel = 0; channel < maxMidiChannel; ++channel)
  111. synth[channel]->addSound (sound);
  112. }
  113. //==============================================================================
  114. AudioFormatManager formatManager;
  115. OwnedArray<Synthesiser> synth;
  116. SynthesiserSound::Ptr sound;
  117. //==============================================================================
  118. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultiOutSynth)
  119. };
  120. //==============================================================================
  121. // This creates new instances of the plugin..
  122. AudioProcessor* JUCE_CALLTYPE createPluginFilter()
  123. {
  124. return new MultiOutSynth();
  125. }