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.

juce_AudioSourcePlayer.cpp 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. AudioSourcePlayer::AudioSourcePlayer()
  18. : source (nullptr),
  19. sampleRate (0),
  20. bufferSize (0),
  21. tempBuffer (2, 8),
  22. lastGain (1.0f),
  23. gain (1.0f)
  24. {
  25. }
  26. AudioSourcePlayer::~AudioSourcePlayer()
  27. {
  28. setSource (nullptr);
  29. }
  30. void AudioSourcePlayer::setSource (AudioSource* newSource)
  31. {
  32. if (source != newSource)
  33. {
  34. AudioSource* const oldSource = source;
  35. if (newSource != nullptr && bufferSize > 0 && sampleRate > 0)
  36. newSource->prepareToPlay (bufferSize, sampleRate);
  37. {
  38. const ScopedLock sl (readLock);
  39. source = newSource;
  40. }
  41. if (oldSource != nullptr)
  42. oldSource->releaseResources();
  43. }
  44. }
  45. void AudioSourcePlayer::setGain (const float newGain) noexcept
  46. {
  47. gain = newGain;
  48. }
  49. void AudioSourcePlayer::audioDeviceIOCallback (const float** inputChannelData,
  50. int totalNumInputChannels,
  51. float** outputChannelData,
  52. int totalNumOutputChannels,
  53. int numSamples)
  54. {
  55. // these should have been prepared by audioDeviceAboutToStart()...
  56. jassert (sampleRate > 0 && bufferSize > 0);
  57. const ScopedLock sl (readLock);
  58. if (source != nullptr)
  59. {
  60. int numActiveChans = 0, numInputs = 0, numOutputs = 0;
  61. // messy stuff needed to compact the channels down into an array
  62. // of non-zero pointers..
  63. for (int i = 0; i < totalNumInputChannels; ++i)
  64. {
  65. if (inputChannelData[i] != nullptr)
  66. {
  67. inputChans [numInputs++] = inputChannelData[i];
  68. if (numInputs >= numElementsInArray (inputChans))
  69. break;
  70. }
  71. }
  72. for (int i = 0; i < totalNumOutputChannels; ++i)
  73. {
  74. if (outputChannelData[i] != nullptr)
  75. {
  76. outputChans [numOutputs++] = outputChannelData[i];
  77. if (numOutputs >= numElementsInArray (outputChans))
  78. break;
  79. }
  80. }
  81. if (numInputs > numOutputs)
  82. {
  83. // if there aren't enough output channels for the number of
  84. // inputs, we need to create some temporary extra ones (can't
  85. // use the input data in case it gets written to)
  86. tempBuffer.setSize (numInputs - numOutputs, numSamples,
  87. false, false, true);
  88. for (int i = 0; i < numOutputs; ++i)
  89. {
  90. channels[numActiveChans] = outputChans[i];
  91. memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples);
  92. ++numActiveChans;
  93. }
  94. for (int i = numOutputs; i < numInputs; ++i)
  95. {
  96. channels[numActiveChans] = tempBuffer.getSampleData (i - numOutputs, 0);
  97. memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples);
  98. ++numActiveChans;
  99. }
  100. }
  101. else
  102. {
  103. for (int i = 0; i < numInputs; ++i)
  104. {
  105. channels[numActiveChans] = outputChans[i];
  106. memcpy (channels[numActiveChans], inputChans[i], sizeof (float) * (size_t) numSamples);
  107. ++numActiveChans;
  108. }
  109. for (int i = numInputs; i < numOutputs; ++i)
  110. {
  111. channels[numActiveChans] = outputChans[i];
  112. zeromem (channels[numActiveChans], sizeof (float) * (size_t) numSamples);
  113. ++numActiveChans;
  114. }
  115. }
  116. AudioSampleBuffer buffer (channels, numActiveChans, numSamples);
  117. AudioSourceChannelInfo info (&buffer, 0, numSamples);
  118. source->getNextAudioBlock (info);
  119. for (int i = info.buffer->getNumChannels(); --i >= 0;)
  120. buffer.applyGainRamp (i, info.startSample, info.numSamples, lastGain, gain);
  121. lastGain = gain;
  122. }
  123. else
  124. {
  125. for (int i = 0; i < totalNumOutputChannels; ++i)
  126. if (outputChannelData[i] != nullptr)
  127. zeromem (outputChannelData[i], sizeof (float) * (size_t) numSamples);
  128. }
  129. }
  130. void AudioSourcePlayer::audioDeviceAboutToStart (AudioIODevice* device)
  131. {
  132. prepareToPlay (device->getCurrentSampleRate(),
  133. device->getCurrentBufferSizeSamples());
  134. }
  135. void AudioSourcePlayer::prepareToPlay (double newSampleRate, int newBufferSize)
  136. {
  137. sampleRate = newSampleRate;
  138. bufferSize = newBufferSize;
  139. zeromem (channels, sizeof (channels));
  140. if (source != nullptr)
  141. source->prepareToPlay (bufferSize, sampleRate);
  142. }
  143. void AudioSourcePlayer::audioDeviceStopped()
  144. {
  145. if (source != nullptr)
  146. source->releaseResources();
  147. sampleRate = 0.0;
  148. bufferSize = 0;
  149. tempBuffer.setSize (2, 8);
  150. }