OpenShot Library | libopenshot-audio  0.1.9
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 //==============================================================================
149 {
150  XmlElement* e = new 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
void clearActiveBufferRegion() const
Convenient method to clear the buffer if the source is not producing any data.
void setInputChannelMapping(int destChannelIndex, int sourceChannelIndex)
Creates an input channel mapping.
bool hasTagName(StringRef possibleTagName) const noexcept
Tests whether this element has a particular tag name.
int numSamples
The number of samples in the buffer which the callback is expected to fill with data.
void add(const ElementType &newElement)
Appends a new element at the end of the array.
Definition: juce_Array.h:375
void setSize(int newNumChannels, int newNumSamples, bool keepExistingContent=false, bool clearExtraSpace=false, bool avoidReallocating=false)
Changes the buffer&#39;s size or number of channels.
Used to build a tree of elements representing an XML document.
int getRemappedOutputChannel(int outputChannelIndex) const
Returns the output channel to which channel outputChannelIndex of our input audio source will be sent...
ChannelRemappingAudioSource(AudioSource *source, bool deleteSourceWhenDeleted)
Creates a remapping source that will pass on audio from the given input.
A special array for holding a list of strings.
The JUCE String class!
Definition: juce_String.h:42
void setNumberOfChannelsToProduce(int requiredNumberOfChannels)
Specifies a number of channels that this audio source must produce from its getNextAudioBlock() callb...
XmlElement * createXml() const
Returns an XML object to encapsulate the state of the mappings.
int getRemappedInputChannel(int inputChannelIndex) const
Returns the channel from our input that will be sent to channel inputChannelIndex of our input audio ...
ElementType getUnchecked(int index) const
Returns one of the elements in the array, without checking the index passed in.
Definition: juce_Array.h:256
Base class for objects that can produce a continuous stream of audio.
int addTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
Breaks up a string into tokens and adds them to this array.
String trimEnd() const
Returns a copy of this string with any whitespace characters removed from the end.
void getNextAudioBlock(const AudioSourceChannelInfo &) override
Called repeatedly to fetch subsequent blocks of audio data.
int getNumChannels() const noexcept
Returns the number of channels of audio data that this buffer contains.
void setAttribute(const Identifier &attributeName, const String &newValue)
Adds a named attribute to the element.
void clearAllMappings()
Clears any mapped channels.
void setOutputChannelMapping(int sourceChannelIndex, int destChannelIndex)
Creates an output channel mapping.
void restoreFromXml(const XmlElement &)
Restores the mappings from an XML object created by createXML().
int startSample
The first sample in the buffer from which the callback is expected to write data. ...
void clear()
Removes all elements from the array.
Definition: juce_Array.h:192
int size() const noexcept
Returns the current number of elements in the array.
Definition: juce_Array.h:219
AudioBuffer< float > * buffer
The destination buffer to fill with audio data.
void addFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples, Type gainToApplyToSource=Type(1)) noexcept
Adds samples from another buffer to this one.
const String & getStringAttribute(StringRef attributeName) const noexcept
Returns the value of a named attribute.
void releaseResources() override
Allows the source to release anything it no longer needs after playback has stopped.
int size() const noexcept
Returns the number of strings in the array.
void prepareToPlay(int samplesPerBlockExpected, double sampleRate) override
Tells the source to prepare for playing.
void copyFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples) noexcept
Copies samples from another buffer to this one.
Used by AudioSource::getNextAudioBlock().
Automatically locks and unlocks a mutex object.
void set(int indexToChange, ParameterType newValue)
Replaces an element with a new value.
Definition: juce_Array.h:499
void clear() noexcept
Clears all the samples in all channels.