2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../../core/juce_StandardHeader.h"
30 #include "juce_AudioProcessor.h"
31 #include "../../text/juce_XmlDocument.h"
34 //==============================================================================
35 AudioProcessor::AudioProcessor()
40 numOutputChannels (0),
47 AudioProcessor::~AudioProcessor()
49 // ooh, nasty - the editor should have been deleted before the filter
50 // that it refers to is deleted..
51 jassert (activeEditor
== nullptr);
54 // This will fail if you've called beginParameterChangeGesture() for one
55 // or more parameters without having made a corresponding call to endParameterChangeGesture...
56 jassert (changingParams
.countNumberOfSetBits() == 0);
60 void AudioProcessor::setPlayHead (AudioPlayHead
* const newPlayHead
) noexcept
62 playHead
= newPlayHead
;
65 void AudioProcessor::addListener (AudioProcessorListener
* const newListener
)
67 const ScopedLock
sl (listenerLock
);
68 listeners
.addIfNotAlreadyThere (newListener
);
71 void AudioProcessor::removeListener (AudioProcessorListener
* const listenerToRemove
)
73 const ScopedLock
sl (listenerLock
);
74 listeners
.removeValue (listenerToRemove
);
77 void AudioProcessor::setPlayConfigDetails (const int numIns
,
79 const double sampleRate_
,
80 const int blockSize_
) noexcept
82 numInputChannels
= numIns
;
83 numOutputChannels
= numOuts
;
84 sampleRate
= sampleRate_
;
85 blockSize
= blockSize_
;
88 void AudioProcessor::setNonRealtime (const bool nonRealtime_
) noexcept
90 nonRealtime
= nonRealtime_
;
93 void AudioProcessor::setLatencySamples (const int newLatency
)
95 if (latencySamples
!= newLatency
)
97 latencySamples
= newLatency
;
102 void AudioProcessor::setParameterNotifyingHost (const int parameterIndex
,
103 const float newValue
)
105 setParameter (parameterIndex
, newValue
);
106 sendParamChangeMessageToListeners (parameterIndex
, newValue
);
109 void AudioProcessor::sendParamChangeMessageToListeners (const int parameterIndex
, const float newValue
)
111 jassert (isPositiveAndBelow (parameterIndex
, getNumParameters()));
113 for (int i
= listeners
.size(); --i
>= 0;)
115 AudioProcessorListener
* l
;
118 const ScopedLock
sl (listenerLock
);
123 l
->audioProcessorParameterChanged (this, parameterIndex
, newValue
);
127 void AudioProcessor::beginParameterChangeGesture (int parameterIndex
)
129 jassert (isPositiveAndBelow (parameterIndex
, getNumParameters()));
132 // This means you've called beginParameterChangeGesture twice in succession without a matching
133 // call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it.
134 jassert (! changingParams
[parameterIndex
]);
135 changingParams
.setBit (parameterIndex
);
138 for (int i
= listeners
.size(); --i
>= 0;)
140 AudioProcessorListener
* l
;
143 const ScopedLock
sl (listenerLock
);
148 l
->audioProcessorParameterChangeGestureBegin (this, parameterIndex
);
152 void AudioProcessor::endParameterChangeGesture (int parameterIndex
)
154 jassert (isPositiveAndBelow (parameterIndex
, getNumParameters()));
157 // This means you've called endParameterChangeGesture without having previously called
158 // endParameterChangeGesture. That might be fine in most hosts, but better to keep the
159 // calls matched correctly.
160 jassert (changingParams
[parameterIndex
]);
161 changingParams
.clearBit (parameterIndex
);
164 for (int i
= listeners
.size(); --i
>= 0;)
166 AudioProcessorListener
* l
;
169 const ScopedLock
sl (listenerLock
);
174 l
->audioProcessorParameterChangeGestureEnd (this, parameterIndex
);
178 void AudioProcessor::updateHostDisplay()
180 for (int i
= listeners
.size(); --i
>= 0;)
182 AudioProcessorListener
* l
;
185 const ScopedLock
sl (listenerLock
);
190 l
->audioProcessorChanged (this);
194 bool AudioProcessor::isParameterAutomatable (int /*parameterIndex*/) const
199 bool AudioProcessor::isMetaParameter (int /*parameterIndex*/) const
204 void AudioProcessor::suspendProcessing (const bool shouldBeSuspended
)
206 const ScopedLock
sl (callbackLock
);
207 suspended
= shouldBeSuspended
;
210 void AudioProcessor::reset()
214 //==============================================================================
215 void AudioProcessor::editorBeingDeleted (AudioProcessorEditor
* const editor
) noexcept
217 const ScopedLock
sl (callbackLock
);
219 if (activeEditor
== editor
)
220 activeEditor
= nullptr;
223 AudioProcessorEditor
* AudioProcessor::createEditorIfNeeded()
225 if (activeEditor
!= nullptr)
228 AudioProcessorEditor
* const ed
= createEditor();
230 // You must make your hasEditor() method return a consistent result!
231 jassert (hasEditor() == (ed
!= nullptr));
235 // you must give your editor comp a size before returning it..
236 jassert (ed
->getWidth() > 0 && ed
->getHeight() > 0);
238 const ScopedLock
sl (callbackLock
);
245 //==============================================================================
246 void AudioProcessor::getCurrentProgramStateInformation (JUCE_NAMESPACE::MemoryBlock
& destData
)
248 getStateInformation (destData
);
251 void AudioProcessor::setCurrentProgramStateInformation (const void* data
, int sizeInBytes
)
253 setStateInformation (data
, sizeInBytes
);
256 //==============================================================================
257 // magic number to identify memory blocks that we've stored as XML
258 const uint32 magicXmlNumber
= 0x21324356;
260 void AudioProcessor::copyXmlToBinary (const XmlElement
& xml
,
261 JUCE_NAMESPACE::MemoryBlock
& destData
)
263 const String
xmlString (xml
.createDocument (String::empty
, true, false));
264 const int stringLength
= xmlString
.getNumBytesAsUTF8();
266 destData
.setSize (stringLength
+ 10);
268 char* const d
= static_cast<char*> (destData
.getData());
269 *(uint32
*) d
= ByteOrder::swapIfBigEndian ((const uint32
) magicXmlNumber
);
270 *(uint32
*) (d
+ 4) = ByteOrder::swapIfBigEndian ((const uint32
) stringLength
);
272 xmlString
.copyToUTF8 (d
+ 8, stringLength
+ 1);
275 XmlElement
* AudioProcessor::getXmlFromBinary (const void* data
,
276 const int sizeInBytes
)
279 && ByteOrder::littleEndianInt (data
) == magicXmlNumber
)
281 const int stringLength
= (int) ByteOrder::littleEndianInt (addBytesToPointer (data
, 4));
283 if (stringLength
> 0)
284 return XmlDocument::parse (String::fromUTF8 (static_cast<const char*> (data
) + 8,
285 jmin ((sizeInBytes
- 8), stringLength
)));
291 //==============================================================================
292 void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor
*, int) {}
293 void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor
*, int) {}
295 //==============================================================================
296 bool AudioPlayHead::CurrentPositionInfo::operator== (const CurrentPositionInfo
& other
) const noexcept
298 return timeInSeconds
== other
.timeInSeconds
299 && ppqPosition
== other
.ppqPosition
300 && editOriginTime
== other
.editOriginTime
301 && ppqPositionOfLastBarStart
== other
.ppqPositionOfLastBarStart
302 && frameRate
== other
.frameRate
303 && isPlaying
== other
.isPlaying
304 && isRecording
== other
.isRecording
306 && timeSigNumerator
== other
.timeSigNumerator
307 && timeSigDenominator
== other
.timeSigDenominator
;
310 bool AudioPlayHead::CurrentPositionInfo::operator!= (const CurrentPositionInfo
& other
) const noexcept
312 return ! operator== (other
);
315 void AudioPlayHead::CurrentPositionInfo::resetToDefault()
318 timeSigNumerator
= 4;
319 timeSigDenominator
= 4;