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.

179 lines
5.9KB

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