13
0
livetrax/libs/appleutility/CAAudioUnit.h
David Robillard ab6f1ed9ba Merged with trunk R776
git-svn-id: svn://localhost/ardour2/branches/midi@777 d708f5d6-7413-0410-9779-e7cbd77b26cf
2006-08-10 01:22:45 +00:00

384 lines
14 KiB
C++

/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*=============================================================================
CAAudioUnit.h
=============================================================================*/
#ifndef __CAAudioUnit_h__
#define __CAAudioUnit_h__
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreServices/CoreServices.h>
#include <CoreAudio/CoreAudio.h>
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AUGraph.h>
#else
#include <ConditionalMacros.h>
#include <CoreServices.h>
#include <CoreAudioTypes.h>
#include <AudioUnit.h>
#include <AUGraph.h>
#endif
#include <vector>
#include "CAStreamBasicDescription.h"
#include "CAComponent.h"
#include "CAAudioChannelLayout.h"
// defined below
class CAAUChanHelper;
// These constructors will NOT throw exceptions - so "check" after creation if AU IsValid()
// The destructor will NOT automatically close the AU down
// This state should be managed by the Caller
// once closed, the unit represented by this object is no longer valid
// it is up to the user of this object to ensure its validity is in sync
// if it is removed from a graph
// methods that can significantly change the state of the AU (like its format) are
// NOT const whereas those that don't change the externally related state of the AU are not const
class CAAudioUnit {
public:
typedef std::vector<AudioChannelLayoutTag> ChannelTagVector;
typedef ChannelTagVector::iterator ChannelTagVectorIter;
public:
CAAudioUnit ()
: mDataPtr(0) {}
CAAudioUnit (const AudioUnit& inUnit);
CAAudioUnit (const AUNode &inNode, const AudioUnit& inUnit);
CAAudioUnit (const CAAudioUnit& y)
: mDataPtr(0) { *this = y; }
static OSStatus Open (const CAComponent& inComp, CAAudioUnit &outUnit);
~CAAudioUnit ();
CAAudioUnit& operator= (const CAAudioUnit& y);
bool operator== (const CAAudioUnit& y) const;
bool operator== (const AudioUnit& y) const;
#pragma mark __State Management
bool IsValid () const;
AudioUnit AU() const;
operator AudioUnit () const { return AU(); }
const CAComponent& Comp() const { return mComp; }
bool FromAUGraph () const { return GetAUNode() != 0 || GetAUNode() != -1; }
AUNode GetAUNode () const;
operator AUNode () const { return GetAUNode(); }
#pragma mark __API Wrapper
OSStatus Initialize() const { return AudioUnitInitialize(AU()); }
OSStatus Uninitialize() const { return AudioUnitUninitialize(AU()); }
OSStatus GetPropertyInfo(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
UInt32 *outDataSize, Boolean *outWritable) const
{
return AudioUnitGetPropertyInfo(AU(), propID, scope, element, outDataSize, outWritable);
}
OSStatus GetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
void *outData, UInt32 *ioDataSize) const
{
return AudioUnitGetProperty(AU(), propID, scope, element, outData, ioDataSize);
}
OSStatus SetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
const void *inData, UInt32 inDataSize)
{
return AudioUnitSetProperty(AU(), propID, scope, element, inData, inDataSize);
}
OSStatus SetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
Float32 value, UInt32 bufferOffsetFrames=0);
OSStatus GetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
Float32 &outValue) const;
OSStatus Render (AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inOutputBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData);
OSStatus Reset (AudioUnitScope scope, AudioUnitElement element)
{
return AudioUnitReset (AU(), scope, element);
}
OSStatus GlobalReset ()
{
return AudioUnitReset (AU(), kAudioUnitScope_Global, 0);
}
OSStatus Preroll (UInt32 inFrameSize);
OSStatus AddRenderNotify (AURenderCallback inProc, void *inProcRefCon)
{
return AudioUnitAddRenderNotify (AU(), inProc, inProcRefCon);
}
OSStatus RemoveRenderNotify (AURenderCallback inProc, void *inProcRefCon)
{
return AudioUnitRemoveRenderNotify (AU(), inProc, inProcRefCon);
}
// Fast dispatch support for MIDI Effects or Music Devices
OSStatus MIDIEvent (UInt32 inStatus,
UInt32 inData1,
UInt32 inData2,
UInt32 inOffsetSampleFrame);
// uses the default VoiceForGroup value - this is the normal case
OSStatus StartNote (MusicDeviceGroupID inGroupID,
NoteInstanceID * outNoteInstanceID,
UInt32 inOffsetSampleFrame,
const MusicDeviceNoteParams * inParams)
{
return StartNote (kMusicNoteEvent_UseGroupInstrument,
inGroupID, outNoteInstanceID,
inOffsetSampleFrame, inParams);
}
OSStatus StartNote (MusicDeviceInstrumentID inInstrument,
MusicDeviceGroupID inGroupID,
NoteInstanceID * outNoteInstanceID,
UInt32 inOffsetSampleFrame,
const MusicDeviceNoteParams * inParams);
OSStatus StopNote (MusicDeviceGroupID inGroupID,
NoteInstanceID inNoteInstanceID,
UInt32 inOffsetSampleFrame);
#pragma mark __Format Utilities
// typically you ask this about an AU
// These Questions are asking about Input and Output...
// These ones just say whether an AU can do a single combination of channels
// and is fine if the AU has a single output (and if an input, a single input)
bool CanDo (int inChannelsInOut) const
{
return CanDo (inChannelsInOut, inChannelsInOut);
}
bool CanDo ( int inChannelsIn,
int inChannelsOut) const;
// This version does a more thorough test for ANY AU with ANY ins/outs
// you pass in the channel helper (for the current element count on that scope)
bool CanDo ( const CAAUChanHelper &input,
const CAAUChanHelper &output) const;
bool SupportsNumChannels () const;
bool HasChannelLayouts (AudioUnitScope inScope,
AudioUnitElement inEl) const;
bool GetChannelLayouts (AudioUnitScope inScope,
AudioUnitElement inEl,
ChannelTagVector &outChannelVector) const;
OSStatus GetChannelLayout (AudioUnitScope inScope,
AudioUnitElement inEl,
CAAudioChannelLayout &outLayout) const;
OSStatus SetChannelLayout (AudioUnitScope inScope,
AudioUnitElement inEl,
CAAudioChannelLayout &inLayout);
OSStatus SetChannelLayout (AudioUnitScope inScope,
AudioUnitElement inEl,
AudioChannelLayout &inLayout,
UInt32 inSize);
OSStatus ClearChannelLayout (AudioUnitScope inScope,
AudioUnitElement inEl);
OSStatus GetFormat (AudioUnitScope inScope,
AudioUnitElement inEl,
AudioStreamBasicDescription &outFormat) const;
// if an AudioChannelLayout is either required or set, this call can fail
// and the SetChannelLayout call should be used to set the format
OSStatus SetFormat (AudioUnitScope inScope,
AudioUnitElement inEl,
const AudioStreamBasicDescription &inFormat);
OSStatus GetSampleRate (AudioUnitScope inScope,
AudioUnitElement inEl,
Float64 &outRate) const;
OSStatus SetSampleRate (AudioUnitScope inScope,
AudioUnitElement inEl,
Float64 inRate);
// this sets the sample rate on all in/out buses of the AU
OSStatus SetSampleRate (Float64 inSampleRate);
OSStatus NumberChannels (AudioUnitScope inScope,
AudioUnitElement inEl,
UInt32 &outChans) const;
OSStatus GetNumberChannels (AudioUnitScope inScope,
AudioUnitElement inEl,
UInt32 &outChans) const
{
return NumberChannels (inScope, inEl, outChans);
}
OSStatus SetNumberChannels (AudioUnitScope inScope,
AudioUnitElement inEl,
UInt32 inChans);
OSStatus IsElementCountWritable (AudioUnitScope inScope, bool &outWritable) const;
OSStatus GetElementCount (AudioUnitScope inScope, UInt32 &outCount) const;
OSStatus SetElementCount (AudioUnitScope inScope, UInt32 inCount);
// value of -1 for outTotalNumChannels indicates no restriction on num channels
// for ex. the Matrix Mixer satisfies this (its in/out element count is writable, and can be set to
// any number of channels.
// outTotalNumChannels is only valid if method returns true...
bool HasDynamicInputs (SInt32 &outTotalNumChannels) const
{
return HasDynamicScope (kAudioUnitScope_Input, outTotalNumChannels);
}
bool HasDynamicOutputs (SInt32 &outTotalNumChannels) const
{
return HasDynamicScope (kAudioUnitScope_Output, outTotalNumChannels);
}
// here, if the in (or out) elements are dynamic, then you supply the number of elements
// you want on in (or out) scope, and the number of channels on each consecutive element
OSStatus ConfigureDynamicInput (UInt32 inNumElements, UInt32 *inChannelsPerElement, Float64 inSampleRate)
{
return ConfigureDynamicScope (kAudioUnitScope_Input, inNumElements, inChannelsPerElement, inSampleRate);
}
OSStatus ConfigureDynamicOutput (UInt32 inNumElements, UInt32 *inChannelsPerElement, Float64 inSampleRate)
{
return ConfigureDynamicScope (kAudioUnitScope_Output, inNumElements, inChannelsPerElement, inSampleRate);
}
bool CanBypass () const;
bool GetBypass () const;
OSStatus SetBypass (bool inBypass) const;
Float64 Latency () const;
// these calls just deal with the global preset state
// you could rescope them to deal with presets on the part scope
OSStatus GetAUPreset (CFPropertyListRef &outData) const;
OSStatus SetAUPreset (CFPropertyListRef &inData);
OSStatus GetPresentPreset (AUPreset &outData) const;
OSStatus SetPresentPreset (AUPreset &inData);
bool HasCustomView () const;
#pragma mark __Print
void Print () const { Print (stdout); }
void Print (FILE* file) const;
private:
CAComponent mComp;
class AUState;
AUState* mDataPtr;
// this can throw - so wrap this up in a static that returns a result code...
CAAudioUnit (const CAComponent& inComp);
bool HasDynamicScope (AudioUnitScope inScope, SInt32 &outTotalNumChannels) const;
OSStatus ConfigureDynamicScope (AudioUnitScope inScope,
UInt32 inNumElements,
UInt32 *inChannelsPerElement,
Float64 inSampleRate);
bool ValidateChannelPair (int inChannelsIn,
int inChannelsOut,
const AUChannelInfo * info,
UInt32 numChanInfo) const;
bool ValidateDynamicScope (AudioUnitScope inScope,
SInt32 &outTotalNumChannels,
const AUChannelInfo * info,
UInt32 numInfo) const;
bool CheckOneSide (const CAAUChanHelper &inHelper,
bool checkOutput,
const AUChannelInfo *info,
UInt32 numInfo) const;
};
class CAAUChanHelper {
public:
CAAUChanHelper()
: mChans(mStaticChans), mNumEls(0), mDidAllocate(false)
{
memset (mChans, 0, sizeof(UInt32) * 8);
}
CAAUChanHelper(const CAAudioUnit &inAU, AudioUnitScope inScope);
CAAUChanHelper (const CAAUChanHelper &c) :mChans(mStaticChans), mNumEls(0), mDidAllocate(false) { *this = c; }
~CAAUChanHelper();
CAAUChanHelper& operator= (const CAAUChanHelper &c);
UInt32 * mChans;
UInt32 mNumEls;
private:
UInt32 mStaticChans[8];
bool mDidAllocate;
};
#endif