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.

188 lines
6.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. BEGIN_JUCE_NAMESPACE
  19. //==============================================================================
  20. AudioProcessorPlayer::AudioProcessorPlayer()
  21. : processor (nullptr),
  22. sampleRate (0),
  23. blockSize (0),
  24. isPrepared (false),
  25. numInputChans (0),
  26. numOutputChans (0),
  27. tempBuffer (1, 1)
  28. {
  29. }
  30. AudioProcessorPlayer::~AudioProcessorPlayer()
  31. {
  32. setProcessor (nullptr);
  33. }
  34. //==============================================================================
  35. void AudioProcessorPlayer::setProcessor (AudioProcessor* const processorToPlay)
  36. {
  37. if (processor != processorToPlay)
  38. {
  39. if (processorToPlay != nullptr && sampleRate > 0 && blockSize > 0)
  40. {
  41. processorToPlay->setPlayConfigDetails (numInputChans, numOutputChans,
  42. sampleRate, blockSize);
  43. processorToPlay->prepareToPlay (sampleRate, blockSize);
  44. }
  45. AudioProcessor* oldOne;
  46. {
  47. const ScopedLock sl (lock);
  48. oldOne = isPrepared ? processor : nullptr;
  49. processor = processorToPlay;
  50. isPrepared = true;
  51. }
  52. if (oldOne != nullptr)
  53. oldOne->releaseResources();
  54. }
  55. }
  56. //==============================================================================
  57. void AudioProcessorPlayer::audioDeviceIOCallback (const float** const inputChannelData,
  58. const int numInputChannels,
  59. float** const outputChannelData,
  60. const int numOutputChannels,
  61. const int numSamples)
  62. {
  63. // these should have been prepared by audioDeviceAboutToStart()...
  64. jassert (sampleRate > 0 && blockSize > 0);
  65. incomingMidi.clear();
  66. messageCollector.removeNextBlockOfMessages (incomingMidi, numSamples);
  67. int i, totalNumChans = 0;
  68. if (numInputChannels > numOutputChannels)
  69. {
  70. // if there aren't enough output channels for the number of
  71. // inputs, we need to create some temporary extra ones (can't
  72. // use the input data in case it gets written to)
  73. tempBuffer.setSize (numInputChannels - numOutputChannels, numSamples,
  74. false, false, true);
  75. for (i = 0; i < numOutputChannels; ++i)
  76. {
  77. channels[totalNumChans] = outputChannelData[i];
  78. memcpy (channels[totalNumChans], inputChannelData[i], sizeof (float) * numSamples);
  79. ++totalNumChans;
  80. }
  81. for (i = numOutputChannels; i < numInputChannels; ++i)
  82. {
  83. channels[totalNumChans] = tempBuffer.getSampleData (i - numOutputChannels, 0);
  84. memcpy (channels[totalNumChans], inputChannelData[i], sizeof (float) * numSamples);
  85. ++totalNumChans;
  86. }
  87. }
  88. else
  89. {
  90. for (i = 0; i < numInputChannels; ++i)
  91. {
  92. channels[totalNumChans] = outputChannelData[i];
  93. memcpy (channels[totalNumChans], inputChannelData[i], sizeof (float) * numSamples);
  94. ++totalNumChans;
  95. }
  96. for (i = numInputChannels; i < numOutputChannels; ++i)
  97. {
  98. channels[totalNumChans] = outputChannelData[i];
  99. zeromem (channels[totalNumChans], sizeof (float) * numSamples);
  100. ++totalNumChans;
  101. }
  102. }
  103. AudioSampleBuffer buffer (channels, totalNumChans, numSamples);
  104. const ScopedLock sl (lock);
  105. if (processor != nullptr)
  106. {
  107. const ScopedLock sl2 (processor->getCallbackLock());
  108. if (processor->isSuspended())
  109. {
  110. for (i = 0; i < numOutputChannels; ++i)
  111. zeromem (outputChannelData[i], sizeof (float) * numSamples);
  112. }
  113. else
  114. {
  115. processor->processBlock (buffer, incomingMidi);
  116. }
  117. }
  118. }
  119. void AudioProcessorPlayer::audioDeviceAboutToStart (AudioIODevice* device)
  120. {
  121. const ScopedLock sl (lock);
  122. sampleRate = device->getCurrentSampleRate();
  123. blockSize = device->getCurrentBufferSizeSamples();
  124. numInputChans = device->getActiveInputChannels().countNumberOfSetBits();
  125. numOutputChans = device->getActiveOutputChannels().countNumberOfSetBits();
  126. messageCollector.reset (sampleRate);
  127. zeromem (channels, sizeof (channels));
  128. if (processor != nullptr)
  129. {
  130. if (isPrepared)
  131. processor->releaseResources();
  132. AudioProcessor* const oldProcessor = processor;
  133. setProcessor (nullptr);
  134. setProcessor (oldProcessor);
  135. }
  136. }
  137. void AudioProcessorPlayer::audioDeviceStopped()
  138. {
  139. const ScopedLock sl (lock);
  140. if (processor != nullptr && isPrepared)
  141. processor->releaseResources();
  142. sampleRate = 0.0;
  143. blockSize = 0;
  144. isPrepared = false;
  145. tempBuffer.setSize (1, 1);
  146. }
  147. void AudioProcessorPlayer::handleIncomingMidiMessage (MidiInput*, const MidiMessage& message)
  148. {
  149. messageCollector.addMessageToQueue (message);
  150. }
  151. END_JUCE_NAMESPACE