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.

162 lines
4.5KB

  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. MixerAudioSource::MixerAudioSource()
  19. : tempBuffer (2, 0),
  20. currentSampleRate (0.0),
  21. bufferSizeExpected (0)
  22. {
  23. }
  24. MixerAudioSource::~MixerAudioSource()
  25. {
  26. removeAllInputs();
  27. }
  28. //==============================================================================
  29. void MixerAudioSource::addInputSource (AudioSource* input, const bool deleteWhenRemoved)
  30. {
  31. if (input != nullptr && ! inputs.contains (input))
  32. {
  33. double localRate;
  34. int localBufferSize;
  35. {
  36. const ScopedLock sl (lock);
  37. localRate = currentSampleRate;
  38. localBufferSize = bufferSizeExpected;
  39. }
  40. if (localRate > 0.0)
  41. input->prepareToPlay (localBufferSize, localRate);
  42. const ScopedLock sl (lock);
  43. inputsToDelete.setBit (inputs.size(), deleteWhenRemoved);
  44. inputs.add (input);
  45. }
  46. }
  47. void MixerAudioSource::removeInputSource (AudioSource* input, const bool deleteInput)
  48. {
  49. if (input != nullptr)
  50. {
  51. int index;
  52. {
  53. const ScopedLock sl (lock);
  54. index = inputs.indexOf (input);
  55. if (index >= 0)
  56. {
  57. inputsToDelete.shiftBits (index, 1);
  58. inputs.remove (index);
  59. }
  60. }
  61. if (index >= 0)
  62. {
  63. input->releaseResources();
  64. if (deleteInput)
  65. delete input;
  66. }
  67. }
  68. }
  69. void MixerAudioSource::removeAllInputs()
  70. {
  71. OwnedArray<AudioSource> toDelete;
  72. {
  73. const ScopedLock sl (lock);
  74. for (int i = inputs.size(); --i >= 0;)
  75. if (inputsToDelete[i])
  76. toDelete.add (inputs.getUnchecked(i));
  77. }
  78. }
  79. void MixerAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
  80. {
  81. tempBuffer.setSize (2, samplesPerBlockExpected);
  82. const ScopedLock sl (lock);
  83. currentSampleRate = sampleRate;
  84. bufferSizeExpected = samplesPerBlockExpected;
  85. for (int i = inputs.size(); --i >= 0;)
  86. inputs.getUnchecked(i)->prepareToPlay (samplesPerBlockExpected, sampleRate);
  87. }
  88. void MixerAudioSource::releaseResources()
  89. {
  90. const ScopedLock sl (lock);
  91. for (int i = inputs.size(); --i >= 0;)
  92. inputs.getUnchecked(i)->releaseResources();
  93. tempBuffer.setSize (2, 0);
  94. currentSampleRate = 0;
  95. bufferSizeExpected = 0;
  96. }
  97. void MixerAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info)
  98. {
  99. const ScopedLock sl (lock);
  100. if (inputs.size() > 0)
  101. {
  102. inputs.getUnchecked(0)->getNextAudioBlock (info);
  103. if (inputs.size() > 1)
  104. {
  105. tempBuffer.setSize (jmax (1, info.buffer->getNumChannels()),
  106. info.buffer->getNumSamples());
  107. AudioSourceChannelInfo info2;
  108. info2.buffer = &tempBuffer;
  109. info2.numSamples = info.numSamples;
  110. info2.startSample = 0;
  111. for (int i = 1; i < inputs.size(); ++i)
  112. {
  113. inputs.getUnchecked(i)->getNextAudioBlock (info2);
  114. for (int chan = 0; chan < info.buffer->getNumChannels(); ++chan)
  115. info.buffer->addFrom (chan, info.startSample, tempBuffer, chan, 0, info.numSamples);
  116. }
  117. }
  118. }
  119. else
  120. {
  121. info.clearActiveBufferRegion();
  122. }
  123. }