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.

197 lines
6.1KB

  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. ChannelRemappingAudioSource::ChannelRemappingAudioSource (AudioSource* const source_,
  21. const bool deleteSourceWhenDeleted)
  22. : source (source_, deleteSourceWhenDeleted),
  23. requiredNumberOfChannels (2),
  24. buffer (2, 16)
  25. {
  26. remappedInfo.buffer = &buffer;
  27. remappedInfo.startSample = 0;
  28. }
  29. ChannelRemappingAudioSource::~ChannelRemappingAudioSource() {}
  30. //==============================================================================
  31. void ChannelRemappingAudioSource::setNumberOfChannelsToProduce (const int requiredNumberOfChannels_)
  32. {
  33. const ScopedLock sl (lock);
  34. requiredNumberOfChannels = requiredNumberOfChannels_;
  35. }
  36. void ChannelRemappingAudioSource::clearAllMappings()
  37. {
  38. const ScopedLock sl (lock);
  39. remappedInputs.clear();
  40. remappedOutputs.clear();
  41. }
  42. void ChannelRemappingAudioSource::setInputChannelMapping (const int destIndex, const int sourceIndex)
  43. {
  44. const ScopedLock sl (lock);
  45. while (remappedInputs.size() < destIndex)
  46. remappedInputs.add (-1);
  47. remappedInputs.set (destIndex, sourceIndex);
  48. }
  49. void ChannelRemappingAudioSource::setOutputChannelMapping (const int sourceIndex, const int destIndex)
  50. {
  51. const ScopedLock sl (lock);
  52. while (remappedOutputs.size() < sourceIndex)
  53. remappedOutputs.add (-1);
  54. remappedOutputs.set (sourceIndex, destIndex);
  55. }
  56. int ChannelRemappingAudioSource::getRemappedInputChannel (const int inputChannelIndex) const
  57. {
  58. const ScopedLock sl (lock);
  59. if (inputChannelIndex >= 0 && inputChannelIndex < remappedInputs.size())
  60. return remappedInputs.getUnchecked (inputChannelIndex);
  61. return -1;
  62. }
  63. int ChannelRemappingAudioSource::getRemappedOutputChannel (const int outputChannelIndex) const
  64. {
  65. const ScopedLock sl (lock);
  66. if (outputChannelIndex >= 0 && outputChannelIndex < remappedOutputs.size())
  67. return remappedOutputs .getUnchecked (outputChannelIndex);
  68. return -1;
  69. }
  70. //==============================================================================
  71. void ChannelRemappingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
  72. {
  73. source->prepareToPlay (samplesPerBlockExpected, sampleRate);
  74. }
  75. void ChannelRemappingAudioSource::releaseResources()
  76. {
  77. source->releaseResources();
  78. }
  79. void ChannelRemappingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill)
  80. {
  81. const ScopedLock sl (lock);
  82. buffer.setSize (requiredNumberOfChannels, bufferToFill.numSamples, false, false, true);
  83. const int numChans = bufferToFill.buffer->getNumChannels();
  84. int i;
  85. for (i = 0; i < buffer.getNumChannels(); ++i)
  86. {
  87. const int remappedChan = getRemappedInputChannel (i);
  88. if (remappedChan >= 0 && remappedChan < numChans)
  89. {
  90. buffer.copyFrom (i, 0, *bufferToFill.buffer,
  91. remappedChan,
  92. bufferToFill.startSample,
  93. bufferToFill.numSamples);
  94. }
  95. else
  96. {
  97. buffer.clear (i, 0, bufferToFill.numSamples);
  98. }
  99. }
  100. remappedInfo.numSamples = bufferToFill.numSamples;
  101. source->getNextAudioBlock (remappedInfo);
  102. bufferToFill.clearActiveBufferRegion();
  103. for (i = 0; i < requiredNumberOfChannels; ++i)
  104. {
  105. const int remappedChan = getRemappedOutputChannel (i);
  106. if (remappedChan >= 0 && remappedChan < numChans)
  107. {
  108. bufferToFill.buffer->addFrom (remappedChan, bufferToFill.startSample,
  109. buffer, i, 0, bufferToFill.numSamples);
  110. }
  111. }
  112. }
  113. //==============================================================================
  114. XmlElement* ChannelRemappingAudioSource::createXml() const
  115. {
  116. XmlElement* e = new XmlElement ("MAPPINGS");
  117. String ins, outs;
  118. int i;
  119. const ScopedLock sl (lock);
  120. for (i = 0; i < remappedInputs.size(); ++i)
  121. ins << remappedInputs.getUnchecked(i) << ' ';
  122. for (i = 0; i < remappedOutputs.size(); ++i)
  123. outs << remappedOutputs.getUnchecked(i) << ' ';
  124. e->setAttribute ("inputs", ins.trimEnd());
  125. e->setAttribute ("outputs", outs.trimEnd());
  126. return e;
  127. }
  128. void ChannelRemappingAudioSource::restoreFromXml (const XmlElement& e)
  129. {
  130. if (e.hasTagName ("MAPPINGS"))
  131. {
  132. const ScopedLock sl (lock);
  133. clearAllMappings();
  134. StringArray ins, outs;
  135. ins.addTokens (e.getStringAttribute ("inputs"), false);
  136. outs.addTokens (e.getStringAttribute ("outputs"), false);
  137. int i;
  138. for (i = 0; i < ins.size(); ++i)
  139. remappedInputs.add (ins[i].getIntValue());
  140. for (i = 0; i < outs.size(); ++i)
  141. remappedOutputs.add (outs[i].getIntValue());
  142. }
  143. }
  144. END_JUCE_NAMESPACE