supernova: c++11 compile fix
[supercollider.git] / platform / mac / SuperColliderAU / AUSDK / AUScopeElement.h
blobd8852194ea4ec6200069e628167a1e2a67096991
1 /* Copyright © 2007 Apple Inc. All Rights Reserved.
3 Disclaimer: IMPORTANT: This Apple software is supplied to you by
4 Apple Inc. ("Apple") in consideration of your agreement to the
5 following terms, and your use, installation, modification or
6 redistribution of this Apple software constitutes acceptance of these
7 terms. If you do not agree with these terms, please do not use,
8 install, modify or redistribute this Apple software.
10 In consideration of your agreement to abide by the following terms, and
11 subject to these terms, Apple grants you a personal, non-exclusive
12 license, under Apple's copyrights in this original Apple software (the
13 "Apple Software"), to use, reproduce, modify and redistribute the Apple
14 Software, with or without modifications, in source and/or binary forms;
15 provided that if you redistribute the Apple Software in its entirety and
16 without modifications, you must retain this notice and the following
17 text and disclaimers in all such redistributions of the Apple Software.
18 Neither the name, trademarks, service marks or logos of Apple Inc.
19 may be used to endorse or promote products derived from the Apple
20 Software without specific prior written permission from Apple. Except
21 as expressly stated in this notice, no other rights or licenses, express
22 or implied, are granted by Apple herein, including but not limited to
23 any patent rights that may be infringed by your derivative works or by
24 other works in which the Apple Software may be incorporated.
26 The Apple Software is provided by Apple on an "AS IS" basis. APPLE
27 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
28 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
29 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
30 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
32 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
33 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
36 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
37 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
38 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
41 /*=============================================================================
42 AUScopeElement.h
44 =============================================================================*/
46 #ifndef __AUScopeElement_h__
47 #define __AUScopeElement_h__
49 #include <map>
50 #include <vector>
52 #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
53 #include <AudioUnit/AudioUnit.h>
54 #else
55 #include <AudioUnit.h>
56 #endif
57 #include "ComponentBase.h"
58 #include "AUBuffer.h"
61 class AUBase;
63 // ____________________________________________________________________________
65 // represents a parameter's value (either constant or ramped)
66 /*! @class ParameterMapEvent */
67 class ParameterMapEvent
69 public:
70 /*! @ctor ParameterMapEvent */
71 ParameterMapEvent()
72 : mEventType(kParameterEvent_Immediate), mBufferOffset(0), mDurationInFrames(0), mValue1(0.0), mValue2(0.0), mSliceDurationFrames(0)
75 /*! @ctor ParameterMapEvent */
76 ParameterMapEvent(AudioUnitParameterValue inValue)
77 : mEventType(kParameterEvent_Immediate), mBufferOffset(0), mDurationInFrames(0), mValue1(inValue), mValue2(inValue), mSliceDurationFrames(0)
80 // constructor for scheduled event
81 /*! @ctor ParameterMapEvent */
82 ParameterMapEvent( const AudioUnitParameterEvent &inEvent,
83 UInt32 inSliceOffsetInBuffer,
84 UInt32 inSliceDurationFrames )
86 SetScheduledEvent(inEvent, inSliceOffsetInBuffer, inSliceDurationFrames );
89 /*! @method SetScheduledEvent */
90 void SetScheduledEvent( const AudioUnitParameterEvent &inEvent,
91 UInt32 inSliceOffsetInBuffer,
92 UInt32 inSliceDurationFrames )
94 mEventType = inEvent.eventType;
95 mSliceDurationFrames = inSliceDurationFrames;
97 if(mEventType == kParameterEvent_Immediate )
99 // constant immediate value for the whole slice
100 mValue1 = inEvent.eventValues.immediate.value;
101 mValue2 = mValue1;
102 mDurationInFrames = inSliceDurationFrames;
103 mBufferOffset = 0;
105 else
107 mDurationInFrames = inEvent.eventValues.ramp.durationInFrames;
108 mBufferOffset = inEvent.eventValues.ramp.startBufferOffset - inSliceOffsetInBuffer; // shift over for this slice
109 mValue1 = inEvent.eventValues.ramp.startValue;
110 mValue2 = inEvent.eventValues.ramp.endValue;
116 /*! @method GetEventType */
117 AUParameterEventType GetEventType() const {return mEventType;};
119 /*! @method GetValue */
120 AudioUnitParameterValue GetValue() const {return mValue1;}; // only valid if immediate event type
121 /*! @method SetValue */
122 void SetValue(AudioUnitParameterValue inValue)
124 mEventType = kParameterEvent_Immediate;
125 mValue1 = inValue;
126 mValue2 = inValue;
129 // interpolates the start and end values corresponding to the current processing slice
130 // most ramp parameter implementations will want to use this method
131 // the start value will correspond to the start of the slice
132 // the end value will correspond to the end of the slice
133 /*! @method GetRampSliceStartEnd */
134 void GetRampSliceStartEnd( AudioUnitParameterValue & outStartValue,
135 AudioUnitParameterValue & outEndValue,
136 AudioUnitParameterValue & outValuePerFrameDelta )
138 if (mEventType == kParameterEvent_Ramped) {
139 outValuePerFrameDelta = (mValue2 - mValue1) / mDurationInFrames;
141 outStartValue = mValue1 + outValuePerFrameDelta * (-mBufferOffset); // corresponds to frame 0 of this slice
142 outEndValue = outStartValue + outValuePerFrameDelta * mSliceDurationFrames;
143 } else {
144 outValuePerFrameDelta = 0;
145 outStartValue = outEndValue = mValue1;
149 // Some ramp parameter implementations will want to interpret the ramp using their
150 // own interpolation method (perhaps non-linear)
151 // This method gives the raw ramp information, relative to this processing slice
152 // for the client to interpret as desired
153 /*! @method GetRampInfo */
154 void GetRampInfo( SInt32 & outBufferOffset,
155 UInt32 & outDurationInFrames,
156 AudioUnitParameterValue & outStartValue,
157 AudioUnitParameterValue & outEndValue )
159 outBufferOffset = mBufferOffset;
160 outDurationInFrames = mDurationInFrames;
161 outStartValue = mValue1;
162 outEndValue = mValue2;
165 #if DEBUG
166 void Print()
168 printf("ParameterEvent @ %p\n", this);
169 printf(" mEventType = %d\n", (int)mEventType);
170 printf(" mBufferOffset = %d\n", (int)mBufferOffset);
171 printf(" mDurationInFrames = %d\n", (int)mDurationInFrames);
172 printf(" mSliceDurationFrames = %d\n", (int)mSliceDurationFrames);
173 printf(" mValue1 = %.5f\n", mValue1);
174 printf(" mValue2 = %.5f\n", mValue2);
176 #endif
178 private:
179 AUParameterEventType mEventType;
181 SInt32 mBufferOffset; // ramp start offset relative to start of this slice (may be negative)
182 UInt32 mDurationInFrames; // total duration of ramp parameter
183 AudioUnitParameterValue mValue1; // value if immediate : startValue if ramp
184 AudioUnitParameterValue mValue2; // endValue (only used for ramp)
186 UInt32 mSliceDurationFrames; // duration of this processing slice
191 // ____________________________________________________________________________
194 /*! @class AUElement */
195 class AUElement {
196 public:
197 /*! @ctor AUElement */
198 AUElement(AUBase *audioUnit) : mAudioUnit(audioUnit),
199 mUseIndexedParameters(false), mElementName(0) { }
201 /*! @dtor ~AUElement */
202 virtual ~AUElement() { if (mElementName) CFRelease (mElementName); }
204 /*! @method GetNumberOfParameters */
205 UInt32 GetNumberOfParameters()
207 if(mUseIndexedParameters) return mIndexedParameters.size(); else return mParameters.size();
209 /*! @method GetParameterList */
210 void GetParameterList(AudioUnitParameterID *outList);
212 /*! @method GetParameter */
213 AudioUnitParameterValue GetParameter(AudioUnitParameterID paramID);
214 /*! @method SetParameter */
215 void SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue value);
217 // interpolates the start and end values corresponding to the current processing slice
218 // most ramp parameter implementations will want to use this method
219 /*! @method GetRampSliceStartEnd */
220 void GetRampSliceStartEnd( AudioUnitParameterID paramID,
221 AudioUnitParameterValue & outStartValue,
222 AudioUnitParameterValue & outEndValue,
223 AudioUnitParameterValue & outValuePerFrameDelta );
225 /*! @method SetRampParameter */
226 void SetScheduledEvent( AudioUnitParameterID paramID,
227 const AudioUnitParameterEvent &inEvent,
228 UInt32 inSliceOffsetInBuffer,
229 UInt32 inSliceDurationFrames );
232 /*! @method GetAudioUnit */
233 AUBase * GetAudioUnit() const { return mAudioUnit; };
235 /*! @method SaveState */
236 void SaveState(CFMutableDataRef data);
237 /*! @method RestoreState */
238 const UInt8 * RestoreState(const UInt8 *state);
239 /*! @method GetName */
240 CFStringRef GetName () const { return mElementName; }
241 /*! @method SetName */
242 void SetName (CFStringRef inName);
243 /*! @method HasName */
244 bool HasName () const { return mElementName != 0; }
245 /*! @method UseIndexedParameters */
246 virtual void UseIndexedParameters(int inNumberOfParameters);
248 protected:
249 inline ParameterMapEvent& GetParamEvent(AudioUnitParameterID paramID);
251 private:
252 typedef std::map<AudioUnitParameterID, ParameterMapEvent, std::less<AudioUnitParameterID> > ParameterMap;
254 /*! @var mAudioUnit */
255 AUBase * mAudioUnit;
256 /*! @var mParameters */
257 ParameterMap mParameters;
259 /*! @var mUseIndexedParameters */
260 bool mUseIndexedParameters;
261 /*! @var mIndexedParameters */
262 std::vector<ParameterMapEvent> mIndexedParameters;
264 /*! @var mElementName */
265 CFStringRef mElementName;
270 // ____________________________________________________________________________
272 /*! @class AUIOElement */
273 class AUIOElement : public AUElement {
274 public:
275 /*! @ctor AUIOElement */
276 AUIOElement(AUBase *audioUnit);
278 /*! @method GetStreamFormat */
279 const CAStreamBasicDescription &GetStreamFormat() const { return mStreamFormat; }
281 /*! @method SetStreamFormat */
282 virtual OSStatus SetStreamFormat(const CAStreamBasicDescription &desc);
284 /*! @method AllocateBuffer */
285 void AllocateBuffer(UInt32 inFramesToAllocate = 0);
286 /*! @method DeallocateBuffer */
287 void DeallocateBuffer();
288 /*! @method NeedsBufferSpace */
289 virtual bool NeedsBufferSpace() const = 0;
291 /*! @method UseExternalBuffer */
292 void UseExternalBuffer(const AudioUnitExternalBuffer &buf) {
293 mIOBuffer.UseExternalBuffer(mStreamFormat, buf);
295 /*! @method PrepareBuffer */
296 AudioBufferList & PrepareBuffer(UInt32 nFrames) {
297 return mIOBuffer.PrepareBuffer(mStreamFormat, nFrames);
299 /*! @method PrepareNullBuffer */
300 AudioBufferList & PrepareNullBuffer(UInt32 nFrames) {
301 return mIOBuffer.PrepareNullBuffer(mStreamFormat, nFrames);
303 /*! @method SetBufferList */
304 AudioBufferList & SetBufferList(AudioBufferList &abl) { return mIOBuffer.SetBufferList(abl); }
305 /*! @method SetBuffer */
306 void SetBuffer(UInt32 index, AudioBuffer &ab) { mIOBuffer.SetBuffer(index, ab); }
307 /*! @method InvalidateBufferList */
308 void InvalidateBufferList() { mIOBuffer.InvalidateBufferList(); }
310 /*! @method GetBufferList */
311 AudioBufferList & GetBufferList() const { return mIOBuffer.GetBufferList(); }
313 /*! @method GetChannelData */
314 float * GetChannelData(int ch) const {
315 if (mStreamFormat.IsInterleaved())
316 return static_cast<float *>(mIOBuffer.GetBufferList().mBuffers[0].mData) + ch;
317 else
318 return static_cast<float *>(mIOBuffer.GetBufferList().mBuffers[ch].mData);
321 /*! @method CopyBufferListTo */
322 void CopyBufferListTo(AudioBufferList &abl) const {
323 mIOBuffer.CopyBufferListTo(abl);
325 /*! @method CopyBufferContentsTo */
326 void CopyBufferContentsTo(AudioBufferList &abl) const {
327 mIOBuffer.CopyBufferContentsTo(abl);
330 /* UInt32 BytesToFrames(UInt32 nBytes) { return nBytes / mStreamFormat.mBytesPerFrame; }
331 UInt32 BytesToFrames(AudioBufferList &abl) {
332 return BytesToFrames(abl.mBuffers[0].mDataByteSize);
334 UInt32 FramesToBytes(UInt32 nFrames) { return nFrames * mStreamFormat.mBytesPerFrame; }*/
336 /*! @method IsInterleaved */
337 bool IsInterleaved() const { return mStreamFormat.IsInterleaved(); }
338 /*! @method NumberChannels */
339 UInt32 NumberChannels() const { return mStreamFormat.NumberChannels(); }
340 /*! @method NumberInterleavedChannels */
341 UInt32 NumberInterleavedChannels() const { return mStreamFormat.NumberInterleavedChannels(); }
343 /*! @method GetChannelMapTags */
344 virtual UInt32 GetChannelLayoutTags (AudioChannelLayoutTag *outLayoutTagsPtr);
346 /*! @method GetAudioChannelLayout */
347 virtual UInt32 GetAudioChannelLayout (AudioChannelLayout *outMapPtr, Boolean &outWritable);
349 /*! @method SetAudioChannelLayout */
350 virtual OSStatus SetAudioChannelLayout (const AudioChannelLayout &inData);
352 /*! @method RemoveAudioChannelLayout */
353 virtual OSStatus RemoveAudioChannelLayout ();
355 protected:
356 /*! @var mStreamFormat */
357 CAStreamBasicDescription mStreamFormat;
358 /*! @var mIOBuffer */
359 AUBufferList mIOBuffer; // for input: input proc buffer, only allocated when needed
360 // for output: output cache, usually allocated early on
363 // ____________________________________________________________________________
365 /*! @class AUElementCreator */
366 class AUElementCreator {
367 public:
368 /*! @method CreateElement */
369 virtual AUElement * CreateElement(AudioUnitScope scope, AudioUnitElement element) = 0;
370 virtual ~AUElementCreator() { }
373 // ____________________________________________________________________________
375 // AUScopeDelegates are a way to get virtual scopes.
376 /*! @class AUScopeDelegate */
377 class AUScopeDelegate {
378 public:
379 /*! @ctor AUScopeDelegate */
380 AUScopeDelegate() : mCreator(NULL), mScope(0) { }
381 /*! @dtor ~AUScopeDelegate */
382 virtual ~AUScopeDelegate() {}
384 /*! @method Initialize */
385 virtual void Initialize( AUElementCreator *creator,
386 AudioUnitScope scope,
387 UInt32 numElements)
389 mCreator = creator;
390 mScope = scope;
391 SetNumberOfElements(numElements);
394 /*! @method SetNumberOfElements */
395 virtual void SetNumberOfElements(UInt32 numElements) = 0;
397 /*! @method GetNumberOfElements */
398 virtual UInt32 GetNumberOfElements() = 0;
400 /*! @method GetElement */
401 virtual AUElement * GetElement(UInt32 elementIndex) = 0;
403 AUElementCreator * GetCreator() const { return mCreator; }
404 AudioUnitScope GetScope() const { return mScope; }
407 private:
408 /*! @var mCreator */
409 AUElementCreator * mCreator;
410 /*! @var mScope */
411 AudioUnitScope mScope;
416 // ____________________________________________________________________________
418 /*! @class AUScope */
419 class AUScope {
420 public:
421 /*! @ctor AUScope */
422 AUScope() : mCreator(NULL), mScope(0), mDelegate(0) { }
423 /*! @dtor ~AUScope */
424 ~AUScope();
426 /*! @method Initialize */
427 void Initialize(AUElementCreator *creator,
428 AudioUnitScope scope,
429 UInt32 numElements)
431 if (mDelegate)
432 return mDelegate->Initialize(creator, scope, numElements);
434 mCreator = creator;
435 mScope = scope;
436 SetNumberOfElements(numElements);
439 /*! @method SetNumberOfElements */
440 void SetNumberOfElements(UInt32 numElements);
442 /*! @method GetNumberOfElements */
443 UInt32 GetNumberOfElements() const
445 if (mDelegate)
446 return mDelegate->GetNumberOfElements();
448 return mElements.size();
451 /*! @method GetElement */
452 AUElement * GetElement(UInt32 elementIndex) const
454 if (mDelegate)
455 return mDelegate->GetElement(elementIndex);
457 ElementVector::const_iterator i = mElements.begin() + elementIndex;
458 // catch passing -1 in as the elementIndex - causes a wrap around
459 return (i >= mElements.end() || i < mElements.begin()) ? NULL : *i;
462 /*! @method SafeGetElement */
463 AUElement * SafeGetElement(UInt32 elementIndex)
465 AUElement *element = GetElement(elementIndex);
466 if (element == NULL)
467 COMPONENT_THROW(kAudioUnitErr_InvalidElement);
468 return element;
471 /*! @method GetIOElement */
472 AUIOElement * GetIOElement(UInt32 elementIndex) const
474 AUElement *element = GetElement(elementIndex);
475 AUIOElement *ioel;
476 if (element == NULL || (ioel = dynamic_cast<AUIOElement *>(element)) == NULL)
477 COMPONENT_THROW (kAudioUnitErr_InvalidElement);
478 return ioel;
481 /*! @method HasElementWithName */
482 bool HasElementWithName () const;
484 /*! @method AddElementNamesToDict */
485 void AddElementNamesToDict (CFMutableDictionaryRef & inNameDict);
487 bool RestoreElementNames (CFDictionaryRef& inNameDict);
489 AUElementCreator * GetCreator() const { return mCreator; }
490 AudioUnitScope GetScope() const { return mScope; }
492 void SetDelegate(AUScopeDelegate* inDelegate) { mDelegate = inDelegate; }
494 private:
495 typedef std::vector<AUElement *> ElementVector;
496 /*! @var mCreator */
497 AUElementCreator * mCreator;
498 /*! @var mScope */
499 AudioUnitScope mScope;
500 /*! @var mElements */
501 ElementVector mElements;
502 /*! @var mDelegate */
503 AUScopeDelegate * mDelegate;
508 #endif // __AUScopeElement_h__