LV2 support.
[ardour.git] / libs / appleutility / CAAudioUnit.h
1 /*      Copyright:      � Copyright 2005 Apple Computer, Inc. All rights reserved.
2
3         Disclaimer:     IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
4                         ("Apple") in consideration of your agreement to the following terms, and your
5                         use, installation, modification or redistribution of this Apple software
6                         constitutes acceptance of these terms.  If you do not agree with these terms,
7                         please do not use, install, modify or redistribute this Apple software.
8
9                         In consideration of your agreement to abide by the following terms, and subject
10                         to these terms, Apple grants you a personal, non-exclusive license, under Apple�s
11                         copyrights in this original Apple software (the "Apple Software"), to use,
12                         reproduce, modify and redistribute the Apple Software, with or without
13                         modifications, in source and/or binary forms; provided that if you redistribute
14                         the Apple Software in its entirety and without modifications, you must retain
15                         this notice and the following text and disclaimers in all such redistributions of
16                         the Apple Software.  Neither the name, trademarks, service marks or logos of
17                         Apple Computer, Inc. may be used to endorse or promote products derived from the
18                         Apple Software without specific prior written permission from Apple.  Except as
19                         expressly stated in this notice, no other rights or licenses, express or implied,
20                         are granted by Apple herein, including but not limited to any patent rights that
21                         may be infringed by your derivative works or by other works in which the Apple
22                         Software may be incorporated.
23
24                         The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
25                         WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
26                         WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27                         PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
28                         COMBINATION WITH YOUR PRODUCTS.
29
30                         IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
31                         CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
32                         GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33                         ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
34                         OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
35                         (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
36                         ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 */
38 /*=============================================================================
39         CAAudioUnit.h
40  
41 =============================================================================*/
42
43 #ifndef __CAAudioUnit_h__
44 #define __CAAudioUnit_h__
45
46 #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
47         #include <CoreServices/CoreServices.h>
48         #include <CoreAudio/CoreAudio.h>
49         #include <AudioUnit/AudioUnit.h>
50         #include <AudioToolbox/AUGraph.h>
51 #else
52         #include <ConditionalMacros.h>
53         #include <CoreServices.h>
54         #include <CoreAudioTypes.h>
55         #include <AudioUnit.h>
56         #include <AUGraph.h>
57 #endif
58
59 #include <vector>
60 #include "CAStreamBasicDescription.h"
61 #include "CAComponent.h"
62 #include "CAAudioChannelLayout.h"
63
64 // defined below
65 class CAAUChanHelper;
66
67 // These constructors will NOT throw exceptions - so "check" after creation if AU IsValid()
68 // The destructor will NOT automatically close the AU down
69 // This state should be managed by the Caller
70 // once closed, the unit represented by this object is no longer valid
71 // it is up to the user of this object to ensure its validity is in sync 
72 // if it is removed from a graph
73
74 // methods that can significantly change the state of the AU (like its format) are
75 // NOT const whereas those that don't change the externally related state of the AU are not const
76
77 class CAAudioUnit {
78 public:
79         typedef std::vector<AudioChannelLayoutTag>      ChannelTagVector;
80         typedef ChannelTagVector::iterator                      ChannelTagVectorIter;
81
82 public:
83                                                         CAAudioUnit () 
84                                                                 : mDataPtr(0) {}
85
86                                                         CAAudioUnit (const AudioUnit& inUnit);
87
88                                                         CAAudioUnit (const AUNode &inNode, const AudioUnit& inUnit);
89
90                                                         CAAudioUnit (const CAAudioUnit& y)
91                                                                 : mDataPtr(0) { *this = y; }
92
93         static OSStatus                 Open (const CAComponent& inComp, CAAudioUnit &outUnit);
94
95                                                         ~CAAudioUnit ();
96
97         
98         CAAudioUnit&                    operator= (const CAAudioUnit& y);
99
100         bool                                    operator== (const CAAudioUnit& y) const;
101
102         bool                                    operator== (const AudioUnit& y) const;
103
104 #pragma mark __State Management 
105         bool                                    IsValid () const;
106         
107         AudioUnit                               AU() const;
108         operator AudioUnit () const { return AU(); }
109
110         const CAComponent&              Comp() const { return mComp; }
111         
112         bool                                    FromAUGraph () const { return GetAUNode() != 0 || GetAUNode() != -1; }
113         
114         AUNode                                  GetAUNode () const;
115         operator AUNode () const { return GetAUNode(); }
116         
117 #pragma mark __API Wrapper
118         OSStatus                                Initialize() const { return AudioUnitInitialize(AU()); }
119         OSStatus                                Uninitialize() const { return AudioUnitUninitialize(AU()); }
120         OSStatus                                GetPropertyInfo(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
121                                                                                         UInt32 *outDataSize, Boolean *outWritable) const
122                                                         {
123                                                                 return AudioUnitGetPropertyInfo(AU(), propID, scope, element, outDataSize, outWritable);
124                                                         }
125         OSStatus                                GetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
126                                                                                         void *outData, UInt32 *ioDataSize) const
127                                                         {
128                                                                 return AudioUnitGetProperty(AU(), propID, scope, element, outData, ioDataSize);
129                                                         }
130         OSStatus                                SetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
131                                                                                         const void *inData, UInt32 inDataSize)
132                                                         {
133                                                                 return AudioUnitSetProperty(AU(), propID, scope, element, inData, inDataSize);
134                                                         }
135         OSStatus                                SetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
136                                                                                         Float32 value, UInt32 bufferOffsetFrames=0);
137                                                         
138         OSStatus                                GetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
139                                                                                         Float32 &outValue) const;
140
141         OSStatus                                Render (AudioUnitRenderActionFlags                              * ioActionFlags,
142                                                                                                 const AudioTimeStamp            * inTimeStamp,
143                                                                                                 UInt32                                          inOutputBusNumber,
144                                                                                                 UInt32                                          inNumberFrames,
145                                                                                                 AudioBufferList                         * ioData);
146                                                                                                                         
147         OSStatus                                Reset (AudioUnitScope scope, AudioUnitElement element)
148                                                         {
149                                                                 return AudioUnitReset (AU(), scope, element);
150                                                         }
151         OSStatus                                GlobalReset ()
152                                                         {
153                                                                 return AudioUnitReset (AU(), kAudioUnitScope_Global, 0);
154                                                         }
155
156         OSStatus                                Preroll (UInt32 inFrameSize);
157
158         OSStatus                                AddRenderNotify (AURenderCallback   inProc, void *inProcRefCon)
159                                                         {
160                                                                 return AudioUnitAddRenderNotify (AU(), inProc, inProcRefCon);
161                                                         }
162         
163         OSStatus                                RemoveRenderNotify (AURenderCallback   inProc, void *inProcRefCon)
164                                                         {
165                                                                 return AudioUnitRemoveRenderNotify (AU(), inProc, inProcRefCon);
166                                                         }
167         
168
169 // Fast dispatch support for MIDI Effects or Music Devices      
170         OSStatus                                MIDIEvent (UInt32                                       inStatus,
171                                                                                 UInt32                                  inData1,
172                                                                                 UInt32                                  inData2,
173                                                                                 UInt32                                  inOffsetSampleFrame);
174                                                                 
175                                                                 // uses the default VoiceForGroup value - this is the normal case
176         OSStatus                                StartNote (MusicDeviceGroupID           inGroupID,
177                                                                         NoteInstanceID *                        outNoteInstanceID,
178                                                                         UInt32                                          inOffsetSampleFrame,
179                                                                         const MusicDeviceNoteParams * inParams)
180                                                         {
181                                                                 return StartNote (kMusicNoteEvent_UseGroupInstrument, 
182                                                                                                         inGroupID, outNoteInstanceID, 
183                                                                                                         inOffsetSampleFrame, inParams);
184                                                         }
185
186         OSStatus                                StartNote (MusicDeviceInstrumentID      inInstrument,
187                                                                         MusicDeviceGroupID                      inGroupID,
188                                                                         NoteInstanceID *                        outNoteInstanceID,
189                                                                         UInt32                                          inOffsetSampleFrame,
190                                                                         const MusicDeviceNoteParams * inParams);
191
192         OSStatus                                StopNote (MusicDeviceGroupID            inGroupID,
193                                                                         NoteInstanceID                          inNoteInstanceID,
194                                                                         UInt32                                          inOffsetSampleFrame);
195
196 #pragma mark __Format Utilities
197                 // typically you ask this about an AU
198                 // These Questions are asking about Input and Output...
199
200                 // These ones just say whether an AU can do a single combination of channels
201                 // and is fine if the AU has a single output (and if an input, a single input)
202         bool                                    CanDo (int inChannelsInOut) const
203                                                         {
204                                                                 return CanDo (inChannelsInOut, inChannelsInOut);
205                                                         }
206                                                         
207         bool                                    CanDo (         int                             inChannelsIn, 
208                                                                                 int                             inChannelsOut) const;
209                 
210                 // This version does a more thorough test for ANY AU with ANY ins/outs
211                 // you pass in the channel helper (for the current element count on that scope)
212                 
213         bool                                    CanDo (         const CAAUChanHelper            &input,
214                                                                                 const CAAUChanHelper            &output) const;
215         
216         bool                                    SupportsNumChannels () const;
217         
218         bool                                    HasChannelLayouts (AudioUnitScope               inScope, 
219                                                                                         AudioUnitElement                inEl) const;
220                 
221         bool                                    GetChannelLayouts (AudioUnitScope               inScope,
222                                                                         AudioUnitElement                                inEl,
223                                                                         ChannelTagVector                                &outChannelVector) const;
224         
225         OSStatus                                GetChannelLayout (AudioUnitScope                inScope,
226                                                                                         AudioUnitElement                inEl,
227                                                                                         CAAudioChannelLayout    &outLayout) const;      
228
229         OSStatus                                SetChannelLayout (AudioUnitScope                inScope, 
230                                                                                         AudioUnitElement                inEl,
231                                                                                         CAAudioChannelLayout    &inLayout);
232
233         OSStatus                                SetChannelLayout (AudioUnitScope                inScope, 
234                                                                                         AudioUnitElement                inEl,
235                                                                                         AudioChannelLayout              &inLayout,
236                                                                                         UInt32                                  inSize);
237                                                                                         
238         OSStatus                                ClearChannelLayout (AudioUnitScope              inScope,
239                                                                                         AudioUnitElement                inEl);
240                                                                                                 
241         OSStatus                                GetFormat (AudioUnitScope                                       inScope,
242                                                                                         AudioUnitElement                        inEl,
243                                                                                         AudioStreamBasicDescription     &outFormat) const;
244         // if an AudioChannelLayout is either required or set, this call can fail
245         // and the SetChannelLayout call should be used to set the format
246         OSStatus                                SetFormat (AudioUnitScope                                                       inScope,
247                                                                                         AudioUnitElement                                        inEl,
248                                                                                         const AudioStreamBasicDescription       &inFormat);
249
250         OSStatus                                GetSampleRate (AudioUnitScope           inScope,
251                                                                                         AudioUnitElement        inEl,
252                                                                                         Float64                         &outRate) const;
253         OSStatus                                SetSampleRate (AudioUnitScope           inScope,
254                                                                                         AudioUnitElement        inEl,
255                                                                                         Float64                         inRate);
256
257         // this sets the sample rate on all in/out buses of the AU
258         OSStatus                                SetSampleRate (Float64                          inSampleRate);
259         
260         OSStatus                                NumberChannels (AudioUnitScope          inScope,
261                                                                                         AudioUnitElement        inEl,
262                                                                                         UInt32                          &outChans) const;
263
264         OSStatus                                GetNumberChannels (AudioUnitScope       inScope,
265                                                                                         AudioUnitElement        inEl,
266                                                                                         UInt32                          &outChans) const 
267                                                         { 
268                                                                 return NumberChannels (inScope, inEl, outChans); 
269                                                         }
270
271         OSStatus                                SetNumberChannels (AudioUnitScope       inScope,
272                                                                                         AudioUnitElement        inEl,
273                                                                                         UInt32                          inChans);
274
275         OSStatus                                IsElementCountWritable (AudioUnitScope inScope, bool &outWritable) const;
276
277         OSStatus                                GetElementCount (AudioUnitScope         inScope, UInt32 &outCount) const;
278
279         OSStatus                                SetElementCount (AudioUnitScope         inScope, UInt32 inCount);
280                 
281                 // value of -1 for outTotalNumChannels indicates no restriction on num channels
282                 // for ex. the Matrix Mixer satisfies this (its in/out element count is writable, and can be set to 
283                 // any number of channels.
284                 // outTotalNumChannels is only valid if method returns true...
285         bool                                    HasDynamicInputs (SInt32 &outTotalNumChannels) const
286                                                         {
287                                                                 return HasDynamicScope (kAudioUnitScope_Input, outTotalNumChannels);
288                                                         }
289                                                         
290         bool                                    HasDynamicOutputs (SInt32 &outTotalNumChannels) const
291                                                         {
292                                                                 return HasDynamicScope (kAudioUnitScope_Output, outTotalNumChannels);
293                                                         }
294         
295                 // here, if the in (or out) elements are dynamic, then you supply the number of elements
296                 // you want on in (or out) scope, and the number of channels on each consecutive element
297         OSStatus                                ConfigureDynamicInput (UInt32 inNumElements, UInt32 *inChannelsPerElement, Float64 inSampleRate)
298                                                         {
299                                                                 return ConfigureDynamicScope (kAudioUnitScope_Input, inNumElements, inChannelsPerElement, inSampleRate);
300                                                         }
301                                                         
302         OSStatus                                ConfigureDynamicOutput (UInt32 inNumElements, UInt32 *inChannelsPerElement, Float64 inSampleRate)
303                                                         {
304                                                                 return ConfigureDynamicScope (kAudioUnitScope_Output, inNumElements, inChannelsPerElement, inSampleRate);
305                                                         }
306
307         bool                                    CanBypass               () const;
308
309         bool                                    GetBypass               () const;
310
311         OSStatus                                SetBypass               (bool                           inBypass) const;
312         
313         Float64                                 Latency () const;
314         
315                 // these calls just deal with the global preset state
316                 // you could rescope them to deal with presets on the part scope
317         OSStatus                                GetAUPreset (CFPropertyListRef &outData) const;
318
319         OSStatus                                SetAUPreset (CFPropertyListRef &inData);
320         
321         OSStatus                                GetPresentPreset (AUPreset &outData) const;
322         
323         OSStatus                                SetPresentPreset (AUPreset &inData);
324         
325         bool                                    HasCustomView () const;
326         
327 #pragma mark __Print    
328         void                                    Print () const { Print (stdout); }
329         void                                    Print (FILE* file) const;
330         
331 private:
332         CAComponent                             mComp;
333         
334         class AUState;
335         AUState*                mDataPtr;
336                 
337                 // this can throw - so wrap this up in a static that returns a result code...
338         CAAudioUnit (const CAComponent& inComp);
339
340         bool                            HasDynamicScope (AudioUnitScope inScope, SInt32 &outTotalNumChannels) const;
341         OSStatus                        ConfigureDynamicScope (AudioUnitScope   inScope, 
342                                                                                         UInt32                          inNumElements, 
343                                                                                         UInt32                          *inChannelsPerElement, 
344                                                                                         Float64                         inSampleRate);
345         bool                            ValidateChannelPair (int                                inChannelsIn, 
346                                                                                         int                             inChannelsOut,
347                                                                                         const AUChannelInfo * info,
348                                                                                         UInt32                          numChanInfo) const;
349                                                                                         
350         bool                            ValidateDynamicScope (AudioUnitScope    inScope, 
351                                                                                         SInt32                          &outTotalNumChannels, 
352                                                                                         const AUChannelInfo * info, 
353                                                                                         UInt32 numInfo) const;
354         bool                            CheckOneSide (const CAAUChanHelper              &inHelper, 
355                                                                                         bool                            checkOutput, 
356                                                                                         const AUChannelInfo *info, 
357                                                                                         UInt32                          numInfo) const;
358         
359 };
360
361 class CAAUChanHelper {
362 public:
363                                 CAAUChanHelper() 
364                                         : mChans(mStaticChans), mNumEls(0), mDidAllocate(false) 
365                                 {
366                                         memset (mChans, 0, sizeof(UInt32) * 8);
367                                 }
368                                 CAAUChanHelper(const CAAudioUnit &inAU, AudioUnitScope inScope);
369                                 CAAUChanHelper (const CAAUChanHelper &c) :mChans(mStaticChans), mNumEls(0), mDidAllocate(false) { *this = c; }
370                                 
371                                 ~CAAUChanHelper();
372
373         CAAUChanHelper& operator= (const CAAUChanHelper &c);
374
375         UInt32          * mChans;
376         UInt32          mNumEls;
377         
378 private:
379         UInt32 mStaticChans[8];
380         bool mDidAllocate;
381 };
382
383 #endif