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.

184 lines
6.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software 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. AudioProcessorPlayer::AudioProcessorPlayer()
  18. : processor (nullptr),
  19. sampleRate (0),
  20. blockSize (0),
  21. isPrepared (false),
  22. numInputChans (0),
  23. numOutputChans (0)
  24. {
  25. }
  26. AudioProcessorPlayer::~AudioProcessorPlayer()
  27. {
  28. setProcessor (nullptr);
  29. }
  30. //==============================================================================
  31. void AudioProcessorPlayer::setProcessor (AudioProcessor* const processorToPlay)
  32. {
  33. if (processor != processorToPlay)
  34. {
  35. if (processorToPlay != nullptr && sampleRate > 0 && blockSize > 0)
  36. {
  37. processorToPlay->setPlayConfigDetails (numInputChans, numOutputChans, sampleRate, blockSize);
  38. processorToPlay->prepareToPlay (sampleRate, blockSize);
  39. }
  40. AudioProcessor* oldOne;
  41. {
  42. const ScopedLock sl (lock);
  43. oldOne = isPrepared ? processor : nullptr;
  44. processor = processorToPlay;
  45. isPrepared = true;
  46. }
  47. if (oldOne != nullptr)
  48. oldOne->releaseResources();
  49. }
  50. }
  51. //==============================================================================
  52. void AudioProcessorPlayer::audioDeviceIOCallback (const float** const inputChannelData,
  53. const int numInputChannels,
  54. float** const outputChannelData,
  55. const int numOutputChannels,
  56. const int numSamples)
  57. {
  58. // these should have been prepared by audioDeviceAboutToStart()...
  59. jassert (sampleRate > 0 && blockSize > 0);
  60. incomingMidi.clear();
  61. messageCollector.removeNextBlockOfMessages (incomingMidi, numSamples);
  62. int totalNumChans = 0;
  63. if (numInputChannels > numOutputChannels)
  64. {
  65. // if there aren't enough output channels for the number of
  66. // inputs, we need to create some temporary extra ones (can't
  67. // use the input data in case it gets written to)
  68. tempBuffer.setSize (numInputChannels - numOutputChannels, numSamples,
  69. false, false, true);
  70. for (int i = 0; i < numOutputChannels; ++i)
  71. {
  72. channels[totalNumChans] = outputChannelData[i];
  73. memcpy (channels[totalNumChans], inputChannelData[i], sizeof (float) * (size_t) numSamples);
  74. ++totalNumChans;
  75. }
  76. for (int i = numOutputChannels; i < numInputChannels; ++i)
  77. {
  78. channels[totalNumChans] = tempBuffer.getWritePointer (i - numOutputChannels);
  79. memcpy (channels[totalNumChans], inputChannelData[i], sizeof (float) * (size_t) numSamples);
  80. ++totalNumChans;
  81. }
  82. }
  83. else
  84. {
  85. for (int i = 0; i < numInputChannels; ++i)
  86. {
  87. channels[totalNumChans] = outputChannelData[i];
  88. memcpy (channels[totalNumChans], inputChannelData[i], sizeof (float) * (size_t) numSamples);
  89. ++totalNumChans;
  90. }
  91. for (int i = numInputChannels; i < numOutputChannels; ++i)
  92. {
  93. channels[totalNumChans] = outputChannelData[i];
  94. zeromem (channels[totalNumChans], sizeof (float) * (size_t) numSamples);
  95. ++totalNumChans;
  96. }
  97. }
  98. AudioSampleBuffer buffer (channels, totalNumChans, numSamples);
  99. {
  100. const ScopedLock sl (lock);
  101. if (processor != nullptr)
  102. {
  103. const ScopedLock sl2 (processor->getCallbackLock());
  104. if (! processor->isSuspended())
  105. {
  106. processor->processBlock (buffer, incomingMidi);
  107. return;
  108. }
  109. }
  110. }
  111. for (int i = 0; i < numOutputChannels; ++i)
  112. FloatVectorOperations::clear (outputChannelData[i], numSamples);
  113. }
  114. void AudioProcessorPlayer::audioDeviceAboutToStart (AudioIODevice* const device)
  115. {
  116. const double newSampleRate = device->getCurrentSampleRate();
  117. const int newBlockSize = device->getCurrentBufferSizeSamples();
  118. const int numChansIn = device->getActiveInputChannels().countNumberOfSetBits();
  119. const int numChansOut = device->getActiveOutputChannels().countNumberOfSetBits();
  120. const ScopedLock sl (lock);
  121. sampleRate = newSampleRate;
  122. blockSize = newBlockSize;
  123. numInputChans = numChansIn;
  124. numOutputChans = numChansOut;
  125. messageCollector.reset (sampleRate);
  126. channels.calloc ((size_t) jmax (numChansIn, numChansOut) + 2);
  127. if (processor != nullptr)
  128. {
  129. if (isPrepared)
  130. processor->releaseResources();
  131. AudioProcessor* const oldProcessor = processor;
  132. setProcessor (nullptr);
  133. setProcessor (oldProcessor);
  134. }
  135. }
  136. void AudioProcessorPlayer::audioDeviceStopped()
  137. {
  138. const ScopedLock sl (lock);
  139. if (processor != nullptr && isPrepared)
  140. processor->releaseResources();
  141. sampleRate = 0.0;
  142. blockSize = 0;
  143. isPrepared = false;
  144. tempBuffer.setSize (1, 1);
  145. }
  146. void AudioProcessorPlayer::handleIncomingMidiMessage (MidiInput*, const MidiMessage& message)
  147. {
  148. messageCollector.addMessageToQueue (message);
  149. }