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 /*=============================================================================
44 =============================================================================*/
46 #ifndef __AUScopeElement_h__
47 #define __AUScopeElement_h__
52 #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
53 #include <AudioUnit/AudioUnit.h>
55 #include <AudioUnit.h>
57 #include "ComponentBase.h"
63 // ____________________________________________________________________________
65 // represents a parameter's value (either constant or ramped)
66 /*! @class ParameterMapEvent */
67 class ParameterMapEvent
70 /*! @ctor 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
;
102 mDurationInFrames
= inSliceDurationFrames
;
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
;
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
;
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
;
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
);
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 */
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
);
249 inline ParameterMapEvent
& GetParamEvent(AudioUnitParameterID paramID
);
252 typedef std::map
<AudioUnitParameterID
, ParameterMapEvent
, std::less
<AudioUnitParameterID
> > ParameterMap
;
254 /*! @var 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
{
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
;
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 ();
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
{
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
{
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
,
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
; }
409 AUElementCreator
* mCreator
;
411 AudioUnitScope mScope
;
416 // ____________________________________________________________________________
418 /*! @class AUScope */
422 AUScope() : mCreator(NULL
), mScope(0), mDelegate(0) { }
423 /*! @dtor ~AUScope */
426 /*! @method Initialize */
427 void Initialize(AUElementCreator
*creator
,
428 AudioUnitScope scope
,
432 return mDelegate
->Initialize(creator
, scope
, numElements
);
436 SetNumberOfElements(numElements
);
439 /*! @method SetNumberOfElements */
440 void SetNumberOfElements(UInt32 numElements
);
442 /*! @method GetNumberOfElements */
443 UInt32
GetNumberOfElements() const
446 return mDelegate
->GetNumberOfElements();
448 return mElements
.size();
451 /*! @method GetElement */
452 AUElement
* GetElement(UInt32 elementIndex
) const
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
);
467 COMPONENT_THROW(kAudioUnitErr_InvalidElement
);
471 /*! @method GetIOElement */
472 AUIOElement
* GetIOElement(UInt32 elementIndex
) const
474 AUElement
*element
= GetElement(elementIndex
);
476 if (element
== NULL
|| (ioel
= dynamic_cast<AUIOElement
*>(element
)) == NULL
)
477 COMPONENT_THROW (kAudioUnitErr_InvalidElement
);
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
; }
495 typedef std::vector
<AUElement
*> ElementVector
;
497 AUElementCreator
* mCreator
;
499 AudioUnitScope mScope
;
500 /*! @var mElements */
501 ElementVector mElements
;
502 /*! @var mDelegate */
503 AUScopeDelegate
* mDelegate
;
508 #endif // __AUScopeElement_h__