Audio plugin host https://kx.studio/carla
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.

162 lines
5.2KB

  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. MPESynthesiserBase::MPESynthesiserBase()
  18. : instrument (new MPEInstrument),
  19. sampleRate (0),
  20. minimumSubBlockSize (32)
  21. {
  22. instrument->addListener (this);
  23. }
  24. MPESynthesiserBase::MPESynthesiserBase (MPEInstrument* inst)
  25. : instrument (inst),
  26. sampleRate (0),
  27. minimumSubBlockSize (32)
  28. {
  29. jassert (instrument != nullptr);
  30. instrument->addListener (this);
  31. }
  32. //==============================================================================
  33. MPEZoneLayout MPESynthesiserBase::getZoneLayout() const noexcept
  34. {
  35. return instrument->getZoneLayout();
  36. }
  37. void MPESynthesiserBase::setZoneLayout (MPEZoneLayout newLayout)
  38. {
  39. instrument->setZoneLayout (newLayout);
  40. }
  41. //==============================================================================
  42. void MPESynthesiserBase::enableLegacyMode (int pitchbendRange, Range<int> channelRange)
  43. {
  44. instrument->enableLegacyMode (pitchbendRange, channelRange);
  45. }
  46. bool MPESynthesiserBase::isLegacyModeEnabled() const noexcept
  47. {
  48. return instrument->isLegacyModeEnabled();
  49. }
  50. Range<int> MPESynthesiserBase::getLegacyModeChannelRange() const noexcept
  51. {
  52. return instrument->getLegacyModeChannelRange();
  53. }
  54. void MPESynthesiserBase::setLegacyModeChannelRange (Range<int> channelRange)
  55. {
  56. instrument->setLegacyModeChannelRange (channelRange);
  57. }
  58. int MPESynthesiserBase::getLegacyModePitchbendRange() const noexcept
  59. {
  60. return instrument->getLegacyModePitchbendRange();
  61. }
  62. void MPESynthesiserBase::setLegacyModePitchbendRange (int pitchbendRange)
  63. {
  64. instrument->setLegacyModePitchbendRange (pitchbendRange);
  65. }
  66. //==============================================================================
  67. void MPESynthesiserBase::handleMidiEvent (const MidiMessage& m)
  68. {
  69. instrument->processNextMidiEvent (m);
  70. }
  71. //==============================================================================
  72. template <typename floatType>
  73. void MPESynthesiserBase::renderNextBlock (AudioBuffer<floatType>& outputAudio,
  74. const MidiBuffer& inputMidi,
  75. int startSample,
  76. int numSamples)
  77. {
  78. // you must set the sample rate before using this!
  79. jassert (sampleRate != 0);
  80. MidiBuffer::Iterator midiIterator (inputMidi);
  81. midiIterator.setNextSamplePosition (startSample);
  82. int midiEventPos;
  83. MidiMessage m;
  84. const ScopedLock sl (renderAudioLock);
  85. while (numSamples > 0)
  86. {
  87. if (! midiIterator.getNextEvent (m, midiEventPos))
  88. {
  89. renderNextSubBlock (outputAudio, startSample, numSamples);
  90. return;
  91. }
  92. const int samplesToNextMidiMessage = midiEventPos - startSample;
  93. if (samplesToNextMidiMessage >= numSamples)
  94. {
  95. renderNextSubBlock (outputAudio, startSample, numSamples);
  96. handleMidiEvent (m);
  97. break;
  98. }
  99. if (samplesToNextMidiMessage < minimumSubBlockSize)
  100. {
  101. handleMidiEvent (m);
  102. continue;
  103. }
  104. renderNextSubBlock (outputAudio, startSample, samplesToNextMidiMessage);
  105. handleMidiEvent (m);
  106. startSample += samplesToNextMidiMessage;
  107. numSamples -= samplesToNextMidiMessage;
  108. }
  109. while (midiIterator.getNextEvent (m, midiEventPos))
  110. handleMidiEvent (m);
  111. }
  112. // explicit instantiation for supported float types:
  113. template void MPESynthesiserBase::renderNextBlock<float> (AudioBuffer<float>&, const MidiBuffer&, int, int);
  114. template void MPESynthesiserBase::renderNextBlock<double> (AudioBuffer<double>&, const MidiBuffer&, int, int);
  115. //==============================================================================
  116. void MPESynthesiserBase::setCurrentPlaybackSampleRate (const double newRate)
  117. {
  118. if (sampleRate != newRate)
  119. {
  120. const ScopedLock sl (renderAudioLock);
  121. instrument->releaseAllNotes();
  122. sampleRate = newRate;
  123. }
  124. }
  125. //==============================================================================
  126. void MPESynthesiserBase::setMinimumRenderingSubdivisionSize (int numSamples) noexcept
  127. {
  128. jassert (numSamples > 0); // it wouldn't make much sense for this to be less than 1
  129. minimumSubBlockSize = numSamples;
  130. }