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