OpenShot Audio Library | OpenShotAudio  0.3.2
juce_ChannelRemappingAudioSource.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
27  const bool deleteSourceWhenDeleted)
28  : source (source_, deleteSourceWhenDeleted),
29  requiredNumberOfChannels (2)
30 {
31  remappedInfo.buffer = &buffer;
32  remappedInfo.startSample = 0;
33 }
34 
36 
37 //==============================================================================
38 void ChannelRemappingAudioSource::setNumberOfChannelsToProduce (const int requiredNumberOfChannels_)
39 {
40  const ScopedLock sl (lock);
41  requiredNumberOfChannels = requiredNumberOfChannels_;
42 }
43 
45 {
46  const ScopedLock sl (lock);
47 
48  remappedInputs.clear();
49  remappedOutputs.clear();
50 }
51 
52 void ChannelRemappingAudioSource::setInputChannelMapping (const int destIndex, const int sourceIndex)
53 {
54  const ScopedLock sl (lock);
55 
56  while (remappedInputs.size() < destIndex)
57  remappedInputs.add (-1);
58 
59  remappedInputs.set (destIndex, sourceIndex);
60 }
61 
62 void ChannelRemappingAudioSource::setOutputChannelMapping (const int sourceIndex, const int destIndex)
63 {
64  const ScopedLock sl (lock);
65 
66  while (remappedOutputs.size() < sourceIndex)
67  remappedOutputs.add (-1);
68 
69  remappedOutputs.set (sourceIndex, destIndex);
70 }
71 
72 int ChannelRemappingAudioSource::getRemappedInputChannel (const int inputChannelIndex) const
73 {
74  const ScopedLock sl (lock);
75 
76  if (inputChannelIndex >= 0 && inputChannelIndex < remappedInputs.size())
77  return remappedInputs.getUnchecked (inputChannelIndex);
78 
79  return -1;
80 }
81 
82 int ChannelRemappingAudioSource::getRemappedOutputChannel (const int outputChannelIndex) const
83 {
84  const ScopedLock sl (lock);
85 
86  if (outputChannelIndex >= 0 && outputChannelIndex < remappedOutputs.size())
87  return remappedOutputs .getUnchecked (outputChannelIndex);
88 
89  return -1;
90 }
91 
92 //==============================================================================
93 void ChannelRemappingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
94 {
95  source->prepareToPlay (samplesPerBlockExpected, sampleRate);
96 }
97 
99 {
100  source->releaseResources();
101 }
102 
104 {
105  const ScopedLock sl (lock);
106 
107  buffer.setSize (requiredNumberOfChannels, bufferToFill.numSamples, false, false, true);
108 
109  const int numChans = bufferToFill.buffer->getNumChannels();
110 
111  for (int i = 0; i < buffer.getNumChannels(); ++i)
112  {
113  const int remappedChan = getRemappedInputChannel (i);
114 
115  if (remappedChan >= 0 && remappedChan < numChans)
116  {
117  buffer.copyFrom (i, 0, *bufferToFill.buffer,
118  remappedChan,
119  bufferToFill.startSample,
120  bufferToFill.numSamples);
121  }
122  else
123  {
124  buffer.clear (i, 0, bufferToFill.numSamples);
125  }
126  }
127 
128  remappedInfo.numSamples = bufferToFill.numSamples;
129 
130  source->getNextAudioBlock (remappedInfo);
131 
132  bufferToFill.clearActiveBufferRegion();
133 
134  for (int i = 0; i < requiredNumberOfChannels; ++i)
135  {
136  const int remappedChan = getRemappedOutputChannel (i);
137 
138  if (remappedChan >= 0 && remappedChan < numChans)
139  {
140  bufferToFill.buffer->addFrom (remappedChan, bufferToFill.startSample,
141  buffer, i, 0, bufferToFill.numSamples);
142 
143  }
144  }
145 }
146 
147 //==============================================================================
148 std::unique_ptr<XmlElement> ChannelRemappingAudioSource::createXml() const
149 {
150  auto e = std::make_unique<XmlElement> ("MAPPINGS");
151  String ins, outs;
152 
153  const ScopedLock sl (lock);
154 
155  for (int i = 0; i < remappedInputs.size(); ++i)
156  ins << remappedInputs.getUnchecked(i) << ' ';
157 
158  for (int i = 0; i < remappedOutputs.size(); ++i)
159  outs << remappedOutputs.getUnchecked(i) << ' ';
160 
161  e->setAttribute ("inputs", ins.trimEnd());
162  e->setAttribute ("outputs", outs.trimEnd());
163 
164  return e;
165 }
166 
168 {
169  if (e.hasTagName ("MAPPINGS"))
170  {
171  const ScopedLock sl (lock);
172 
174 
175  StringArray ins, outs;
176  ins.addTokens (e.getStringAttribute ("inputs"), false);
177  outs.addTokens (e.getStringAttribute ("outputs"), false);
178 
179  for (int i = 0; i < ins.size(); ++i)
180  remappedInputs.add (ins[i].getIntValue());
181 
182  for (int i = 0; i < outs.size(); ++i)
183  remappedOutputs.add (outs[i].getIntValue());
184  }
185 }
186 
187 } // namespace juce
ElementType getUnchecked(int index) const
Definition: juce_Array.h:252
int size() const noexcept
Definition: juce_Array.h:215
void add(const ElementType &newElement)
Definition: juce_Array.h:418
void set(int indexToChange, ParameterType newValue)
Definition: juce_Array.h:542
void clear()
Definition: juce_Array.h:188
void setSize(int newNumChannels, int newNumSamples, bool keepExistingContent=false, bool clearExtraSpace=false, bool avoidReallocating=false)
int getNumChannels() const noexcept
void copyFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples) noexcept
void addFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples, Type gainToApplyToSource=Type(1)) noexcept
void setOutputChannelMapping(int sourceChannelIndex, int destChannelIndex)
void getNextAudioBlock(const AudioSourceChannelInfo &) override
void prepareToPlay(int samplesPerBlockExpected, double sampleRate) override
void setNumberOfChannelsToProduce(int requiredNumberOfChannels)
int getRemappedInputChannel(int inputChannelIndex) const
int getRemappedOutputChannel(int outputChannelIndex) const
ChannelRemappingAudioSource(AudioSource *source, bool deleteSourceWhenDeleted)
std::unique_ptr< XmlElement > createXml() const
void setInputChannelMapping(int destChannelIndex, int sourceChannelIndex)
int size() const noexcept
int addTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
String trimEnd() const
bool hasTagName(StringRef possibleTagName) const noexcept
const String & getStringAttribute(StringRef attributeName) const noexcept
AudioBuffer< float > * buffer