rollback to 3428, before the mysterious removal of libs/* at 3431/3432

git-svn-id: svn://localhost/ardour2/branches/3.0@3435 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2008-06-02 21:41:35 +00:00
parent 9c0d7d72d7
commit 449aab3c46
2869 changed files with 1026749 additions and 0 deletions

1
libs/.cvsignore Normal file
View File

@ -0,0 +1 @@
.DS_Store

View File

@ -0,0 +1,160 @@
/* 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.
*/
/*=============================================================================
AUOutputBL.h
=============================================================================*/
#include "AUOutputBL.h"
/*
struct AudioBufferList
{
UInt32 mNumberBuffers;
AudioBuffer mBuffers[1];
};
struct AudioBuffer
{
UInt32 mNumberChannels; // number of interleaved channels in the buffer
UInt32 mDataByteSize; // the size of the buffer pointed to by mData
void* mData; // the pointer to the buffer
};
*/
AUOutputBL::AUOutputBL (const CAStreamBasicDescription &inDesc, UInt32 inDefaultNumFrames)
: mFormat (inDesc),
mBufferMemory(NULL),
mBufferList (NULL),
mNumberBuffers (0), // keep this here, so can ensure integrity of ABL
mBufferSize (0),
mFrames(inDefaultNumFrames)
{
mNumberBuffers = mFormat.IsInterleaved() ? 1 : mFormat.NumberChannels();
mBufferList = reinterpret_cast<AudioBufferList*>(new Byte[sizeof(UInt32) + (mNumberBuffers * sizeof(AudioBuffer))]);
}
AUOutputBL::~AUOutputBL()
{
if (mBufferMemory)
delete[] mBufferMemory;
if (mBufferList)
delete [] mBufferList;
}
void AUOutputBL::Prepare (UInt32 inNumFrames, bool inWantNullBufferIfAllocated)
{
UInt32 channelsPerBuffer = mFormat.IsInterleaved() ? mFormat.NumberChannels() : 1;
if (mBufferMemory == NULL || inWantNullBufferIfAllocated)
{
mBufferList->mNumberBuffers = mNumberBuffers;
AudioBuffer *buf = &mBufferList->mBuffers[0];
for (UInt32 i = 0; i < mNumberBuffers; ++i, ++buf) {
buf->mNumberChannels = channelsPerBuffer;
buf->mDataByteSize = mFormat.FramesToBytes (inNumFrames);
buf->mData = NULL;
}
}
else
{
UInt32 nBytes = mFormat.FramesToBytes (inNumFrames);
if ((nBytes * mNumberBuffers) > AllocatedBytes())
throw OSStatus(-10874);//(kAudioUnitErr_TooManyFramesToProcess);
mBufferList->mNumberBuffers = mNumberBuffers;
AudioBuffer *buf = &mBufferList->mBuffers[0];
Byte* p = mBufferMemory;
for (UInt32 i = 0; i < mNumberBuffers; ++i, ++buf) {
buf->mNumberChannels = channelsPerBuffer;
buf->mDataByteSize = nBytes;
buf->mData = p;
p += mBufferSize;
}
}
}
void AUOutputBL::Allocate (UInt32 inNumFrames)
{
if (inNumFrames)
{
UInt32 nBytes = mFormat.FramesToBytes (inNumFrames);
if (nBytes <= AllocatedBytes())
return;
// align successive buffers for Altivec and to take alternating
// cache line hits by spacing them by odd multiples of 16
if (mNumberBuffers > 1)
nBytes = (nBytes + (0x10 - (nBytes & 0xF))) | 0x10;
mBufferSize = nBytes;
UInt32 memorySize = mBufferSize * mNumberBuffers;
Byte *newMemory = new Byte[memorySize];
memset(newMemory, 0, memorySize); // make buffer "hot"
Byte *oldMemory = mBufferMemory;
mBufferMemory = newMemory;
delete[] oldMemory;
mFrames = inNumFrames;
}
else
{
if (mBufferMemory) {
delete [] mBufferMemory;
mBufferMemory = NULL;
}
mBufferSize = 0;
mFrames = 0;
}
}
#if DEBUG
void AUOutputBL::Print()
{
printf ("AUOutputBL::Print\n");
mFormat.Print();
printf ("Num Buffers:%ld, mFrames:%ld, allocatedMemory:%c\n", mBufferList->mNumberBuffers, mFrames, (mBufferMemory != NULL ? 'T' : 'F'));
AudioBuffer *buf = &mBufferList->mBuffers[0];
for (UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i, ++buf)
printf ("\tBuffer:%ld, Size:%ld, Chans:%ld, Buffer:%X\n", i, buf->mDataByteSize, buf->mNumberChannels, int(buf->mData));
}
#endif

View File

@ -0,0 +1,115 @@
/* 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.
*/
/*=============================================================================
AUOutputBL.h
=============================================================================*/
#ifndef __AUOutputBL_h__
#define __AUOutputBL_h__
#include "CAStreamBasicDescription.h"
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreServices/CoreServices.h>
#else
#include <AssertMacros.h>
#endif
// ____________________________________________________________________________
//
// AUOutputBL - Simple Buffer List wrapper targetted to use with retrieving AU output
// Works in one of two ways (both adjustable)... Can use it with NULL pointers, or allocate
// memory to receive the data in.
// Before using this with any call to AudioUnitRender, it needs to be Prepared
// as some calls to AudioUnitRender can reset the ABL
class AUOutputBL {
public:
// you CANNOT use one of these - it will crash!
// AUOutputBL ();
// this is the constructor that you use
// it can't be reset once you've constructed it
AUOutputBL (const CAStreamBasicDescription &inDesc, UInt32 inDefaultNumFrames = 512);
~AUOutputBL();
void Prepare ()
{
Prepare (mFrames);
}
// this version can throw if this is an allocted ABL and inNumFrames is > AllocatedFrames()
// you can set the bool to true if you want a NULL buffer list even if allocated
// inNumFrames must be a valid number (will throw if inNumFrames is 0)
void Prepare (UInt32 inNumFrames, bool inWantNullBufferIfAllocated = false);
AudioBufferList* ABL() { return mBufferList; }
// You only need to call this if you want to allocate a buffer list
// if you want an empty buffer list, just call Prepare()
// if you want to dispose previously allocted memory, pass in 0
// then you either have an empty buffer list, or you can re-allocate
// Memory is kept around if an Allocation request is less than what is currently allocated
void Allocate (UInt32 inNumberFrames);
UInt32 AllocatedFrames() const { return mFrames; }
const CAStreamBasicDescription& GetFormat() const { return mFormat; }
#if DEBUG
void Print();
#endif
private:
UInt32 AllocatedBytes () const { return (mBufferSize * mNumberBuffers); }
CAStreamBasicDescription mFormat;
Byte* mBufferMemory;
AudioBufferList* mBufferList;
UInt32 mNumberBuffers;
UInt32 mBufferSize;
UInt32 mFrames;
// don't want to copy these.. can if you want, but more code to write!
AUOutputBL (const AUOutputBL &c) {}
AUOutputBL& operator= (const AUOutputBL& c) { return *this; }
};
#endif // __AUOutputBL_h__

View File

@ -0,0 +1,134 @@
/* 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.
*/
/*=============================================================================
AUParamInfo.cpp
=============================================================================*/
#include "AUParamInfo.h"
#include "CAXException.h"
AUParamInfo::AUParamInfo (AudioUnit inAU,
bool inIncludeExpert,
bool inIncludeReadOnly,
AudioUnitScope inScope,
AudioUnitElement inElement)
: mAU (inAU),
mNumParams (0),
mParamListID(NULL),
mScope (inScope),
mElement (inElement)
{
UInt32 size;
OSStatus result = AudioUnitGetPropertyInfo(mAU, kAudioUnitProperty_ParameterList, inScope, mElement, &size, NULL);
if (size == 0 || result) return;
int nparams = size / sizeof(AudioUnitPropertyID);
mParamListID = new AudioUnitParameterID[nparams];
memset (mParamListID, 0xFF, size);
AudioUnitParameterID *paramList = new AudioUnitParameterID[nparams];
result = AudioUnitGetProperty(mAU, kAudioUnitProperty_ParameterList, mScope, mElement, paramList, &size);
if (result) {
delete [] mParamListID;
delete [] paramList;
mParamListID = NULL;
return;
}
ParameterMap params;
for (int i = 0; i < nparams; ++i)
{
CAAUParameter auvp (mAU, paramList[i], mScope, mElement); // took out only using global scope in CAAUParameter creation
const AudioUnitParameterInfo &paramInfo = auvp.ParamInfo();
// don't include if parameter can't be read or written
if (!(paramInfo.flags & kAudioUnitParameterFlag_IsWritable)
&& !(paramInfo.flags & kAudioUnitParameterFlag_IsReadable))
continue;
// only include if expert params wanted
if (!inIncludeExpert && auvp.IsExpert())
continue;
// only include if read only params are wanted
if (!(paramInfo.flags & kAudioUnitParameterFlag_IsWritable)
&& (paramInfo.flags & kAudioUnitParameterFlag_IsReadable))
{
if (!inIncludeReadOnly)
continue;
}
mParamListID[mNumParams] = paramList[i];
mNumParams++;
// ok - if we're here, then we have a parameter we are going to display.
UInt32 clump = 0;
auvp.GetClumpID (clump);
mParams[clump].push_back (auvp);
}
delete [] paramList;
}
AUParamInfo::~AUParamInfo()
{
delete [] mParamListID;
}
UInt32 AUParamInfo::NumParamsForClump (UInt32 inClump) const
{
ParameterMap::const_iterator it = mParams.find(inClump);
if (it != mParams.end())
return (*it).second.size();
return 0;
}
const CAAUParameter* AUParamInfo::GetParamInfo (AudioUnitParameterID inParamID) const
{
for (ParameterMap::const_iterator it = mParams.begin(); it != mParams.end(); ++it) {
const ParameterList &list = (*it).second;
for (ParameterList::const_iterator iter = list.begin(); iter != list.end(); ++iter) {
if (inParamID == (*iter).mParameterID) {
return &(*iter);
}
}
}
return NULL;
}

View File

@ -0,0 +1,107 @@
/* 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.
*/
/*=============================================================================
AUParamInfo.h
=============================================================================*/
#include <map>
#include <vector>
#include <AudioUnit/AudioUnit.h>
#include "CAAUParameter.h"
/*
The ParameterMap returned by the Map() method is a map where
- the key is the clumpID
- the value is a ParameterList (vector<CAAUParameter>)
If you have parameters on multiple scopes (or elements within a scope), then you should create one of these
for each scope-element pair
*/
class AUParamInfo {
public:
typedef std::vector <CAAUParameter> ParameterList;
typedef std::map <UInt32, ParameterList, std::less<UInt32> > ParameterMap;
AUParamInfo (AudioUnit inAU,
bool inIncludeExpert,
bool inIncludeReadOnly,
AudioUnitScope inScope = kAudioUnitScope_Global,
AudioUnitElement inElement = 0);
~AUParamInfo();
const ParameterMap& Map () const { return mParams; }
// some convenience methods
UInt32 NumParams () const { return mNumParams; }
AudioUnitParameterID ParamID (UInt32 inIndex) const
{
if (inIndex < mNumParams) return mParamListID[inIndex];
return 0xFFFFFFFF;
}
UInt32 NumClumps () const { return mParams.size(); }
UInt32 NumParamsForClump (UInt32 inClump) const;
// returns NULL if there's no info for the parameter
const CAAUParameter* GetParamInfo (AudioUnitParameterID inParamID) const;
AudioUnitScope GetScope () const { return mScope; }
AudioUnitElement GetElement () const { return mElement; }
private:
AudioUnit mAU;
UInt32 mNumParams;
AudioUnitParameterID * mParamListID;
ParameterMap mParams;
AudioUnitScope mScope;
AudioUnitElement mElement;
// disallow
AUParamInfo () {}
AUParamInfo (const AUParamInfo &c) {}
AUParamInfo& operator= (const AUParamInfo& c) { return *this; }
};

View File

@ -0,0 +1,316 @@
/* 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.
*/
/*=============================================================================
CAAUParameter.cpp
=============================================================================*/
#include "CAAUParameter.h"
CAAUParameter::CAAUParameter()
{
memset(this, 0, sizeof(CAAUParameter));
}
CAAUParameter::CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element)
{
memset(this, 0, sizeof(CAAUParameter));
Init (au, param, scope, element);
}
CAAUParameter::CAAUParameter (AudioUnitParameter &inParam)
{
memset(this, 0, sizeof(CAAUParameter));
Init (inParam.mAudioUnit, inParam.mParameterID, inParam.mScope, inParam.mElement);
}
CAAUParameter::CAAUParameter(const CAAUParameter &a)
{
memset(this, 0, sizeof(CAAUParameter));
*this = a;
}
CAAUParameter & CAAUParameter::operator = (const CAAUParameter &a)
{
if (mParamName) CFRelease(mParamName);
if (mParamTag) CFRelease(mParamTag);
if (mNamedParams) CFRelease(mNamedParams);
memcpy(this, &a, sizeof(CAAUParameter));
if (mParamName) CFRetain(mParamName);
if (mParamTag) CFRetain(mParamTag);
if (mNamedParams) CFRetain(mNamedParams);
return *this;
}
CAAUParameter::~CAAUParameter()
{
if (mParamName) CFRelease(mParamName);
if (mParamTag) CFRelease(mParamTag);
if (mNamedParams) CFRelease (mNamedParams);
}
void CAAUParameter::Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element)
{
mAudioUnit = au;
mParameterID = param;
mScope = scope;
mElement = element;
UInt32 propertySize = sizeof(mParamInfo);
OSStatus err = AudioUnitGetProperty(au, kAudioUnitProperty_ParameterInfo,
scope, param, &mParamInfo, &propertySize);
if (err)
memset(&mParamInfo, 0, sizeof(mParamInfo));
if (mParamInfo.flags & kAudioUnitParameterFlag_HasCFNameString) {
mParamName = mParamInfo.cfNameString;
if (!(mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease))
CFRetain (mParamName);
} else
mParamName = CFStringCreateWithCString(NULL, mParamInfo.name, kCFStringEncodingUTF8);
char* str = 0;
switch (mParamInfo.unit)
{
case kAudioUnitParameterUnit_Boolean:
str = "T/F";
break;
case kAudioUnitParameterUnit_Percent:
case kAudioUnitParameterUnit_EqualPowerCrossfade:
str = "%";
break;
case kAudioUnitParameterUnit_Seconds:
str = "Secs";
break;
case kAudioUnitParameterUnit_SampleFrames:
str = "Samps";
break;
case kAudioUnitParameterUnit_Phase:
case kAudioUnitParameterUnit_Degrees:
str = "Degr.";
break;
case kAudioUnitParameterUnit_Hertz:
str = "Hz";
break;
case kAudioUnitParameterUnit_Cents:
case kAudioUnitParameterUnit_AbsoluteCents:
str = "Cents";
break;
case kAudioUnitParameterUnit_RelativeSemiTones:
str = "S-T";
break;
case kAudioUnitParameterUnit_MIDINoteNumber:
case kAudioUnitParameterUnit_MIDIController:
str = "MIDI";
//these are inclusive, so add one value here
mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue);
break;
case kAudioUnitParameterUnit_Decibels:
str = "dB";
break;
case kAudioUnitParameterUnit_MixerFaderCurve1:
case kAudioUnitParameterUnit_LinearGain:
str = "Gain";
break;
case kAudioUnitParameterUnit_Pan:
str = "L/R";
break;
case kAudioUnitParameterUnit_Meters:
str = "Mtrs";
break;
case kAudioUnitParameterUnit_Octaves:
str = "8ve";
break;
case kAudioUnitParameterUnit_BPM:
str = "BPM";
break;
case kAudioUnitParameterUnit_Beats:
str = "Beats";
break;
case kAudioUnitParameterUnit_Milliseconds:
str = "msecs";
break;
case kAudioUnitParameterUnit_Ratio:
str = "ratio";
break;
case kAudioUnitParameterUnit_Indexed:
{
propertySize = sizeof(mNamedParams);
err = AudioUnitGetProperty (au,
kAudioUnitProperty_ParameterValueStrings,
scope,
param,
&mNamedParams,
&propertySize);
if (!err && mNamedParams) {
mNumIndexedParams = CFArrayGetCount(mNamedParams);
} else {
//these are inclusive, so add one value here
mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue);
}
str = NULL;
}
break;
case kAudioUnitParameterUnit_CustomUnit:
{
CFStringRef unitName = mParamInfo.unitName;
static char paramStr[256];
CFStringGetCString (unitName, paramStr, 256, kCFStringEncodingUTF8);
if (mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease)
CFRelease (unitName);
str = paramStr;
break;
}
case kAudioUnitParameterUnit_Generic:
case kAudioUnitParameterUnit_Rate:
default:
str = NULL;
break;
}
if (str)
mParamTag = CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8);
else
mParamTag = NULL;
}
Float32 CAAUParameter::GetValue() const
{
Float32 value = 0.;
//OSStatus err =
AudioUnitGetParameter(mAudioUnit, mParameterID, mScope, mElement, &value);
return value;
}
CFStringRef CAAUParameter::GetStringFromValueCopy(const Float32 *value) const
{
if (HasNamedParams())
{
Float32 val = (value == NULL ? GetValue() : *value);
int index = int(mParamInfo.minValue) + int(val);
CFStringRef str = GetParamName (index);
if (str) {
CFRetain (str);
return str;
}
}
else if (ValuesHaveStrings())
{
AudioUnitParameterStringFromValue stringValue;
stringValue.inParamID = mParameterID;
stringValue.inValue = value;
stringValue.outString = NULL;
UInt32 propertySize = sizeof(stringValue);
OSStatus err = AudioUnitGetProperty (mAudioUnit,
kAudioUnitProperty_ParameterStringFromValue,
mScope,
mParameterID,
&stringValue,
&propertySize);
if (err == noErr && stringValue.outString != NULL)
return stringValue.outString;
}
Float32 val = (value == NULL ? GetValue() : *value);
char valstr[32];
AUParameterFormatValue (val, this, valstr, 4);
return CFStringCreateWithCString(NULL, valstr, kCFStringEncodingUTF8);
}
Float32 CAAUParameter::GetValueFromString(CFStringRef str) const
{
if (ValuesHaveStrings())
{
AudioUnitParameterValueFromString valueString;
valueString.inParamID = mParameterID;
valueString.inString = str;
UInt32 propertySize = sizeof(valueString);
OSStatus err = AudioUnitGetProperty (mAudioUnit,
kAudioUnitProperty_ParameterValueFromString,
mScope,
mParameterID,
&valueString,
&propertySize);
if (err == noErr) {
return valueString.outValue;
}
}
Float32 paramValue = mParamInfo.defaultValue;
char valstr[32];
CFStringGetCString(str, valstr, sizeof(valstr), kCFStringEncodingUTF8);
sscanf(valstr, "%f", &paramValue);
return paramValue;
}
void CAAUParameter::SetValue( AUParameterListenerRef inListener,
void * inObject,
Float32 inValue) const
{
// clip inValue as: maxValue >= inValue >= minValue before setting
Float32 valueToSet = inValue;
if (valueToSet > mParamInfo.maxValue)
valueToSet = mParamInfo.maxValue;
if (valueToSet < mParamInfo.minValue)
valueToSet = mParamInfo.minValue;
AUParameterSet(inListener, inObject, this, valueToSet, 0);
}
#if DEBUG
void CAAUParameter::Print() const
{
UInt32 clump = 0;
GetClumpID (clump);
UInt32 len = CFStringGetLength(mParamName);
char* chars = (char*)malloc (len * 2); // give us plenty of room for unichar chars
if (!CFStringGetCString (mParamName, chars, len * 2, kCFStringEncodingUTF8))
chars[0] = 0;
printf ("ID: %ld, Clump: %ld, Name: %s\n", mParameterID, clump, chars);
free (chars);
}
#endif

View File

@ -0,0 +1,187 @@
/* 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.
*/
/*=============================================================================
CAAUParameter.h
=============================================================================*/
#ifndef __CAAUParameter_h__
#define __CAAUParameter_h__
#include <AudioToolbox/AudioUnitUtilities.h>
// ____________________________________________________________________________
// CAAUParameter
// complete parameter specification
/*! @class CAAUParameter */
class CAAUParameter : public AudioUnitParameter {
public:
/*! @ctor CAAUParameter.0 */
CAAUParameter();
/*! @ctor CAAUParameter.1 */
CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element);
/*! @ctor CAAUParameter.2 */
CAAUParameter(AudioUnitParameter &inParam);
/*! @ctor CAAUParameter.3 */
CAAUParameter(const CAAUParameter &a);
/*! @dtor ~CAAUParameter */
~CAAUParameter();
/*! @method operator <@ */
bool operator < (const CAAUParameter &a) const
{
return memcmp(this, &a, sizeof(AudioUnitParameter)) < 0;
}
/*! @method operator ==@ */
bool operator == (const CAAUParameter &a) const
{
return !memcmp(this, &a, sizeof(AudioUnitParameter));
}
/*! @method operator =@ */
CAAUParameter & operator = (const CAAUParameter &a);
/*! @method GetValue */
Float32 GetValue() const;
/*! @method SetValue */
void SetValue( AUParameterListenerRef inListener,
void * inObject,
Float32 inValue) const;
/*! @method GetName */
CFStringRef GetName() const { return mParamName; }
// borrowed reference!
/*! @method GetStringFromValueCopy */
CFStringRef GetStringFromValueCopy(const Float32 *value = NULL) const;
// returns a copy of the name of the current parameter value
// or null if there is no name associated
// caller must release
/*! @method ValuesHaveStrings */
bool ValuesHaveStrings () const
{
return (mParamInfo.flags & kAudioUnitParameterFlag_ValuesHaveStrings) != 0;
}
/*! @method GetValueFromString */
Float32 GetValueFromString (CFStringRef str) const;
// caller must release
/*! @method ParamInfo */
const AudioUnitParameterInfo &
ParamInfo() const { return mParamInfo; }
/*! @method GetParamTag */
CFStringRef GetParamTag() const { return mParamTag; }
// this may return null! -
// in which case there is no descriptive tag for the parameter
/*! @method GetParamName */
CFStringRef GetParamName (int inIndex) const
// this can return null if there is no name for the parameter
{
return (mNamedParams && inIndex < mNumIndexedParams)
? (CFStringRef) CFArrayGetValueAtIndex(mNamedParams, inIndex)
: 0;
}
/*! @method GetNumIndexedParams */
int GetNumIndexedParams () const { return mNumIndexedParams; }
/*! @method IsIndexedParam */
bool IsIndexedParam () const { return mNumIndexedParams != 0; }
/*! @method HasNamedParams */
bool HasNamedParams () const { return IsIndexedParam() && mNamedParams; }
/*! @method GetClumpID */
bool GetClumpID (UInt32 &outClumpID) const
{
if (mParamInfo.flags & kAudioUnitParameterFlag_HasClump) {
outClumpID = mParamInfo.clumpID;
return true;
}
return false;
}
/*! @method HasDisplayTransformation */
bool HasDisplayTransformation () const
{
return GetAudioUnitParameterDisplayType (mParamInfo.flags);
}
/*! @method IsExpert */
bool IsExpert () const
{
return mParamInfo.flags & kAudioUnitParameterFlag_ExpertMode;
}
#if DEBUG
void Print () const;
#endif
// these methods are defined in CAPersistence.cpp
// they will persist and restore only the scope, element and param ID's of the AudioUnitParameter
// however, this is sufficient to be able to save/restore a CAAUParameter object
void Save (CFPropertyListRef &outData) const;
static void Save (const AudioUnitParameter &inParam, CFPropertyListRef &outData);
static OSStatus Restore (const CFPropertyListRef inData, AudioUnitParameter &outParam);
protected:
// cached parameter info
/*! @var mParamInfo */
AudioUnitParameterInfo mParamInfo;
/*! @var mParamName */
CFStringRef mParamName;
/*! @var mParamTag */
CFStringRef mParamTag;
/*! @var mNumIndexedParams */
short mNumIndexedParams;
/*! @var mNamedParams */
CFArrayRef mNamedParams;
private:
void Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element);
};
#endif // __CAAUParameter_h__

View File

@ -0,0 +1,138 @@
/* 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.
*/
/*=============================================================================
CAAudioChannelLayout.cpp
=============================================================================*/
//=============================================================================
// Includes
//=============================================================================
// Self Include
#include "CAAudioChannelLayout.h"
#include <stdlib.h>
#include <string.h>
//=============================================================================
// CAAudioChannelLayout
//=============================================================================
AudioChannelLayout* CAAudioChannelLayout::Create(UInt32 inNumberChannelDescriptions)
{
UInt32 theSize = CalculateByteSize(inNumberChannelDescriptions);
AudioChannelLayout* theAnswer = static_cast<AudioChannelLayout*>(calloc(1, theSize));
if(theAnswer != NULL)
{
SetAllToUnknown(*theAnswer, inNumberChannelDescriptions);
}
return theAnswer;
}
void CAAudioChannelLayout::Destroy(AudioChannelLayout* inChannelLayout)
{
free(inChannelLayout);
}
void CAAudioChannelLayout::SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions)
{
outChannelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
outChannelLayout.mChannelBitmap = 0;
outChannelLayout.mNumberChannelDescriptions = inNumberChannelDescriptions;
for(UInt32 theChannelIndex = 0; theChannelIndex < inNumberChannelDescriptions; ++theChannelIndex)
{
outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelLabel = kAudioChannelLabel_Unknown;
outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelFlags = 0;
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[0] = 0;
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[1] = 0;
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[2] = 0;
}
}
bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y)
{
// compare based on the number of channel descriptions present
// (this may be too strict a comparison if all you care about are matching layout tags)
UInt32 theSize1 = CAAudioChannelLayout::CalculateByteSize(x.mNumberChannelDescriptions);
UInt32 theSize2 = CAAudioChannelLayout::CalculateByteSize(y.mNumberChannelDescriptions);
if (theSize1 != theSize2)
return false;
return !memcmp (&x, &y, theSize1);
}
// counting the one bits in a word
inline UInt32 CountOnes(UInt32 x)
{
// secret magic algorithm for counting bits in a word.
UInt32 t;
x = x - ((x >> 1) & 0x55555555);
t = ((x >> 2) & 0x33333333);
x = (x & 0x33333333) + t;
x = (x + (x >> 4)) & 0x0F0F0F0F;
x = x + (x << 8);
x = x + (x << 16);
return x >> 24;
}
UInt32 CAAudioChannelLayout::NumberChannels (const AudioChannelLayout& inLayout)
{
if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
return inLayout.mNumberChannelDescriptions;
if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
return CountOnes (inLayout.mChannelBitmap);
return AudioChannelLayoutTag_GetNumberOfChannels(inLayout.mChannelLayoutTag);
}
void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout)
{
fprintf (file, "\tTag=0x%lX, ", layout->mChannelLayoutTag);
if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
fprintf (file, "Using Bitmap:0x%lX\n", layout->mChannelBitmap);
else {
fprintf (file, "Num Chan Descs=%ld\n", layout->mNumberChannelDescriptions);
const AudioChannelDescription *desc = layout->mChannelDescriptions;
for (unsigned int i = 0; i < layout->mNumberChannelDescriptions; ++i, ++desc) {
fprintf (file, "\t\tLabel=%ld, Flags=0x%lX, ", desc->mChannelLabel, desc->mChannelFlags);
fprintf (file, "[az=%f,el=%f,dist=%f]\n", desc->mCoordinates[0], desc->mCoordinates[1], desc->mCoordinates[2]);
}
}
}

View File

@ -0,0 +1,162 @@
/* 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.
*/
/*=============================================================================
CAAudioChannelLayout.h
=============================================================================*/
#if !defined(__CAAudioChannelLayout_h__)
#define __CAAudioChannelLayout_h__
//=============================================================================
// Includes
//=============================================================================
// System Includes
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreAudio/CoreAudioTypes.h>
#include <CoreFoundation/CoreFoundation.h>
#else
#include <CoreAudioTypes.h>
#include <CoreFoundation.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !HAL_Build
#include "CAReferenceCounted.h"
#endif
//=============================================================================
// CAAudioChannelLayout
//=============================================================================
bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y);
extern "C" void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout);
class CAAudioChannelLayout
{
// static Construction/Destruction
public:
static AudioChannelLayout* Create(UInt32 inNumberChannelDescriptions);
static void Destroy(AudioChannelLayout* inChannelLayout);
static UInt32 CalculateByteSize(UInt32 inNumberChannelDescriptions) {
return offsetof(AudioChannelLayout, mChannelDescriptions) + inNumberChannelDescriptions * sizeof(AudioChannelDescription);
}
static void SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions);
static UInt32 NumberChannels(const AudioChannelLayout& inLayout);
#if !HAL_Build
// object methods
public:
CAAudioChannelLayout ();
CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
// if inChooseSurround is false, then symmetrical speaker arrangements
// are chosen in place of surround layouts if there is a choice
// This call chooses layouts based on the expected defaults in
// AudioUnit usage
CAAudioChannelLayout (AudioChannelLayoutTag inTag);
CAAudioChannelLayout (const CAAudioChannelLayout &c);
CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout);
~CAAudioChannelLayout();
CAAudioChannelLayout& operator= (const AudioChannelLayout* inChannelLayout);
CAAudioChannelLayout& operator= (const CAAudioChannelLayout& c);
bool operator== (const CAAudioChannelLayout &c) const;
void SetWithTag(AudioChannelLayoutTag inTag);
bool IsValid() const { return NumberChannels() > 0; }
UInt32 Size() const { return mLayoutHolder ? mLayoutHolder->Size() : 0; }
UInt32 NumberChannels() const { return NumberChannels(Layout()); }
AudioChannelLayoutTag Tag() const { return Layout().mChannelLayoutTag; }
const AudioChannelLayout& Layout() const { return mLayoutHolder->Layout(); }
operator const AudioChannelLayout *() const { return &Layout(); }
void Print () const { Print (stdout); }
void Print (FILE* file) const;
OSStatus Save (CFPropertyListRef *outData) const;
OSStatus Restore (CFPropertyListRef &inData);
private:
class ACLRefCounter : public CAReferenceCounted {
public:
ACLRefCounter (UInt32 inDataSize)
{
if (inDataSize < offsetof(AudioChannelLayout, mChannelDescriptions))
inDataSize = offsetof(AudioChannelLayout, mChannelDescriptions);
mLayout = static_cast<AudioChannelLayout*>(malloc (inDataSize));
memset (mLayout, 0, inDataSize);
mByteSize = inDataSize;
}
const AudioChannelLayout & Layout() const { return *mLayout; }
UInt32 Size () const { return mByteSize; }
private:
AudioChannelLayout *mLayout;
UInt32 mByteSize;
// only the constructors can change the actual state of the layout
friend CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
friend OSStatus CAAudioChannelLayout::Restore (CFPropertyListRef &inData);
friend CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout);
friend void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag);
AudioChannelLayout * GetLayout() { return mLayout; }
~ACLRefCounter() { if (mLayout) { free(mLayout); mLayout = NULL; } }
private:
ACLRefCounter () : mLayout(NULL) { }
ACLRefCounter(const ACLRefCounter& c) : mLayout(NULL) { }
ACLRefCounter& operator=(const ACLRefCounter& c) { return *this; }
};
ACLRefCounter *mLayoutHolder;
#endif // HAL_Build
};
#endif

View File

@ -0,0 +1,199 @@
/* 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.
*/
/*=============================================================================
CAAudioChannelLayoutObject.cpp
=============================================================================*/
#include "CAAudioChannelLayout.h"
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreServices/CoreServices.h>
#include <AudioToolbox/AudioFormat.h>
#else
#include <CoreServices.h>
#include <AudioFormat.h>
#endif
CAAudioChannelLayout::CAAudioChannelLayout ()
{
mLayoutHolder = new ACLRefCounter (offsetof(AudioChannelLayout, mChannelDescriptions));
}
//=============================================================================
// CAAudioChannelLayout::CAAudioChannelLayout
//=============================================================================
CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround)
{
// this chooses default layouts based on the number of channels...
UInt32 theSize = CalculateByteSize (inNumberChannels);
mLayoutHolder = new ACLRefCounter (theSize);
AudioChannelLayout* layout = mLayoutHolder->GetLayout();
layout->mNumberChannelDescriptions = inNumberChannels;
switch (inNumberChannels)
{
case 1:
layout->mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
break;
case 2:
layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_Binaural : kAudioChannelLayoutTag_Stereo;
break;
case 4:
layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_Ambisonic_B_Format : kAudioChannelLayoutTag_AudioUnit_4;
break;
case 5:
layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_AudioUnit_5_0 : kAudioChannelLayoutTag_AudioUnit_5;
break;
case 6:
layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_AudioUnit_6_0 : kAudioChannelLayoutTag_AudioUnit_6;
break;
case 7:
layout->mChannelLayoutTag = kAudioChannelLayoutTag_AudioUnit_7_0;
break;
case 8:
layout->mChannelLayoutTag = kAudioChannelLayoutTag_AudioUnit_8;
break;
default:
// here we have a "broken" layout, in the sense that we haven't any idea how to lay this out
// the layout itself is all set to zeros
// ### no longer true ###
SetAllToUnknown(*layout, inNumberChannels);
break;
}
}
//=============================================================================
// CAAudioChannelLayout::CAAudioChannelLayout
//=============================================================================
CAAudioChannelLayout::CAAudioChannelLayout (AudioChannelLayoutTag inLayoutTag)
: mLayoutHolder(NULL)
{
SetWithTag(inLayoutTag);
}
//=============================================================================
// CAAudioChannelLayout::CAAudioChannelLayout
//=============================================================================
CAAudioChannelLayout::CAAudioChannelLayout (const CAAudioChannelLayout &c)
: mLayoutHolder(NULL)
{
*this = c;
}
//=============================================================================
// CAAudioChannelLayout::AudioChannelLayout
//=============================================================================
CAAudioChannelLayout::CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout)
: mLayoutHolder(NULL)
{
*this = inChannelLayout;
}
//=============================================================================
// CAAudioChannelLayout::~CAAudioChannelLayout
//=============================================================================
CAAudioChannelLayout::~CAAudioChannelLayout ()
{
if (mLayoutHolder) {
mLayoutHolder->release();
mLayoutHolder = NULL;
}
}
//=============================================================================
// CAAudioChannelLayout::CAAudioChannelLayout
//=============================================================================
CAAudioChannelLayout& CAAudioChannelLayout::operator= (const CAAudioChannelLayout &c)
{
if (mLayoutHolder != c.mLayoutHolder) {
if (mLayoutHolder)
mLayoutHolder->release();
if ((mLayoutHolder = c.mLayoutHolder) != NULL)
mLayoutHolder->retain();
}
return *this;
}
CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout)
{
if (mLayoutHolder)
mLayoutHolder->release();
UInt32 theSize = CalculateByteSize (inChannelLayout->mNumberChannelDescriptions);
mLayoutHolder = new ACLRefCounter (theSize);
memcpy(mLayoutHolder->mLayout, inChannelLayout, theSize);
return *this;
}
void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag)
{
if (mLayoutHolder)
mLayoutHolder->release();
mLayoutHolder = new ACLRefCounter(offsetof(AudioChannelLayout, mChannelDescriptions[0]));
AudioChannelLayout* layout = mLayoutHolder->GetLayout();
layout->mChannelLayoutTag = inTag;
}
//=============================================================================
// CAAudioChannelLayout::operator==
//=============================================================================
bool CAAudioChannelLayout::operator== (const CAAudioChannelLayout &c) const
{
if (mLayoutHolder == c.mLayoutHolder)
return true;
return Layout() == c.Layout();
}
//=============================================================================
// CAAudioChannelLayout::Print
//=============================================================================
void CAAudioChannelLayout::Print (FILE* file) const
{
CAShowAudioChannelLayout (file, &Layout());
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,439 @@
/* 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.
*/
/*=============================================================================
CAAudioFile.h
=============================================================================*/
#ifndef __CAAudioFile_h__
#define __CAAudioFile_h__
#include <AvailabilityMacros.h>
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <AudioToolbox/AudioToolbox.h>
#else
#include <AudioToolbox.h>
#endif
#include "CAStreamBasicDescription.h"
#include "CABufferList.h"
#include "CAAudioChannelLayout.h"
#include "CAXException.h"
#include "CAMath.h"
#ifndef CAAF_USE_EXTAUDIOFILE
// option: use AudioToolbox/ExtAudioFile.h? Only available on Tiger.
#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_3
// we are building software that must be deployable on Panther or earlier
#define CAAF_USE_EXTAUDIOFILE 0
#else
// else we require Tiger and can use the API
#define CAAF_USE_EXTAUDIOFILE 1
#endif
#endif
#ifndef MAC_OS_X_VERSION_10_4
// we have pre-Tiger headers; add our own declarations
typedef UInt32 AudioFileTypeID;
enum {
kExtAudioFileError_InvalidProperty = -66561,
kExtAudioFileError_InvalidPropertySize = -66562,
kExtAudioFileError_NonPCMClientFormat = -66563,
kExtAudioFileError_InvalidChannelMap = -66564, // number of channels doesn't match format
kExtAudioFileError_InvalidOperationOrder = -66565,
kExtAudioFileError_InvalidDataFormat = -66566,
kExtAudioFileError_MaxPacketSizeUnknown = -66567,
kExtAudioFileError_InvalidSeek = -66568, // writing, or offset out of bounds
kExtAudioFileError_AsyncWriteTooLarge = -66569,
kExtAudioFileError_AsyncWriteBufferOverflow = -66570 // an async write could not be completed in time
};
#else
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <AudioToolbox/ExtendedAudioFile.h>
#else
#include "ExtendedAudioFile.h"
#endif
#endif
// _______________________________________________________________________________________
// Wrapper class for an AudioFile, supporting encode/decode to/from a PCM client format
class CAAudioFile {
public:
// implementation-independent helpers
void Open(const char *filePath) {
FSRef fsref;
XThrowIfError(FSPathMakeRef((UInt8 *)filePath, &fsref, NULL), "locate audio file");
Open(fsref);
}
bool HasConverter() const { return GetConverter() != NULL; }
double GetDurationSeconds() {
double sr = GetFileDataFormat().mSampleRate;
return fnonzero(sr) ? GetNumberFrames() / sr : 0.;
}
// will be 0 if the file's frames/packet is 0 (variable)
// or the file's sample rate is 0 (unknown)
#if CAAF_USE_EXTAUDIOFILE
public:
CAAudioFile() : mExtAF(NULL) { }
virtual ~CAAudioFile() { if (mExtAF) Close(); }
void Open(const FSRef &fsref) {
// open an existing file
XThrowIfError(ExtAudioFileOpen(&fsref, &mExtAF), "ExtAudioFileOpen failed");
}
void CreateNew(const FSRef &inParentDir, CFStringRef inFileName, AudioFileTypeID inFileType, const AudioStreamBasicDescription &inStreamDesc, const AudioChannelLayout *inChannelLayout=NULL) {
XThrowIfError(ExtAudioFileCreateNew(&inParentDir, inFileName, inFileType, &inStreamDesc, inChannelLayout, &mExtAF), "ExtAudioFileCreateNew failed");
}
void Wrap(AudioFileID fileID, bool forWriting) {
// use this to wrap an AudioFileID opened externally
XThrowIfError(ExtAudioFileWrapAudioFileID(fileID, forWriting, &mExtAF), "ExtAudioFileWrapAudioFileID failed");
}
void Close() {
XThrowIfError(ExtAudioFileDispose(mExtAF), "ExtAudioFileClose failed");
mExtAF = NULL;
}
const CAStreamBasicDescription &GetFileDataFormat() {
UInt32 size = sizeof(mFileDataFormat);
XThrowIfError(ExtAudioFileGetProperty(mExtAF, kExtAudioFileProperty_FileDataFormat, &size, &mFileDataFormat), "Couldn't get file's data format");
return mFileDataFormat;
}
const CAAudioChannelLayout & GetFileChannelLayout() {
return FetchChannelLayout(mFileChannelLayout, kExtAudioFileProperty_FileChannelLayout);
}
void SetFileChannelLayout(const CAAudioChannelLayout &layout) {
XThrowIfError(ExtAudioFileSetProperty(mExtAF, kExtAudioFileProperty_FileChannelLayout, layout.Size(), &layout.Layout()), "Couldn't set file's channel layout");
mFileChannelLayout = layout;
}
const CAStreamBasicDescription &GetClientDataFormat() {
UInt32 size = sizeof(mClientDataFormat);
XThrowIfError(ExtAudioFileGetProperty(mExtAF, kExtAudioFileProperty_ClientDataFormat, &size, &mClientDataFormat), "Couldn't get client data format");
return mClientDataFormat;
}
const CAAudioChannelLayout & GetClientChannelLayout() {
return FetchChannelLayout(mClientChannelLayout, kExtAudioFileProperty_ClientChannelLayout);
}
void SetClientFormat(const CAStreamBasicDescription &dataFormat, const CAAudioChannelLayout *layout=NULL) {
XThrowIfError(ExtAudioFileSetProperty(mExtAF, kExtAudioFileProperty_ClientDataFormat, sizeof(dataFormat), &dataFormat), "Couldn't set client format");
if (layout)
SetClientChannelLayout(*layout);
}
void SetClientChannelLayout(const CAAudioChannelLayout &layout) {
XThrowIfError(ExtAudioFileSetProperty(mExtAF, kExtAudioFileProperty_ClientChannelLayout, layout.Size(), &layout.Layout()), "Couldn't set client channel layout");
}
AudioConverterRef GetConverter() const {
UInt32 size = sizeof(AudioConverterRef);
AudioConverterRef converter;
XThrowIfError(ExtAudioFileGetProperty(mExtAF, kExtAudioFileProperty_AudioConverter, &size, &converter), "Couldn't get file's AudioConverter");
return converter;
}
OSStatus SetConverterProperty(AudioConverterPropertyID inPropertyID, UInt32 inPropertyDataSize, const void *inPropertyData, bool inCanFail=false)
{
OSStatus err = AudioConverterSetProperty(GetConverter(), inPropertyID, inPropertyDataSize, inPropertyData);
if (!inCanFail)
XThrowIfError(err, "Couldn't set audio converter property");
if (!err) {
// must tell the file that we have changed the converter; a NULL converter config is sufficient
CFPropertyListRef config = NULL;
XThrowIfError(ExtAudioFileSetProperty(mExtAF, kExtAudioFileProperty_ConverterConfig, sizeof(CFPropertyListRef), &config), "couldn't signal the file that the converter has changed");
}
return err;
}
SInt64 GetNumberFrames() {
SInt64 length;
UInt32 size = sizeof(SInt64);
XThrowIfError(ExtAudioFileGetProperty(mExtAF, kExtAudioFileProperty_FileLengthFrames, &size, &length), "Couldn't get file's length");
return length;
}
void SetNumberFrames(SInt64 length) {
XThrowIfError(ExtAudioFileSetProperty(mExtAF, kExtAudioFileProperty_FileLengthFrames, sizeof(SInt64), &length), "Couldn't set file's length");
}
void Seek(SInt64 pos) {
XThrowIfError(ExtAudioFileSeek(mExtAF, pos), "Couldn't seek in audio file");
}
SInt64 Tell() {
SInt64 pos;
XThrowIfError(ExtAudioFileTell(mExtAF, &pos), "Couldn't get file's mark");
return pos;
}
void Read(UInt32 &ioFrames, AudioBufferList *ioData) {
XThrowIfError(ExtAudioFileRead(mExtAF, &ioFrames, ioData), "Couldn't read audio file");
}
void Write(UInt32 inFrames, const AudioBufferList *inData) {
XThrowIfError(ExtAudioFileWrite(mExtAF, inFrames, inData), "Couldn't write audio file");
}
void SetIOBufferSizeBytes(UInt32 bufferSizeBytes) {
XThrowIfError(ExtAudioFileSetProperty(mExtAF, kExtAudioFileProperty_IOBufferSizeBytes, sizeof(UInt32), &bufferSizeBytes), "Couldn't set audio file's I/O buffer size");
}
private:
const CAAudioChannelLayout & FetchChannelLayout(CAAudioChannelLayout &layoutObj, ExtAudioFilePropertyID propID) {
UInt32 size;
XThrowIfError(ExtAudioFileGetPropertyInfo(mExtAF, propID, &size, NULL), "Couldn't get info about channel layout");
AudioChannelLayout *layout = (AudioChannelLayout *)malloc(size);
OSStatus err = ExtAudioFileGetProperty(mExtAF, propID, &size, layout);
if (err) {
free(layout);
XThrowIfError(err, "Couldn't get channel layout");
}
layoutObj = layout;
free(layout);
return layoutObj;
}
private:
ExtAudioFileRef mExtAF;
CAStreamBasicDescription mFileDataFormat;
CAAudioChannelLayout mFileChannelLayout;
CAStreamBasicDescription mClientDataFormat;
CAAudioChannelLayout mClientChannelLayout;
#endif
#if !CAAF_USE_EXTAUDIOFILE
CAAudioFile();
virtual ~CAAudioFile();
// --- second-stage initializers ---
// Use exactly one of the following:
// - Open
// - PrepareNew followed by Create
// - Wrap
void Open(const FSRef &fsref);
// open an existing file
void CreateNew(const FSRef &inParentDir, CFStringRef inFileName, AudioFileTypeID inFileType, const AudioStreamBasicDescription &inStreamDesc, const AudioChannelLayout *inChannelLayout=NULL);
void Wrap(AudioFileID fileID, bool forWriting);
// use this to wrap an AudioFileID opened externally
// ---
void Close();
// In case you want to close the file before the destructor executes
// --- Data formats ---
// Allow specifying the file's channel layout. Must be called before SetClientFormat.
// When writing, the specified channel layout is written to the file (if the file format supports
// the channel layout). When reading, the specified layout overrides the one read from the file,
// if any.
void SetFileChannelLayout(const CAAudioChannelLayout &layout);
// This specifies the data format which the client will use for reading/writing the file,
// which may be different from the file's format. An AudioConverter is created if necessary.
// The client format must be linear PCM.
void SetClientFormat(const CAStreamBasicDescription &dataFormat, const CAAudioChannelLayout *layout=NULL);
void SetClientDataFormat(const CAStreamBasicDescription &dataFormat) { SetClientFormat(dataFormat, NULL); }
void SetClientChannelLayout(const CAAudioChannelLayout &layout) { SetClientFormat(mClientDataFormat, &layout); }
// Wrapping the underlying converter, if there is one
OSStatus SetConverterProperty(AudioConverterPropertyID inPropertyID,
UInt32 inPropertyDataSize,
const void * inPropertyData,
bool inCanFail = false);
void SetConverterConfig(CFArrayRef config) {
SetConverterProperty(kAudioConverterPropertySettings, sizeof(config), &config); }
CFArrayRef GetConverterConfig();
// --- I/O ---
// All I/O is sequential, but you can seek to an arbitrary position when reading.
// SeekToPacket and TellPacket's packet numbers are in the file's data format, not the client's.
// However, ReadPackets/WritePackets use packet counts in the client data format.
void Read(UInt32 &ioNumFrames, AudioBufferList *ioData);
void Write(UInt32 numFrames, const AudioBufferList *data);
// These can fail for files without a constant mFramesPerPacket
void Seek(SInt64 frameNumber);
SInt64 Tell() const; // frameNumber
// --- Accessors ---
// note: client parameters only valid if SetClientFormat has been called
AudioFileID GetAudioFileID() const { return mAudioFile; }
const CAStreamBasicDescription &GetFileDataFormat() const { return mFileDataFormat; }
const CAStreamBasicDescription &GetClientDataFormat() const { return mClientDataFormat; }
const CAAudioChannelLayout & GetFileChannelLayout() const { return mFileChannelLayout; }
const CAAudioChannelLayout & GetClientChannelLayout() const { return mClientChannelLayout; }
AudioConverterRef GetConverter() const { return mConverter; }
UInt32 GetFileMaxPacketSize() const { return mFileMaxPacketSize; }
UInt32 GetClientMaxPacketSize() const { return mClientMaxPacketSize; }
SInt64 GetNumberPackets() const {
SInt64 npackets;
UInt32 propertySize = sizeof(npackets);
XThrowIfError(AudioFileGetProperty(mAudioFile, kAudioFilePropertyAudioDataPacketCount, &propertySize, &npackets), "get audio file's packet count");
return npackets;
}
SInt64 GetNumberFrames() const;
// will be 0 if the file's frames/packet is 0 (variable)
void SetNumberFrames(SInt64 length); // should only be set on a PCM file
// --- Tunable performance parameters ---
void SetUseCache(bool b) { mUseCache = b; }
void SetIOBufferSizeBytes(UInt32 bufferSizeBytes) { mIOBufferSizeBytes = bufferSizeBytes; }
UInt32 GetIOBufferSizeBytes() { return mIOBufferSizeBytes; }
void * GetIOBuffer() { return mIOBufferList.mBuffers[0].mData; }
void SetIOBuffer(void *buf);
// -- Profiling ---
#if CAAUDIOFILE_PROFILE
void EnableProfiling(bool b) { mProfiling = b; }
UInt64 TicksInConverter() const { return (mTicksInConverter > 0) ? (mTicksInConverter - mTicksInReadInConverter) : 0; }
UInt64 TicksInIO() const { return mTicksInIO; }
#endif
// _______________________________________________________________________________________
private:
SInt64 FileDataOffset();
void SeekToPacket(SInt64 packetNumber);
SInt64 TellPacket() const { return mPacketMark; } // will be imprecise if SeekToFrame was called
void SetConverterChannelLayout(bool output, const CAAudioChannelLayout &layout);
void WritePacketsFromCallback(
AudioConverterComplexInputDataProc inInputDataProc,
void * inInputDataProcUserData);
// will use I/O buffer size
void InitFileMaxPacketSize();
void FileFormatChanged(const FSRef *parentDir=0, CFStringRef filename=0, AudioFileTypeID filetype=0);
void GetExistingFileInfo();
void FlushEncoder();
void CloseConverter();
void UpdateClientMaxPacketSize();
void AllocateBuffers(bool okToFail=false);
SInt64 PacketToFrame(SInt64 packet) const;
SInt64 FrameToPacket(SInt64 inFrame) const;
static OSStatus ReadInputProc( AudioConverterRef inAudioConverter,
UInt32* ioNumberDataPackets,
AudioBufferList* ioData,
AudioStreamPacketDescription** outDataPacketDescription,
void* inUserData);
static OSStatus WriteInputProc( AudioConverterRef inAudioConverter,
UInt32* ioNumberDataPackets,
AudioBufferList* ioData,
AudioStreamPacketDescription** outDataPacketDescription,
void* inUserData);
// _______________________________________________________________________________________
private:
// the file
FSRef mFSRef;
AudioFileID mAudioFile;
bool mOwnOpenFile;
bool mUseCache;
bool mFinishingEncoding;
enum { kClosed, kReading, kPreparingToCreate, kPreparingToWrite, kWriting } mMode;
// SInt64 mNumberPackets; // in file's format
SInt64 mFileDataOffset;
SInt64 mPacketMark; // in file's format
SInt64 mFrameMark; // this may be offset from the start of the file
// by the codec's latency; i.e. our frame 0 could
// lie at frame 2112 of a decoded AAC file
SInt32 mFrame0Offset;
UInt32 mFramesToSkipFollowingSeek;
// buffers
UInt32 mIOBufferSizeBytes;
UInt32 mIOBufferSizePackets;
AudioBufferList mIOBufferList; // only one buffer -- USE ACCESSOR so it can be lazily initialized
bool mClientOwnsIOBuffer;
AudioStreamPacketDescription *mPacketDescs;
UInt32 mNumPacketDescs;
// formats/conversion
AudioConverterRef mConverter;
CAStreamBasicDescription mFileDataFormat;
CAStreamBasicDescription mClientDataFormat;
CAAudioChannelLayout mFileChannelLayout;
CAAudioChannelLayout mClientChannelLayout;
UInt32 mFileMaxPacketSize;
UInt32 mClientMaxPacketSize;
// cookie
Byte * mMagicCookie;
UInt32 mMagicCookieSize;
// for ReadPackets
UInt32 mMaxPacketsToRead;
// for WritePackets
UInt32 mWritePackets;
CABufferList * mWriteBufferList;
#if CAAUDIOFILE_PROFILE
// performance
bool mProfiling;
UInt64 mTicksInConverter;
UInt64 mTicksInReadInConverter;
UInt64 mTicksInIO;
bool mInConverter;
#endif
#endif // CAAF_USE_EXTAUDIOFILE
};
#endif // __CAAudioFile_h__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,383 @@
/* 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

View File

@ -0,0 +1,179 @@
/* 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.
*/
/*=============================================================================
CABufferList.cpp
=============================================================================*/
#include "CABufferList.h"
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreServices/CoreServices.h>
#else
#include <Endian.h>
#endif
void CABufferList::AllocateBuffers(UInt32 nBytes)
{
if (nBytes <= GetNumBytes()) return;
if (mNumberBuffers > 1)
// align successive buffers for Altivec and to take alternating
// cache line hits by spacing them by odd multiples of 16
nBytes = (nBytes + (0x10 - (nBytes & 0xF))) | 0x10;
UInt32 memorySize = nBytes * mNumberBuffers;
Byte *newMemory = new Byte[memorySize], *p = newMemory;
memset(newMemory, 0, memorySize); // get page faults now, not later
AudioBuffer *buf = mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++buf) {
if (buf->mData != NULL && buf->mDataByteSize > 0)
// preserve existing buffer contents
memcpy(p, buf->mData, buf->mDataByteSize);
buf->mDataByteSize = nBytes;
buf->mData = p;
p += nBytes;
}
Byte *oldMemory = mBufferMemory;
mBufferMemory = newMemory;
delete[] oldMemory;
}
void CABufferList::AllocateBuffersAndCopyFrom(UInt32 nBytes, CABufferList *inSrcList, CABufferList *inSetPtrList)
{
if (mNumberBuffers != inSrcList->mNumberBuffers) return;
if (mNumberBuffers != inSetPtrList->mNumberBuffers) return;
if (nBytes <= GetNumBytes()) {
CopyAllFrom(inSrcList, inSetPtrList);
return;
}
inSetPtrList->VerifyNotTrashingOwnedBuffer();
UInt32 fromByteSize = inSrcList->GetNumBytes();
if (mNumberBuffers > 1)
// align successive buffers for Altivec and to take alternating
// cache line hits by spacing them by odd multiples of 16
nBytes = (nBytes + (0x10 - (nBytes & 0xF))) | 0x10;
UInt32 memorySize = nBytes * mNumberBuffers;
Byte *newMemory = new Byte[memorySize], *p = newMemory;
memset(newMemory, 0, memorySize); // make buffer "hot"
AudioBuffer *buf = mBuffers;
AudioBuffer *ptrBuf = inSetPtrList->mBuffers;
AudioBuffer *srcBuf = inSrcList->mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++buf, ++ptrBuf, ++srcBuf) {
if (srcBuf->mData != NULL && srcBuf->mDataByteSize > 0)
// preserve existing buffer contents
memmove(p, srcBuf->mData, srcBuf->mDataByteSize);
buf->mDataByteSize = nBytes;
buf->mData = p;
ptrBuf->mDataByteSize = srcBuf->mDataByteSize;
ptrBuf->mData = p;
p += nBytes;
}
Byte *oldMemory = mBufferMemory;
mBufferMemory = newMemory;
if (inSrcList != inSetPtrList)
inSrcList->BytesConsumed(fromByteSize);
delete[] oldMemory;
}
void CABufferList::DeallocateBuffers()
{
AudioBuffer *buf = mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++buf) {
buf->mData = NULL;
buf->mDataByteSize = 0;
}
if (mBufferMemory != NULL) {
delete[] mBufferMemory;
mBufferMemory = NULL;
}
}
extern "C" void CAShowAudioBufferList(const AudioBufferList *abl, int framesToPrint, int wordSize)
{
printf("AudioBufferList @ %p:\n", abl);
const AudioBuffer *buf = abl->mBuffers;
for (UInt32 i = 0; i < abl->mNumberBuffers; ++i, ++buf) {
printf(" [%2ld]: %2ldch, %5ld bytes @ %8p",
i, buf->mNumberChannels, buf->mDataByteSize, buf->mData);
if (framesToPrint) {
printf(":");
Byte *p = (Byte *)buf->mData;
for (int j = framesToPrint * buf->mNumberChannels; --j >= 0; )
switch (wordSize) {
case 0:
printf(" %6.3f", *(Float32 *)p);
p += sizeof(Float32);
break;
case 1:
case -1:
printf(" %02X", *p);
p += 1;
break;
case 2:
printf(" %04X", EndianU16_BtoN(*(UInt16 *)p));
p += 2;
break;
case 3:
printf(" %06X", (p[0] << 16) | (p[1] << 8) | p[2]);
p += 3;
break;
case 4:
printf(" %08lX", EndianU32_BtoN(*(UInt32 *)p));
p += 4;
break;
case -2:
printf(" %04X", EndianU16_LtoN(*(UInt16 *)p));
p += 2;
break;
case -3:
printf(" %06X", (p[2] << 16) | (p[1] << 8) | p[0]);
p += 3;
break;
case -4:
printf(" %08lX", EndianU32_LtoN(*(UInt32 *)p));
p += 4;
break;
}
}
printf("\n");
}
}

View File

@ -0,0 +1,300 @@
/* 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.
*/
/*=============================================================================
CABufferList.h
=============================================================================*/
#ifndef __CABufferList_h__
#define __CABufferList_h__
#include <stddef.h>
#include "CAStreamBasicDescription.h"
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreServices/CoreServices.h>
#else
#include <AssertMacros.h>
#endif
extern "C" void CAShowAudioBufferList(const AudioBufferList *abl, int framesToPrint, int wordSize);
// wordSize: 0 = float32, else integer word size, negative if little-endian
/* ____________________________________________________________________________
// CABufferList - variable length buffer list
This class is designed for use in non-simplistic cases. For AudioUnits, AUBufferList
is preferred.
CABufferList can be used in one of two ways:
- as mutable pointers into non-owned memory
- as an immutable array of buffers (owns its own memory).
All buffers are assumed to have the same format (number of channels, word size), so that
we can assume their mDataByteSizes are all the same.
____________________________________________________________________________ */
class CABufferList {
public:
void * operator new(size_t /*size*/, int nBuffers) {
return ::operator new(sizeof(CABufferList) + (nBuffers-1) * sizeof(AudioBuffer));
}
static CABufferList * New(const char *name, const CAStreamBasicDescription &format)
{
UInt32 numBuffers = format.NumberChannelStreams(), channelsPerBuffer = format.NumberInterleavedChannels();
return new(numBuffers) CABufferList(name, numBuffers, channelsPerBuffer);
}
protected:
CABufferList(const char *name, UInt32 numBuffers, UInt32 channelsPerBuffer) :
mName(name),
mBufferMemory(NULL)
{
check(numBuffers > 0 /*&& channelsPerBuffer > 0*/);
mNumberBuffers = numBuffers;
AudioBuffer *buf = mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++buf) {
buf->mNumberChannels = channelsPerBuffer;
buf->mDataByteSize = 0;
buf->mData = NULL;
}
}
public:
~CABufferList()
{
if (mBufferMemory)
delete[] mBufferMemory;
}
const char * Name() { return mName; }
const AudioBufferList & GetBufferList() const { return *(AudioBufferList *)&mNumberBuffers; }
AudioBufferList & GetModifiableBufferList()
{
VerifyNotTrashingOwnedBuffer();
return _GetBufferList();
}
UInt32 GetNumBytes() const
{
return mBuffers[0].mDataByteSize;
}
void SetBytes(UInt32 nBytes, void *data)
{
VerifyNotTrashingOwnedBuffer();
check(mNumberBuffers == 1);
mBuffers[0].mDataByteSize = nBytes;
mBuffers[0].mData = data;
}
void CopyAllFrom(CABufferList *srcbl, CABufferList *ptrbl)
// copies bytes from srcbl
// make ptrbl reflect the length copied
// note that srcbl may be same as ptrbl!
{
// Note that this buffer *can* own memory and its pointers/lengths are not
// altered; only its buffer contents, which are copied from srcbl.
// The pointers/lengths in ptrbl are updated to reflect the addresses/lengths
// of the copied data, and srcbl's contents are consumed.
ptrbl->VerifyNotTrashingOwnedBuffer();
UInt32 nBytes = srcbl->GetNumBytes();
AudioBuffer *mybuf = mBuffers, *srcbuf = srcbl->mBuffers,
*ptrbuf = ptrbl->mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++mybuf, ++srcbuf, ++ptrbuf) {
memmove(mybuf->mData, srcbuf->mData, srcbuf->mDataByteSize);
ptrbuf->mData = mybuf->mData;
ptrbuf->mDataByteSize = srcbuf->mDataByteSize;
}
if (srcbl != ptrbl)
srcbl->BytesConsumed(nBytes);
}
void AppendFrom(CABufferList *blp, UInt32 nBytes)
{
VerifyNotTrashingOwnedBuffer();
AudioBuffer *mybuf = mBuffers, *srcbuf = blp->mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++mybuf, ++srcbuf) {
check(nBytes <= srcbuf->mDataByteSize);
memcpy((Byte *)mybuf->mData + mybuf->mDataByteSize, srcbuf->mData, nBytes);
mybuf->mDataByteSize += nBytes;
}
blp->BytesConsumed(nBytes);
}
void PadWithZeroes(UInt32 desiredBufferSize)
// for cases where an algorithm (e.g. SRC) requires some
// padding to create silence following end-of-file
{
VerifyNotTrashingOwnedBuffer();
if (GetNumBytes() > desiredBufferSize) return;
AudioBuffer *buf = mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++buf) {
memset((Byte *)buf->mData + buf->mDataByteSize, 0, desiredBufferSize - buf->mDataByteSize);
buf->mDataByteSize = desiredBufferSize;
}
}
void SetToZeroes(UInt32 nBytes)
{
VerifyNotTrashingOwnedBuffer();
AudioBuffer *buf = mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++buf) {
memset((Byte *)buf->mData, 0, nBytes);
buf->mDataByteSize = nBytes;
}
}
void Reset()
{
DeallocateBuffers();
}
Boolean SameDataAs(const CABufferList* anotherBufferList)
{
// check to see if two buffer lists point to the same memory.
if (mNumberBuffers != anotherBufferList->mNumberBuffers) return false;
for (UInt32 i = 0; i < mNumberBuffers; ++i) {
if (mBuffers[i].mData != anotherBufferList->mBuffers[i].mData) return false;
}
return true;
}
void BytesConsumed(UInt32 nBytes)
// advance buffer pointers, decrease buffer sizes
{
VerifyNotTrashingOwnedBuffer();
AudioBuffer *buf = mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++buf) {
check(nBytes <= buf->mDataByteSize);
buf->mData = (Byte *)buf->mData + nBytes;
buf->mDataByteSize -= nBytes;
}
}
void SetFrom(const AudioBufferList *abl)
{
VerifyNotTrashingOwnedBuffer();
memcpy(&_GetBufferList(), abl, (char *)&abl->mBuffers[abl->mNumberBuffers] - (char *)abl);
}
void SetFrom(const CABufferList *blp)
{
SetFrom(&blp->GetBufferList());
}
void SetFrom(const AudioBufferList *abl, UInt32 nBytes)
{
VerifyNotTrashingOwnedBuffer();
AudioBuffer *mybuf = mBuffers;
const AudioBuffer *srcbuf = abl->mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++mybuf, ++srcbuf) {
mybuf->mNumberChannels = srcbuf->mNumberChannels;
mybuf->mDataByteSize = nBytes;
mybuf->mData = srcbuf->mData;
}
}
void SetFrom(const CABufferList *blp, UInt32 nBytes)
{
SetFrom(&blp->GetBufferList(), nBytes);
}
AudioBufferList * ToAudioBufferList(AudioBufferList *abl) const
{
memcpy(abl, &GetBufferList(), (char *)&abl->mBuffers[mNumberBuffers] - (char *)abl);
return abl;
}
void AllocateBuffers(UInt32 nBytes);
void AllocateBuffersAndCopyFrom(UInt32 nBytes, CABufferList *inCopyFromList, CABufferList *inSetPtrList);
void DeallocateBuffers();
void UseExternalBuffer(Byte *ptr, UInt32 nBytes);
void AdvanceBufferPointers(UInt32 nBytes)
// this is for bufferlists that function simply as
// an array of pointers into another bufferlist, being advanced,
// as in RenderOutput implementations
{
VerifyNotTrashingOwnedBuffer();
AudioBuffer *buf = mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++buf) {
buf->mData = (Byte *)buf->mData + nBytes;
buf->mDataByteSize -= nBytes;
}
}
void SetNumBytes(UInt32 nBytes)
{
VerifyNotTrashingOwnedBuffer();
AudioBuffer *buf = mBuffers;
for (UInt32 i = mNumberBuffers; i--; ++buf)
buf->mDataByteSize = nBytes;
}
void Print(const char *label=NULL, int nframes=0, int wordSize=0) const
{
if (label == NULL)
label = mName;
printf("%s - ", label);
CAShowAudioBufferList(&GetBufferList(), nframes, wordSize);
if (mBufferMemory)
printf(" owned memory @ 0x%p:\n", mBufferMemory);
}
protected:
AudioBufferList & _GetBufferList() { return *(AudioBufferList *)&mNumberBuffers; } // use with care
// if we make this public, then we lose ability to call VerifyNotTrashingOwnedBuffer
void VerifyNotTrashingOwnedBuffer()
{
// This needs to be called from places where we are modifying the buffer list.
// It's an error to modify the buffer pointers or lengths if we own the buffer memory.
check(mBufferMemory == NULL);
}
const char * mName; // for debugging
Byte * mBufferMemory;
// the rest must exactly mirror the structure of AudioBufferList
UInt32 mNumberBuffers;
AudioBuffer mBuffers[1];
};
#endif // __CABufferList_h__

View File

@ -0,0 +1,478 @@
/* 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.
*/
/*=============================================================================
CACFDictionary.cpp
CAAudioEngine
=============================================================================*/
//=============================================================================
// Includes
//=============================================================================
// Self Include
#include "CACFDictionary.h"
// PublicUtility Includes
#include "CACFString.h"
#include "CACFNumber.h"
//=============================================================================
// CACFDictionary
//=============================================================================
bool CACFDictionary::HasKey(const CFStringRef inKey) const
{
return CFDictionaryContainsKey(mCFDictionary, inKey) != 0;
}
UInt32 CACFDictionary::Size () const
{
return CFDictionaryGetCount(mCFDictionary);
}
void CACFDictionary::GetKeys (const void **keys) const
{
CFDictionaryGetKeysAndValues(mCFDictionary, keys, NULL);
}
bool CACFDictionary::GetBool(const CFStringRef inKey, bool& outValue) const
{
bool theAnswer = false;
CFTypeRef theValue = NULL;
if(GetCFType(inKey, theValue))
{
if((theValue != NULL) && (CFGetTypeID(theValue) == CFBooleanGetTypeID()))
{
outValue = CFBooleanGetValue(static_cast<CFBooleanRef>(theValue));
theAnswer = true;
}
else if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
{
SInt32 theNumericValue = 0;
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &theNumericValue);
outValue = theNumericValue != 0;
theAnswer = true;
}
}
return theAnswer;
}
bool CACFDictionary::GetSInt32(const CFStringRef inKey, SInt32& outValue) const
{
bool theAnswer = false;
CFTypeRef theValue = NULL;
if(GetCFType(inKey, theValue))
{
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
{
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
theAnswer = true;
}
}
return theAnswer;
}
bool CACFDictionary::GetUInt32(const CFStringRef inKey, UInt32& outValue) const
{
bool theAnswer = false;
CFTypeRef theValue = NULL;
if(GetCFType(inKey, theValue))
{
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
{
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
theAnswer = true;
}
}
return theAnswer;
}
bool CACFDictionary::GetSInt64(const CFStringRef inKey, SInt64& outValue) const
{
bool theAnswer = false;
CFTypeRef theValue = NULL;
if(GetCFType(inKey, theValue))
{
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
{
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
theAnswer = true;
}
}
return theAnswer;
}
bool CACFDictionary::GetUInt64(const CFStringRef inKey, UInt64& outValue) const
{
bool theAnswer = false;
CFTypeRef theValue = NULL;
if(GetCFType(inKey, theValue))
{
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
{
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
theAnswer = true;
}
}
return theAnswer;
}
bool CACFDictionary::GetFloat32(const CFStringRef inKey, Float32& outValue) const
{
bool theAnswer = false;
CFTypeRef theValue = NULL;
if(GetCFType(inKey, theValue))
{
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
{
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat32Type, &outValue);
theAnswer = true;
}
}
return theAnswer;
}
bool CACFDictionary::GetFloat64(const CFStringRef inKey, Float64& outValue) const
{
bool theAnswer = false;
CFTypeRef theValue = NULL;
if(GetCFType(inKey, theValue))
{
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
{
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat64Type, &outValue);
theAnswer = true;
}
}
return theAnswer;
}
bool CACFDictionary::GetString(const CFStringRef inKey, CFStringRef& outValue) const
{
bool theAnswer = false;
CFTypeRef theValue = NULL;
if(GetCFType(inKey, theValue))
{
if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
{
outValue = static_cast<CFStringRef>(theValue);
theAnswer = true;
}
}
return theAnswer;
}
bool CACFDictionary::GetArray(const CFStringRef inKey, CFArrayRef& outValue) const
{
bool theAnswer = false;
CFTypeRef theValue = NULL;
if(GetCFType(inKey, theValue))
{
if((theValue != NULL) && (CFGetTypeID(theValue) == CFArrayGetTypeID()))
{
outValue = static_cast<CFArrayRef>(theValue);
theAnswer = true;
}
}
return theAnswer;
}
bool CACFDictionary::GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const
{
bool theAnswer = false;
CFTypeRef theValue = NULL;
if(GetCFType(inKey, theValue))
{
if((theValue != NULL) && (CFGetTypeID(theValue) == CFDictionaryGetTypeID()))
{
outValue = static_cast<CFDictionaryRef>(theValue);
theAnswer = true;
}
}
return theAnswer;
}
bool CACFDictionary::GetData(const CFStringRef inKey, CFDataRef& outValue) const
{
bool theAnswer = false;
CFTypeRef theValue = NULL;
if(GetCFType(inKey, theValue))
{
if((theValue != NULL) && (CFGetTypeID(theValue) == CFDataGetTypeID()))
{
outValue = static_cast<CFDataRef>(theValue);
theAnswer = true;
}
}
return theAnswer;
}
bool CACFDictionary::GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const
{
bool theAnswer = false;
if(mCFDictionary != NULL)
{
outValue = CFDictionaryGetValue(mCFDictionary, inKey);
theAnswer = (outValue != NULL);
}
return theAnswer;
}
bool CACFDictionary::GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const
{
bool theAnswer = false;
if(mCFDictionary != NULL)
{
CACFString theKey(inKey);
if(theKey.IsValid())
{
theAnswer = GetCFType(theKey.GetCFString(), outValue);
}
}
return theAnswer;
}
bool CACFDictionary::AddSInt32(const CFStringRef inKey, SInt32 inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
CACFNumber theValue(inValue);
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
}
return theAnswer;
}
bool CACFDictionary::AddUInt32(const CFStringRef inKey, UInt32 inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
CACFNumber theValue(inValue);
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
}
return theAnswer;
}
bool CACFDictionary::AddSInt64(const CFStringRef inKey, SInt64 inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
CACFNumber theValue(inValue);
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
}
return theAnswer;
}
bool CACFDictionary::AddUInt64(const CFStringRef inKey, UInt64 inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
CACFNumber theValue(inValue);
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
}
return theAnswer;
}
bool CACFDictionary::AddFloat32(const CFStringRef inKey, Float32 inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
CACFNumber theValue(inValue);
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
}
return theAnswer;
}
bool CACFDictionary::AddFloat64(const CFStringRef inKey, Float64 inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
CACFNumber theValue(inValue);
theAnswer = AddCFType(inKey, theValue.GetCFNumber());
}
return theAnswer;
}
bool CACFDictionary::AddNumber(const CFStringRef inKey, const CFNumberRef inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
theAnswer = AddCFType(inKey, inValue);
}
return theAnswer;
}
bool CACFDictionary::AddString(const CFStringRef inKey, const CFStringRef inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
theAnswer = AddCFType(inKey, inValue);
}
return theAnswer;
}
bool CACFDictionary::AddArray(const CFStringRef inKey, const CFArrayRef inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
theAnswer = AddCFType(inKey, inValue);
}
return theAnswer;
}
bool CACFDictionary::AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
theAnswer = AddCFType(inKey, inValue);
}
return theAnswer;
}
bool CACFDictionary::AddData(const CFStringRef inKey, const CFDataRef inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
theAnswer = AddCFType(inKey, inValue);
}
return theAnswer;
}
bool CACFDictionary::AddCFType(const CFStringRef inKey, const CFTypeRef inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
CFDictionarySetValue(mCFDictionary, inKey, inValue);
theAnswer = true;
}
return theAnswer;
}
bool CACFDictionary::AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
CACFString theKey(inKey);
if(theKey.IsValid())
{
theAnswer = AddCFType(theKey.GetCFString(), inValue);
}
}
return theAnswer;
}
bool CACFDictionary::AddCString(const CFStringRef inKey, const char* inValue)
{
bool theAnswer = false;
if(mMutable && (mCFDictionary != NULL))
{
CACFString theValue(inValue);
if(theValue.IsValid())
{
theAnswer = AddCFType(inKey, theValue.GetCFString());
}
}
return theAnswer;
}

View File

@ -0,0 +1,141 @@
/* 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.
*/
/*=============================================================================
CACFDictionary.h
=============================================================================*/
#if !defined(__CACFDictionary_h__)
#define __CACFDictionary_h__
//=============================================================================
// Includes
//=============================================================================
// System Includes
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreFoundation/CoreFoundation.h>
#else
#include <CoreFoundation.h>
#endif
//=============================================================================
// CACFDictionary
//=============================================================================
class CACFDictionary
{
// Construction/Destruction
public:
CACFDictionary(bool inRelease) : mCFDictionary(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)), mRelease(inRelease), mMutable(true) {}
CACFDictionary(const CFDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(const_cast<CFMutableDictionaryRef>(inCFDictionary)), mRelease(inRelease), mMutable(true) {}
CACFDictionary(const CFMutableDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(inCFDictionary), mRelease(inRelease), mMutable(true) {}
CACFDictionary(const CACFDictionary& inDictionary) : mCFDictionary(inDictionary.mCFDictionary), mRelease(inDictionary.mRelease), mMutable(inDictionary.mMutable) { if(mRelease && (mCFDictionary != NULL)) { CFRetain(mCFDictionary); } }
CACFDictionary& operator=(const CACFDictionary& inDictionary) { mCFDictionary = inDictionary.mCFDictionary; mRelease = inDictionary.mRelease; mMutable = inDictionary.mMutable; if(mRelease && (mCFDictionary != NULL)) { CFRetain(mCFDictionary); } return *this; }
~CACFDictionary() { if(mRelease && (mCFDictionary != NULL)) { CFRelease(mCFDictionary); } }
// Attributes
public:
bool IsValid() const { return mCFDictionary != NULL; }
bool IsMutable() const { return mMutable;}
bool CanModify() const { return mMutable && (mCFDictionary != NULL); }
bool WillRelease() const { return mRelease; }
void ShouldRelease(bool inRelease) { mRelease = inRelease; }
CFDictionaryRef GetDict() const { return mCFDictionary; }
CFDictionaryRef GetCFDictionary() const { return mCFDictionary; }
CFDictionaryRef CopyCFDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }
CFMutableDictionaryRef GetMutableDict() { return mCFDictionary; }
CFMutableDictionaryRef GetCFMutableDictionary() const { return mCFDictionary; }
CFMutableDictionaryRef CopyCFMutableDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }
void SetCFMutableDictionaryFromCopy(CFDictionaryRef inDictionary, bool inRelease = true) { if(mRelease && (mCFDictionary != NULL)) { CFRelease(mCFDictionary); } mCFDictionary = CFDictionaryCreateMutableCopy(NULL, 0, inDictionary); mMutable = true; mRelease = inRelease; }
CFPropertyListRef AsPropertyList() const { return mCFDictionary; }
OSStatus GetDictIfMutable(CFMutableDictionaryRef& outDict) const { OSStatus theAnswer = -1; if(mMutable) { outDict = mCFDictionary; theAnswer = 0; } return theAnswer; }
// Item Operations
public:
bool HasKey(const CFStringRef inKey) const;
UInt32 Size() const;
void GetKeys(const void** keys) const;
bool GetBool(const CFStringRef inKey, bool& outValue) const;
bool GetSInt32(const CFStringRef inKey, SInt32& outValue) const;
bool GetUInt32(const CFStringRef inKey, UInt32& outValue) const;
bool GetSInt64(const CFStringRef inKey, SInt64& outValue) const;
bool GetUInt64(const CFStringRef inKey, UInt64& outValue) const;
bool GetFloat32(const CFStringRef inKey, Float32& outValue) const;
bool GetFloat64(const CFStringRef inKey, Float64& outValue) const;
bool GetString(const CFStringRef inKey, CFStringRef& outValue) const;
bool GetArray(const CFStringRef inKey, CFArrayRef& outValue) const;
bool GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const;
bool GetData(const CFStringRef inKey, CFDataRef& outValue) const;
bool GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const;
bool GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const;
bool AddSInt32(const CFStringRef inKey, SInt32 inValue);
bool AddUInt32(const CFStringRef inKey, UInt32 inValue);
bool AddSInt64(const CFStringRef inKey, SInt64 inValue);
bool AddUInt64(const CFStringRef inKey, UInt64 inValue);
bool AddFloat32(const CFStringRef inKey, Float32 inValue);
bool AddFloat64(const CFStringRef inKey, Float64 inValue);
bool AddNumber(const CFStringRef inKey, const CFNumberRef inValue);
bool AddString(const CFStringRef inKey, const CFStringRef inValue);
bool AddArray(const CFStringRef inKey, const CFArrayRef inValue);
bool AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue);
bool AddData(const CFStringRef inKey, const CFDataRef inValue);
bool AddCFType(const CFStringRef inKey, const CFTypeRef inValue);
bool AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue);
bool AddCString(const CFStringRef inKey, const char* inValue);
void Clear() { if(CanModify()) { CFDictionaryRemoveAllValues(mCFDictionary); } }
void Show() { CFShow(mCFDictionary); }
// Implementation
private:
CFMutableDictionaryRef mCFDictionary;
bool mRelease;
bool mMutable;
};
#endif //__CACFDictionary_h__

View File

@ -0,0 +1,65 @@
/* 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.
*/
/*=============================================================================
CACFNumber.cp
=============================================================================*/
//=============================================================================
// Includes
//=============================================================================
#include "CACFNumber.h"
//=============================================================================
// CACFNumber
//=============================================================================
Float32 CACFNumber::GetFixed32() const
{
SInt32 theFixedValue = GetSInt32();
// this is a 16.16 value so convert it to a float
Float32 theSign = theFixedValue < 0 ? -1.0 : 1.0;
theFixedValue *= (SInt32)theSign;
Float32 theWholePart = (theFixedValue & 0x7FFF0000) >> 16;
Float32 theFractPart = theFixedValue & 0x0000FFFF;
theFractPart /= 65536.0;
return theSign * (theWholePart + theFractPart);
}

View File

@ -0,0 +1,102 @@
/* 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.
*/
/*=============================================================================
CACFNumber.h
=============================================================================*/
#if !defined(__CACFNumber_h__)
#define __CACFNumber_h__
//=============================================================================
// Includes
//=============================================================================
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreAudio/CoreAudioTypes.h>
#include <CoreFoundation/CFNumber.h>
#else
#include <CoreAudioTypes.h>
#include <CFNumber.h>
#endif
//=============================================================================
// CACFNumber
//=============================================================================
class CACFNumber
{
// Construction/Destruction
public:
CACFNumber(CFNumberRef inCFNumber, bool inWillRelease = true) : mCFNumber(inCFNumber), mWillRelease(inWillRelease) {}
CACFNumber(SInt32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt32Type, &inValue)), mWillRelease(true) {}
CACFNumber(UInt32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt32Type, &inValue)), mWillRelease(true) {}
CACFNumber(SInt64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt64Type, &inValue)), mWillRelease(true) {}
CACFNumber(UInt64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt64Type, &inValue)), mWillRelease(true) {}
CACFNumber(Float32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberFloat32Type, &inValue)), mWillRelease(true) {}
CACFNumber(Float64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberFloat64Type, &inValue)), mWillRelease(true) {}
~CACFNumber() { Release(); }
CACFNumber(const CACFNumber& inNumber) : mCFNumber(inNumber.mCFNumber), mWillRelease(inNumber.mWillRelease) { Retain(); }
CACFNumber& operator=(const CACFNumber& inNumber) { Release(); mCFNumber = inNumber.mCFNumber; mWillRelease = inNumber.mWillRelease; Retain(); return *this; }
CACFNumber& operator=(CFNumberRef inCFNumber) { Release(); mCFNumber = inCFNumber; mWillRelease = true; return *this; }
private:
void Retain() { if(mWillRelease && (mCFNumber != NULL)) { CFRetain(mCFNumber); } }
void Release() { if(mWillRelease && (mCFNumber != NULL)) { CFRelease(mCFNumber); } }
CFNumberRef mCFNumber;
bool mWillRelease;
// Operations
public:
void AllowRelease() { mWillRelease = true; }
void DontAllowRelease() { mWillRelease = false; }
bool IsValid() { return mCFNumber != NULL; }
// Value Access
public:
CFNumberRef GetCFNumber() const { return mCFNumber; }
CFNumberRef CopyCFNumber() const { if(mCFNumber != NULL) { CFRetain(mCFNumber); } return mCFNumber; }
SInt8 GetSInt8() const { SInt8 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt8Type, &theAnswer); } return theAnswer; }
SInt32 GetSInt32() const { SInt32 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt32Type, &theAnswer); } return theAnswer; }
Float32 GetFloat32() const { Float32 theAnswer = 0.0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberFloat32Type, &theAnswer); } return theAnswer; }
Float32 GetFixed32() const;
SInt64 GetSInt64() const { SInt64 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt64Type, &theAnswer); } return theAnswer; }
};
#endif

View File

@ -0,0 +1,106 @@
/* 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.
*/
/*=============================================================================
CACFString.cp
=============================================================================*/
//=============================================================================
// Includes
//=============================================================================
#include "CACFString.h"
//=============================================================================
// CACFString
//=============================================================================
UInt32 CACFString::GetStringByteLength(CFStringRef inCFString, CFStringEncoding inEncoding)
{
UInt32 theAnswer = 0;
if(inCFString != NULL)
{
CFRange theRange = { 0, CFStringGetLength(inCFString) };
CFStringGetBytes(inCFString, theRange, inEncoding, 0, false, NULL, 0x7FFFFFFF, (CFIndex*)&theAnswer);
}
return theAnswer;
}
void CACFString::GetCString(CFStringRef inCFString, char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding)
{
if(ioStringSize > 0)
{
if(inCFString != NULL)
{
CFIndex theLength = 0;
CFRange theRange = { 0, CFStringGetLength(inCFString) };
CFStringGetBytes(inCFString, theRange, inEncoding, 0, false, (UInt8*)outString, ioStringSize - 1, &theLength);
outString[theLength] = 0;
ioStringSize = theLength + 1;
}
else
{
outString[0] = 0;
ioStringSize = 1;
}
}
}
void CACFString::GetUnicodeString(CFStringRef inCFString, UInt16* outString, UInt32& ioStringSize)
{
if(ioStringSize > 0)
{
if(inCFString != NULL)
{
CFRange theStringRange = { 0, CFStringGetLength(inCFString) };
if(static_cast<UInt32>(theStringRange.length) > ioStringSize)
{
theStringRange.length = ioStringSize;
}
CFStringGetCharacters(inCFString, theStringRange, outString);
ioStringSize = theStringRange.length;
}
else
{
outString[0] = 0;
ioStringSize = 0;
}
}
}

View File

@ -0,0 +1,156 @@
/* 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.
*/
/*=============================================================================
CACFString.h
=============================================================================*/
#if !defined(__CACFString_h__)
#define __CACFString_h__
//=============================================================================
// Includes
//=============================================================================
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreAudio/CoreAudioTypes.h>
#include <CoreFoundation/CFString.h>
#else
#include <CoreAudioTypes.h>
#include <CFString.h>
#endif
//=============================================================================
// CACFString
//=============================================================================
class CACFString
{
// Construction/Destruction
public:
CACFString() : mCFString(NULL), mWillRelease(true) {}
CACFString(CFStringRef inCFString, bool inWillRelease = true) : mCFString(inCFString), mWillRelease(inWillRelease) {}
CACFString(const char* inCString, bool inWillRelease = true) : mCFString(CFStringCreateWithCString(NULL, inCString, kCFStringEncodingASCII)), mWillRelease(inWillRelease) {}
CACFString(const char* inCString, CFStringEncoding inCStringEncoding, bool inWillRelease = true) : mCFString(CFStringCreateWithCString(NULL, inCString, inCStringEncoding)), mWillRelease(inWillRelease) {}
~CACFString() { Release(); }
CACFString(const CACFString& inString) : mCFString(inString.mCFString), mWillRelease(inString.mWillRelease) { Retain(); }
CACFString& operator=(const CACFString& inString) { Release(); mCFString = inString.mCFString; mWillRelease = inString.mWillRelease; Retain(); return *this; }
CACFString& operator=(CFStringRef inCFString) { Release(); mCFString = inCFString; mWillRelease = true; return *this; }
private:
void Retain() { if(mWillRelease && (mCFString != NULL)) { CFRetain(mCFString); } }
void Release() { if(mWillRelease && (mCFString != NULL)) { CFRelease(mCFString); } }
CFStringRef mCFString;
bool mWillRelease;
// Operations
public:
void AllowRelease() { mWillRelease = true; }
void DontAllowRelease() { mWillRelease = false; }
bool IsValid() const { return mCFString != NULL; }
bool StartsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringHasPrefix(mCFString, inString); } return theAnswer; }
bool EndsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringHasSuffix(mCFString, inString); } return theAnswer; }
// Value Access
public:
CFStringRef GetCFString() const { return mCFString; }
CFStringRef CopyCFString() const { if(mCFString != NULL) { CFRetain(mCFString); } return mCFString; }
UInt32 GetLength() const { UInt32 theAnswer = 0; if(mCFString != NULL) { theAnswer = CFStringGetLength(mCFString); } return theAnswer; }
UInt32 GetByteLength(CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { UInt32 theAnswer = 0; if(mCFString != NULL) { theAnswer = GetStringByteLength(mCFString, inEncoding); } return theAnswer; }
void GetCString(char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { GetCString(mCFString, outString, ioStringSize, inEncoding); }
void GetUnicodeString(UInt16* outString, UInt32& ioStringSize) const { GetUnicodeString(mCFString, outString, ioStringSize); }
static UInt32 GetStringByteLength(CFStringRef inCFString, CFStringEncoding inEncoding = kCFStringEncodingUTF8);
static void GetCString(CFStringRef inCFString, char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8);
static void GetUnicodeString(CFStringRef inCFString, UInt16* outString, UInt32& ioStringSize);
};
inline bool operator<(const CACFString& x, const CACFString& y) { return CFStringCompare(x.GetCFString(), y.GetCFString(), 0) == kCFCompareLessThan; }
inline bool operator==(const CACFString& x, const CACFString& y) { return CFStringCompare(x.GetCFString(), y.GetCFString(), 0) == kCFCompareEqualTo; }
inline bool operator!=(const CACFString& x, const CACFString& y) { return !(x == y); }
inline bool operator<=(const CACFString& x, const CACFString& y) { return (x < y) || (x == y); }
inline bool operator>=(const CACFString& x, const CACFString& y) { return !(x < y); }
inline bool operator>(const CACFString& x, const CACFString& y) { return !((x < y) || (x == y)); }
//=============================================================================
// CACFMutableString
//=============================================================================
class CACFMutableString
{
// Construction/Destruction
public:
CACFMutableString() : mCFMutableString(NULL), mWillRelease(true) {}
CACFMutableString(CFMutableStringRef inCFMutableString, bool inWillRelease = true) : mCFMutableString(inCFMutableString), mWillRelease(inWillRelease) {}
CACFMutableString(CFStringRef inStringToCopy, bool /*inMakeCopy*/, bool inWillRelease = true) : mCFMutableString(CFStringCreateMutableCopy(NULL, 0, inStringToCopy)), mWillRelease(inWillRelease) {}
CACFMutableString(const char* inCString, bool inWillRelease = true) : mCFMutableString(NULL), mWillRelease(inWillRelease) { CACFString theString(inCString); mCFMutableString = CFStringCreateMutableCopy(NULL, 0, theString.GetCFString()); }
CACFMutableString(const char* inCString, CFStringEncoding inCStringEncoding, bool inWillRelease = true) : mCFMutableString(NULL), mWillRelease(inWillRelease) { CACFString theString(inCString, inCStringEncoding); mCFMutableString = CFStringCreateMutableCopy(NULL, 0, theString.GetCFString()); }
~CACFMutableString() { Release(); }
CACFMutableString(const CACFMutableString& inString) : mCFMutableString(inString.mCFMutableString), mWillRelease(inString.mWillRelease) { Retain(); }
CACFMutableString operator=(const CACFMutableString& inString) { Release(); mCFMutableString = inString.mCFMutableString; mWillRelease = inString.mWillRelease; Retain(); return *this; }
CACFMutableString operator=(CFMutableStringRef inCFMutableString) { Release(); mCFMutableString = inCFMutableString; mWillRelease = true; return *this; }
private:
void Retain() { if(mWillRelease && (mCFMutableString != NULL)) { CFRetain(mCFMutableString); } }
void Release() { if(mWillRelease && (mCFMutableString != NULL)) { CFRelease(mCFMutableString); } }
CFMutableStringRef mCFMutableString;
bool mWillRelease;
// Operations
public:
void AllowRelease() { mWillRelease = true; }
void DontAllowRelease() { mWillRelease = false; }
bool IsValid() { return mCFMutableString != NULL; }
bool StartsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringHasPrefix(mCFMutableString, inString); } return theAnswer; }
bool EndsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringHasSuffix(mCFMutableString, inString); } return theAnswer; }
void Append(CFStringRef inString) { if(mCFMutableString != NULL) { CFStringAppend(mCFMutableString, inString); } }
// Value Access
public:
CFMutableStringRef GetCFMutableString() const { return mCFMutableString; }
CFMutableStringRef CopyCFMutableString() const { if(mCFMutableString != NULL) { CFRetain(mCFMutableString); } return mCFMutableString; }
UInt32 GetLength() const { UInt32 theAnswer = 0; if(mCFMutableString != NULL) { theAnswer = CFStringGetLength(mCFMutableString); } return theAnswer; }
UInt32 GetByteLength(CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { UInt32 theAnswer = 0; if(mCFMutableString != NULL) { theAnswer = CACFString::GetStringByteLength(mCFMutableString, inEncoding); } return theAnswer; }
void GetCString(char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { CACFString::GetCString(mCFMutableString, outString, ioStringSize, inEncoding); }
void GetUnicodeString(UInt16* outString, UInt32& ioStringSize) const { CACFString::GetUnicodeString(mCFMutableString, outString, ioStringSize); }
};
#endif

View File

@ -0,0 +1,257 @@
/* 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.
*/
/*=============================================================================
CAComponent.cpp
=============================================================================*/
#include "CAComponent.h"
#include "CAComponentDescription.h"
#include "CACFDictionary.h"
#include <stdlib.h>
CAComponent::CAComponent (const ComponentDescription& inDesc, CAComponent* next)
: mManuName(0), mAUName(0), mCompName(0), mCompInfo (0)
{
mComp = FindNextComponent ((next ? next->Comp() : NULL), const_cast<ComponentDescription*>(&inDesc));
if (mComp)
GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
else
memcpy (&mDesc, &inDesc, sizeof(ComponentDescription));
}
CAComponent::CAComponent (const Component& comp)
: mComp (comp),
mManuName(0),
mAUName(0),
mCompName(0),
mCompInfo (0)
{
GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
}
CAComponent::CAComponent (const ComponentInstance& compInst)
: mComp (Component(compInst)),
mManuName(0),
mAUName(0),
mCompName(0),
mCompInfo (0)
{
GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
}
CAComponent::CAComponent (OSType inType, OSType inSubtype, OSType inManu)
: mDesc (inType, inSubtype, inManu),
mManuName(0), mAUName(0), mCompName(0), mCompInfo (0)
{
mComp = FindNextComponent (NULL, &mDesc);
GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
}
CAComponent::~CAComponent ()
{
Clear();
}
OSStatus CAComponent::GetResourceVersion (UInt32 &outVersion) const
{
bool versionFound = false;
short componentResFileID = kResFileNotOpened;
OSStatus result;
short thngResourceCount;
short curRes = CurResFile();
require_noerr (result = OpenAComponentResFile( mComp, &componentResFileID), home);
require_noerr (result = componentResFileID <= 0, home);
UseResFile(componentResFileID);
thngResourceCount = Count1Resources(kComponentResourceType);
require_noerr (result = ResError(), home);
// only go on if we successfully found at least 1 thng resource
require_noerr (thngResourceCount <= 0 ? -1 : 0, home);
// loop through all of the Component thng resources trying to
// find one that matches this Component description
for (short i = 0; i < thngResourceCount && (!versionFound); i++)
{
// try to get a handle to this code resource
Handle thngResourceHandle = Get1IndResource(kComponentResourceType, i+1);
if (thngResourceHandle != NULL && ((*thngResourceHandle) != NULL))
{
if (UInt32(GetHandleSize(thngResourceHandle)) >= sizeof(ExtComponentResource))
{
ExtComponentResource * componentThng = (ExtComponentResource*) (*thngResourceHandle);
// check to see if this is the thng resource for the particular Component that we are looking at
// (there often is more than one Component described in the resource)
if ((componentThng->cd.componentType == mDesc.Type())
&& (componentThng->cd.componentSubType == mDesc.SubType())
&& (componentThng->cd.componentManufacturer == mDesc.Manu()))
{
outVersion = componentThng->componentVersion;
versionFound = true;
}
}
ReleaseResource(thngResourceHandle);
}
}
if (!versionFound)
result = resNotFound;
UseResFile(curRes); // revert
if ( componentResFileID != kResFileNotOpened )
CloseComponentResFile(componentResFileID);
home:
return result;
}
void CAComponent::Clear ()
{
if (mManuName) { CFRelease (mManuName); mManuName = 0; }
if (mAUName) { CFRelease (mAUName); mAUName = 0; }
if (mCompName) { CFRelease (mCompName); mCompName = 0; }
if (mCompInfo) { CFRelease (mCompInfo); mCompInfo = 0; }
}
CAComponent& CAComponent::operator= (const CAComponent& y)
{
Clear();
mComp = y.mComp;
mDesc = y.mDesc;
if (y.mManuName) { mManuName = y.mManuName; CFRetain (mManuName); }
if (y.mAUName) { mAUName = y.mAUName; CFRetain (mAUName); }
if (y.mCompName) { mCompName = y.mCompName; CFRetain (mCompName); }
if (y.mCompInfo) { mCompInfo = y.mCompInfo; CFRetain (mCompInfo); }
return *this;
}
void CAComponent::SetCompNames () const
{
if (!mCompName) {
Handle h1 = NewHandle(4);
CAComponentDescription desc;
OSStatus err = GetComponentInfo (Comp(), &desc, h1, 0, 0);
if (err) { DisposeHandle(h1); return; }
HLock(h1);
char* ptr1 = *h1;
// Get the manufacturer's name... look for the ':' character convention
int len = *ptr1++;
char* displayStr = 0;
const_cast<CAComponent*>(this)->mCompName = CFStringCreateWithPascalString(NULL, (const unsigned char*)*h1, kCFStringEncodingMacRoman);
for (int i = 0; i < len; ++i) {
if (ptr1[i] == ':') { // found the name
ptr1[i] = 0;
displayStr = ptr1;
break;
}
}
if (displayStr)
{
const_cast<CAComponent*>(this)->mManuName = CFStringCreateWithCString(NULL, displayStr, kCFStringEncodingMacRoman);
//move displayStr ptr past the manu, to the name
// we move the characters down a index, because the handle doesn't have any room
// at the end for the \0
int i = strlen(displayStr), j = 0;
while (displayStr[++i] == ' ' && i < len)
;
while (i < len)
displayStr[j++] = displayStr[i++];
displayStr[j] = 0;
const_cast<CAComponent*>(this)->mAUName = CFStringCreateWithCString(NULL, displayStr, kCFStringEncodingMacRoman);
}
DisposeHandle (h1);
}
}
void CAComponent::SetCompInfo () const
{
if (!mCompInfo) {
Handle h1 = NewHandle(4);
CAComponentDescription desc;
OSStatus err = GetComponentInfo (Comp(), &desc, 0, h1, 0);
if (err) return;
HLock (h1);
const_cast<CAComponent*>(this)->mCompInfo = CFStringCreateWithPascalString(NULL, (const unsigned char*)*h1, kCFStringEncodingMacRoman);
DisposeHandle (h1);
}
}
void _ShowCF (FILE* file, CFStringRef str)
{
if (CFGetTypeID(str) != CFStringGetTypeID()) {
CFShow(str);
return;
}
UInt32 len = CFStringGetLength(str);
char* chars = (char*)malloc (len * 2); // give us plenty of room for unichar chars
if (CFStringGetCString (str, chars, len * 2, kCFStringEncodingUTF8))
fprintf (file, "%s", chars);
else
CFShow (str);
free (chars);
}
void CAComponent::Print(FILE* file) const
{
fprintf (file, "CAComponent: 0x%X", int(Comp()));
if (mManuName) {
fprintf (file, ", Manu:"); _ShowCF (file, mManuName);
if (mAUName) fprintf (file, ", Name:"); _ShowCF (file, mAUName);
}
fprintf (file, ", ");
Desc ().Print(file);
}

View File

@ -0,0 +1,120 @@
/* 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.
*/
/*=============================================================================
CAComponent.h
=============================================================================*/
#ifndef __CAComponent_h__
#define __CAComponent_h__
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreServices/CoreServices.h>
#else
#include <ConditionalMacros.h>
#include <CoreServices.h>
#endif
#include "CAComponentDescription.h"
class CAComponent
{
public:
CAComponent ()
: mComp (0), mDesc(), mManuName(0), mAUName(0), mCompName(0), mCompInfo (0) {}
// if next is specifed that is used to find the next component after that one
CAComponent (const ComponentDescription& inDesc, CAComponent* next = 0);
CAComponent (const CAComponent& y)
: mComp (0), mDesc(), mManuName(0), mAUName(0), mCompName(0), mCompInfo (0) { *this = y; }
CAComponent (const Component& comp);
CAComponent (const ComponentInstance& compInst);
CAComponent (OSType inType, OSType inSubtype = 0, OSType inManu = 0);
~CAComponent ();
CAComponent& operator= (const CAComponent& y);
// returns true if this object references a valid component
bool IsValid () const { return Comp() != 0; }
bool HasAUStrings() const { SetCompNames (); return mManuName != 0; }
// CFStringRef should be retained by caller if needed beyond lifetime of this object
// Can return NULL if component doesn't follow AU naming conventions
CFStringRef GetAUManu () const { SetCompNames (); return mManuName; }
CFStringRef GetAUName () const { SetCompNames (); return mAUName ? mAUName : mCompName; }
// Return value of NULL indicates a problem getting that information from the component
CFStringRef GetCompName () const { SetCompNames(); return mCompName; }
CFStringRef GetCompInfo () const { SetCompInfo(); return mCompInfo; }
const CAComponentDescription& Desc () const { return mDesc; }
OSStatus Open (ComponentInstance& outInst) const
{
return OpenAComponent (Comp(), &outInst);
}
OSStatus GetResourceVersion (UInt32 &outVersion) const;
const Component& Comp() const { return mComp; }
void Print(FILE* file = stdout) const;
OSStatus Save (CFPropertyListRef *outData) const;
OSStatus Restore (CFPropertyListRef &inData);
private:
Component mComp;
CAComponentDescription mDesc;
CFStringRef mManuName, mAUName, mCompName, mCompInfo;
void SetCompNames () const;
void SetCompInfo () const;
void Clear ();
};
#endif

View File

@ -0,0 +1,123 @@
/* 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.
*/
/*=============================================================================
CAComponentDescription.cpp
=============================================================================*/
#include "CAComponentDescription.h"
#include <ctype.h>
extern "C" void CAShowComponentDescription(const ComponentDescription *desc)
{
CAComponentDescription::_CAShowComponentDescription (desc, stdout);
}
char *StringForOSType (OSType t, char *writeLocation)
{
char *p = writeLocation;
unsigned char str[4], *q = str;
*(UInt32 *)str = EndianU32_NtoB(t);
for (int i = 0; i < 4; ++i) {
if (isprint(*q) && *q != '\\')
*p++ = *q++;
else {
sprintf(p, "\\x%02X", *q++);
p += 4;
}
}
*p = '\0';
return writeLocation;
}
void CAComponentDescription::_CAShowComponentDescription(const ComponentDescription *desc, FILE* file)
{
if (desc)
{
char str[24];
fprintf (file, "ComponentDescription: %s - ", StringForOSType(desc->componentType, str));
fprintf (file, "%s - ", StringForOSType(desc->componentSubType, str));
fprintf (file, "%s", StringForOSType(desc->componentManufacturer, str));
fprintf (file, ", 0x%lX, 0x%lX\n", desc->componentFlags, desc->componentFlagsMask);
}
}
CAComponentDescription::CAComponentDescription (OSType inType, OSType inSubtype, OSType inManu)
{
componentType = inType;
componentSubType = inSubtype;
componentManufacturer = inManu;
componentFlags = 0;
componentFlagsMask = 0;
}
bool CAComponentDescription::IsAU () const
{
bool flag = IsEffect() || IsMusicDevice() || IsOffline();
if (flag) return true;
switch (componentType) {
case kAudioUnitType_Output:
case kAudioUnitType_FormatConverter:
case kAudioUnitType_Mixer:
return true;
}
return false;
}
inline bool _MatchTest (const OSType &inTypeA, const OSType &inTypeB)
{
return ((inTypeA == inTypeB) || (!inTypeA && !inTypeB) || (inTypeA && !inTypeB) || (!inTypeA && inTypeB));
}
bool CAComponentDescription::Matches (const ComponentDescription &desc) const
{
bool matches = false;
// see if the type matches
matches = _MatchTest (componentType, desc.componentType);
if (matches)
matches = _MatchTest (componentSubType, desc.componentSubType);
if (matches)
matches = _MatchTest (componentManufacturer, desc.componentManufacturer);
return matches;
}

View File

@ -0,0 +1,148 @@
/* 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.
*/
/*=============================================================================
CAComponentDescription.h
=============================================================================*/
#ifndef __CAComponentDescription_h__
#define __CAComponentDescription_h__
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreServices/CoreServices.h>
#include <AudioUnit/AudioUnit.h>
#else
#include <ConditionalMacros.h>
#include <CoreServices.h>
#include <AudioUnit.h>
#endif
#include "CACFDictionary.h"
#include <stdio.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
void CAShowComponentDescription(const ComponentDescription *desc);
#ifdef __cplusplus
}
#endif
// ____________________________________________________________________________
//
// CAComponentDescription
class CAComponentDescription : public ComponentDescription {
public:
CAComponentDescription() { memset (this, 0, sizeof (ComponentDescription)); }
CAComponentDescription (OSType inType, OSType inSubtype = 0, OSType inManu = 0);
CAComponentDescription(const ComponentDescription& desc) { memcpy (this, &desc, sizeof (ComponentDescription)); }
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
//
// interrogation
bool IsAU () const;
bool IsAUFX() const { return componentType == kAudioUnitType_Effect; }
bool IsAUFM() const { return componentType == kAudioUnitType_MusicEffect; }
bool IsEffect () const { return IsAUFX() || IsAUFM() || IsPanner(); }
bool IsOffline () const { return componentType == 'auol'; }
bool IsFConv () const { return componentType == kAudioUnitType_FormatConverter; }
bool IsPanner () const { return componentType == kAudioUnitType_Panner; }
bool IsMusicDevice () const { return componentType == kAudioUnitType_MusicDevice; }
#ifndef MAC_OS_X_VERSION_10_4
bool IsGenerator () const { return componentType =='augn'; }
#else
bool IsGenerator () const { return componentType ==kAudioUnitType_Generator; }
#endif
bool IsOutput () const { return componentType == kAudioUnitType_Output; }
bool IsSource () const { return IsMusicDevice() || IsGenerator(); }
OSType Type () const { return componentType; }
OSType SubType () const { return componentSubType; }
OSType Manu () const { return componentManufacturer; }
int Count() const { return CountComponents(const_cast<CAComponentDescription*>(this)); }
// does a semantic match where "wild card" values for type, subtype, manu will match
bool Matches (const ComponentDescription &desc) const;
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
//
// other
void Print(FILE* file = stdout) const { _CAShowComponentDescription (this, file); }
OSStatus Save (CFPropertyListRef *outData) const;
OSStatus Restore (CFPropertyListRef &inData);
private:
static void _CAShowComponentDescription (const ComponentDescription *desc, FILE* file);
friend void CAShowComponentDescription (const ComponentDescription *desc);
};
inline bool operator< (const ComponentDescription& x, const ComponentDescription& y)
{
return memcmp (&x, &y, offsetof (ComponentDescription, componentFlags)) < 0;
}
inline bool operator== (const ComponentDescription& x, const ComponentDescription& y)
{
return !memcmp (&x, &y, offsetof (ComponentDescription, componentFlags));
}
inline bool operator!= (const ComponentDescription& x, const ComponentDescription& y)
{
return !(x == y);
}
#endif

View File

@ -0,0 +1,74 @@
/* 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.
*/
/*=============================================================================
CAConditionalMacros.h
=============================================================================*/
#if !defined(__CAConditionalMacros_h__)
#define __CAConditionalMacros_h__
//=============================================================================
// This file exists to make figuring out how to include system headers
// easier in a cross platform world. We throw in an include of the standard
// ConditionalMacros too.
//=============================================================================
// ########## THIS FILE SHOULD GO AWAY SOON, replaced by __COREAUDIO_USE_FLAT_INCLUDES__
// but for now, use this as a way to define __COREAUDIO_USE_FLAT_INCLUDES__ programmatically
// TargetConditionals.h defines the bare minimum we need
#include "TargetConditionals.h"
// Determine whether or not to use framework style includes for system headers
#if !defined(CoreAudio_Use_Framework_Includes) && !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#if TARGET_RT_MAC_MACHO
#define CoreAudio_Use_Framework_Includes 1
#else
#define CoreAudio_Use_Framework_Includes 0
#endif
#endif
// Include the regular ConditionalMacros.h too, since it has useful stuff that
// TargetConditionals.h lacks for some reason.
#if CoreAudio_Use_Framework_Includes
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h>
#else
#include "ConditionalMacros.h"
#endif
#endif

View File

@ -0,0 +1,84 @@
/* 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.
*/
/*=============================================================================
CADebugMacros.cp
=============================================================================*/
#include "CADebugMacros.h"
#include <stdio.h>
#include <stdarg.h>
#if TARGET_API_MAC_OSX
#include <syslog.h>
#endif
#if DEBUG
#include <stdio.h>
void DebugPrint(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
#endif // DEBUG
#if TARGET_API_MAC_OSX
void LogError(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
#if DEBUG
vprintf(fmt, args);
#endif
vsyslog(LOG_ERR, fmt, args);
va_end(args);
}
void LogWarning(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
#if DEBUG
vprintf(fmt, args);
#endif
vsyslog(LOG_WARNING, fmt, args);
va_end(args);
}
#endif

View File

@ -0,0 +1,414 @@
/* 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.
*/
/*=============================================================================
CADebugMacros.h
=============================================================================*/
#if !defined(__CADebugMacros_h__)
#define __CADebugMacros_h__
//=============================================================================
// CADebugMacros
//=============================================================================
//#define CoreAudio_StopOnFailure 1
//#define CoreAudio_TimeStampMessages 1
//#define CoreAudio_ThreadStampMessages 1
//#define CoreAudio_FlushDebugMessages 1
#define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 }
#pragma mark Basic Definitions
#if DEBUG || CoreAudio_Debug
// can be used to break into debugger immediately, also see CADebugger
#define BusError() (*(long *)0 = 0)
// basic debugging print routines
#if TARGET_OS_MAC && !TARGET_API_MAC_CARBON
extern pascal void DebugStr(const unsigned char* debuggerMsg);
#define DebugMessage(msg) DebugStr("\p"msg)
#define DebugMessageN1(msg, N1)
#define DebugMessageN2(msg, N1, N2)
#define DebugMessageN3(msg, N1, N2, N3)
#else
#include "CADebugPrintf.h"
#if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile)
#define FlushRtn ;fflush(DebugPrintfFile)
#else
#define FlushRtn
#endif
#if CoreAudio_ThreadStampMessages
#include <pthread.h>
#include "CAHostTimeBase.h"
#define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn
#define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn
#define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn
#define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn
#define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn
#define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn
#define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn
#define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn
#define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn
#define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn
#elif CoreAudio_TimeStampMessages
#include "CAHostTimeBase.h"
#define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFile, "%.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn
#define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn
#define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn
#define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn
#define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn
#define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn
#define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn
#define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn
#define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn
#define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn
#else
#define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFile, "%s"DebugPrintfLineEnding, msg) FlushRtn
#define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1) FlushRtn
#define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2) FlushRtn
#define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3) FlushRtn
#define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4) FlushRtn
#define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5) FlushRtn
#define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6) FlushRtn
#define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7) FlushRtn
#define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn
#define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn
#endif
#endif
void DebugPrint(const char *fmt, ...); // can be used like printf
#define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h)
#if VERBOSE
#define vprint(msg) DEBUGPRINT(msg)
#else
#define vprint(msg)
#endif
#if CoreAudio_StopOnFailure
#include "CADebugger.h"
#define STOP CADebuggerStop()
#else
#define STOP
#endif
#else
#define DebugMessage(msg)
#define DebugMessageN1(msg, N1)
#define DebugMessageN2(msg, N1, N2)
#define DebugMessageN3(msg, N1, N2, N3)
#define DebugMessageN4(msg, N1, N2, N3, N4)
#define DebugMessageN5(msg, N1, N2, N3, N4, N5)
#define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6)
#define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7)
#define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8)
#define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9)
#define DEBUGPRINT(msg)
#define vprint(msg)
#define STOP
#endif
void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging)
void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging)
#if DEBUG || CoreAudio_Debug
#pragma mark Debug Macros
#define Assert(inCondition, inMessage) \
if(!(inCondition)) \
{ \
DebugMessage(inMessage); \
STOP; \
}
#define AssertNoError(inError, inMessage) \
{ \
SInt32 __Err = (inError); \
if(__Err != 0) \
{ \
char __4CC[5] = CA4CCToCString(__Err); \
DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \
STOP; \
} \
}
#define AssertNoKernelError(inError, inMessage) \
{ \
unsigned int __Err = (unsigned int)(inError); \
if(__Err != 0) \
{ \
DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
STOP; \
} \
}
#define FailIf(inCondition, inHandler, inMessage) \
if(inCondition) \
{ \
DebugMessage(inMessage); \
STOP; \
goto inHandler; \
}
#define FailWithAction(inCondition, inAction, inHandler, inMessage) \
if(inCondition) \
{ \
DebugMessage(inMessage); \
STOP; \
{ inAction; } \
goto inHandler; \
}
#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \
if((inPointer) == NULL) \
{ \
DebugMessage(inMessage); \
STOP; \
{ inAction; } \
goto inHandler; \
}
#define FailIfKernelError(inKernelError, inException, inMessage) \
{ \
kern_return_t __Err = (inKernelError); \
if(__Err != 0) \
{ \
DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
STOP; \
{ inAction; } \
goto inHandler; \
} \
}
#define FailIfError(inError, inException, inMessage) \
{ \
SInt32 __Err = (inError); \
if(__Err != 0) \
{ \
char __4CC[5] = CA4CCToCString(__Err); \
DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \
STOP; \
{ inAction; } \
goto inHandler; \
} \
}
#if defined(__cplusplus)
#define Throw(inException) STOP; throw (inException)
#define ThrowIf(inCondition, inException, inMessage) \
if(inCondition) \
{ \
DebugMessage(inMessage); \
Throw(inException); \
}
#define ThrowIfNULL(inPointer, inException, inMessage) \
if((inPointer) == NULL) \
{ \
DebugMessage(inMessage); \
Throw(inException); \
}
#define ThrowIfKernelError(inKernelError, inException, inMessage) \
{ \
kern_return_t __Err = (inKernelError); \
if(__Err != 0) \
{ \
DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
Throw(inException); \
} \
}
#define ThrowIfError(inError, inException, inMessage) \
{ \
SInt32 __Err = (inError); \
if(__Err != 0) \
{ \
char __4CC[5] = CA4CCToCString(__Err); \
DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \
Throw(inException); \
} \
}
#if TARGET_OS_WIN32
#define ThrowIfWinError(inError, inException, inMessage) \
{ \
HRESULT __Err = (inError); \
if(FAILED(__Err)) \
{ \
DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
Throw(inException); \
} \
}
#endif
#define SubclassResponsibility(inMethodName, inException) \
{ \
DebugMessage(inMethodName": Subclasses must implement this method"); \
Throw(inException); \
}
#endif // defined(__cplusplus)
#else
#pragma mark Release Macros
#define Assert(inCondition, inMessage) \
if(!(inCondition)) \
{ \
STOP; \
}
#define AssertNoError(inError, inMessage) \
{ \
SInt32 __Err = (inError); \
if(__Err != 0) \
{ \
STOP; \
} \
}
#define AssertNoKernelError(inError, inMessage) \
{ \
unsigned int __Err = (unsigned int)(inError); \
if(__Err != 0) \
{ \
STOP; \
} \
}
#define FailIf(inCondition, inHandler, inMessage) \
if(inCondition) \
{ \
STOP; \
goto inHandler; \
}
#define FailWithAction(inCondition, inAction, inHandler, inMessage) \
if(inCondition) \
{ \
STOP; \
{ inAction; } \
goto inHandler; \
}
#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \
if((inPointer) == NULL) \
{ \
STOP; \
{ inAction; } \
goto inHandler; \
}
#define FailIfKernelError(inKernelError, inException, inMessage) \
if((inKernelError) != 0) \
{ \
STOP; \
{ inAction; } \
goto inHandler; \
}
#define FailIfError(inError, inException, inMessage) \
if((inError) != 0) \
{ \
STOP; \
{ inAction; } \
goto inHandler; \
}
#if defined(__cplusplus)
#define Throw(inException) STOP; throw (inException)
#define ThrowIf(inCondition, inException, inMessage) \
if(inCondition) \
{ \
Throw(inException); \
}
#define ThrowIfNULL(inPointer, inException, inMessage) \
if((inPointer) == NULL) \
{ \
Throw(inException); \
}
#define ThrowIfKernelError(inKernelError, inException, inMessage) \
{ \
kern_return_t __Err = (inKernelError); \
if(__Err != 0) \
{ \
Throw(inException); \
} \
}
#define ThrowIfError(inError, inException, inMessage) \
{ \
SInt32 __Err = (inError); \
if(__Err != 0) \
{ \
Throw(inException); \
} \
}
#if TARGET_OS_WIN32
#define ThrowIfWinError(inError, inException, inMessage) \
{ \
HRESULT __Err = (inError); \
if(FAILED(__Err)) \
{ \
Throw(inException); \
} \
}
#endif
#define SubclassResponsibility(inMethodName, inException) \
{ \
Throw(inException); \
}
#endif // defined(__cplusplus)
#endif // DEBUG || CoreAudio_Debug
#endif

View File

@ -0,0 +1,64 @@
/* 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.
*/
/*=============================================================================
CAMath.h
=============================================================================*/
#ifndef __CAMath_h__
#define __CAMath_h__
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreAudio/CoreAudioTypes.h>
#else
#include <CoreAudioTypes.h>
#endif
inline bool fiszero(Float64 f) { return (f == 0.); }
inline bool fiszero(Float32 f) { return (f == 0.f); }
inline bool fnonzero(Float64 f) { return !fiszero(f); }
inline bool fnonzero(Float32 f) { return !fiszero(f); }
inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; }
inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; }
inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); }
inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); }
#endif // __CAMath_h__

View File

@ -0,0 +1,83 @@
/* 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.
*/
/*=============================================================================
CAReferenceCounted.h
=============================================================================*/
#ifndef __CAReferenceCounted_h__
#define __CAReferenceCounted_h__
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreServices/CoreServices.h>
#else
#include <CoreServices.h>
#endif
#if TARGET_OS_WIN32
#include "CAWindows.h"
#endif
// base class for reference-counted objects
class CAReferenceCounted {
public:
CAReferenceCounted() : mRefCount(1) {}
void retain() { IncrementAtomic(&mRefCount); }
void release()
{
// this returns the ORIGINAL value, not the new one.
SInt32 rc = DecrementAtomic(&mRefCount);
if (rc == 1) {
delete this;
}
}
protected:
virtual ~CAReferenceCounted() { }
private:
SInt32 mRefCount;
CAReferenceCounted(const CAReferenceCounted &a) : mRefCount(0) { }
CAReferenceCounted operator=(const CAReferenceCounted &a) { return *this; }
};
#endif // __CAReferenceCounted_h__

View File

@ -0,0 +1,520 @@
/* 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.
*/
/*=============================================================================
CAStreamBasicDescription.cpp
=============================================================================*/
#include "CAConditionalMacros.h"
#include "CAStreamBasicDescription.h"
#include "CAMath.h"
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreFoundation/CFByteOrder.h>
#else
#include <CFByteOrder.h>
#endif
#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 };
CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID,
UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
UInt32 inBitsPerChannel, UInt32 inFormatFlags)
{
mSampleRate = inSampleRate;
mFormatID = inFormatID;
mBytesPerPacket = inBytesPerPacket;
mFramesPerPacket = inFramesPerPacket;
mBytesPerFrame = inBytesPerFrame;
mChannelsPerFrame = inChannelsPerFrame;
mBitsPerChannel = inBitsPerChannel;
mFormatFlags = inFormatFlags;
}
void CAStreamBasicDescription::PrintFormat(FILE *f, const char *indent, const char *name) const
{
fprintf(f, "%s%s ", indent, name);
char formatID[5];
*(UInt32 *)formatID = CFSwapInt32HostToBig(mFormatID);
formatID[4] = '\0';
fprintf(f, "%2ld ch, %6.0f Hz, '%-4.4s' (0x%08lX) ",
NumberChannels(), mSampleRate, formatID,
mFormatFlags);
if (mFormatID == kAudioFormatLinearPCM) {
bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat);
int wordSize = SampleWordSize();
const char *endian = (wordSize > 1) ?
((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : "";
const char *sign = isInt ?
((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : "";
const char *floatInt = isInt ? "integer" : "float";
char packed[32];
if (wordSize > 0 && PackednessIsSignificant()) {
if (mFormatFlags & kLinearPCMFormatFlagIsPacked)
sprintf(packed, "packed in %d bytes", wordSize);
else
sprintf(packed, "unpacked in %d bytes", wordSize);
} else
packed[0] = '\0';
const char *align = (wordSize > 0 && AlignmentIsSignificant()) ?
((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : "";
const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : "";
const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : "";
fprintf(f, "%ld-bit%s%s %s%s%s%s%s\n",
mBitsPerChannel, endian, sign, floatInt,
commaSpace, packed, align, deinter);
} else if (mFormatID == 'alac') { // kAudioFormatAppleLossless
int sourceBits = 0;
switch (mFormatFlags)
{
case 1: // kAppleLosslessFormatFlag_16BitSourceData
sourceBits = 16;
break;
case 2: // kAppleLosslessFormatFlag_20BitSourceData
sourceBits = 20;
break;
case 3: // kAppleLosslessFormatFlag_24BitSourceData
sourceBits = 24;
break;
case 4: // kAppleLosslessFormatFlag_32BitSourceData
sourceBits = 32;
break;
}
if (sourceBits)
fprintf(f, "from %d-bit source, ", sourceBits);
else
fprintf(f, "from UNKNOWN source bit depth, ");
fprintf(f, "%ld frames/packet\n", mFramesPerPacket);
}
else
fprintf(f, "%ld bits/channel, %ld bytes/packet, %ld frames/packet, %ld bytes/frame\n",
mBitsPerChannel, mBytesPerPacket, mFramesPerPacket, mBytesPerFrame);
}
void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription)
{
// the only thing that changes is to make mixable linear PCM into the canonical linear PCM format
if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0))
{
// the canonical linear PCM format is 32 bit native endian floats
ioDescription.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
ioDescription.mBytesPerPacket = sizeof(Float32) * ioDescription.mChannelsPerFrame;
ioDescription.mFramesPerPacket = 1;
ioDescription.mBytesPerFrame = sizeof(Float32) * ioDescription.mChannelsPerFrame;
ioDescription.mBitsPerChannel = 8 * sizeof(Float32);
}
}
void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription)
{
ioDescription.mSampleRate = 0;
ioDescription.mFormatID = 0;
ioDescription.mBytesPerPacket = 0;
ioDescription.mFramesPerPacket = 0;
ioDescription.mBytesPerFrame = 0;
ioDescription.mChannelsPerFrame = 0;
ioDescription.mBitsPerChannel = 0;
ioDescription.mFormatFlags = 0;
}
void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription)
{
if(fiszero(ioDescription.mSampleRate))
{
ioDescription.mSampleRate = inTemplateDescription.mSampleRate;
}
if(ioDescription.mFormatID == 0)
{
ioDescription.mFormatID = inTemplateDescription.mFormatID;
}
if(ioDescription.mFormatFlags == 0)
{
ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags;
}
if(ioDescription.mBytesPerPacket == 0)
{
ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket;
}
if(ioDescription.mFramesPerPacket == 0)
{
ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket;
}
if(ioDescription.mBytesPerFrame == 0)
{
ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame;
}
if(ioDescription.mChannelsPerFrame == 0)
{
ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame;
}
if(ioDescription.mBitsPerChannel == 0)
{
ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel;
}
}
void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate)
{
switch(inDescription.mFormatID)
{
case kAudioFormatLinearPCM:
{
const char* theEndianString = NULL;
if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0)
{
#if TARGET_RT_LITTLE_ENDIAN
theEndianString = "Big Endian";
#endif
}
else
{
#if TARGET_RT_BIG_ENDIAN
theEndianString = "Little Endian";
#endif
}
const char* theKindString = NULL;
if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0)
{
theKindString = (inAbbreviate ? "Float" : "Floating Point");
}
else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0)
{
theKindString = (inAbbreviate ? "SInt" : "Signed Integer");
}
else
{
theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer");
}
const char* thePackingString = NULL;
if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0)
{
if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0)
{
thePackingString = "High";
}
else
{
thePackingString = "Low";
}
}
const char* theMixabilityString = NULL;
if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0)
{
theMixabilityString = "Mixable";
}
else
{
theMixabilityString = "Unmixable";
}
if(inAbbreviate)
{
if(theEndianString != NULL)
{
if(thePackingString != NULL)
{
sprintf(outName, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
}
else
{
sprintf(outName, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel);
}
}
else
{
if(thePackingString != NULL)
{
sprintf(outName, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8));
}
else
{
sprintf(outName, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel);
}
}
}
else
{
if(theEndianString != NULL)
{
if(thePackingString != NULL)
{
sprintf(outName, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
}
else
{
sprintf(outName, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString);
}
}
else
{
if(thePackingString != NULL)
{
sprintf(outName, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
}
else
{
sprintf(outName, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString);
}
}
}
}
break;
case kAudioFormatAC3:
strcpy(outName, "AC-3");
break;
case kAudioFormat60958AC3:
strcpy(outName, "AC-3 for SPDIF");
break;
default:
{
char* the4CCString = (char*)&inDescription.mFormatID;
outName[0] = the4CCString[0];
outName[1] = the4CCString[1];
outName[2] = the4CCString[2];
outName[3] = the4CCString[3];
outName[4] = 0;
}
break;
};
}
#if CoreAudio_Debug
#include "CALogMacros.h"
void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc)
{
PrintFloat (" Sample Rate: ", inDesc.mSampleRate);
Print4CharCode (" Format ID: ", inDesc.mFormatID);
PrintHex (" Format Flags: ", inDesc.mFormatFlags);
PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket);
PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket);
PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame);
PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame);
PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel);
}
#endif
bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
{
bool theAnswer = false;
bool isDone = false;
// note that if either side is 0, that field is skipped
// format ID is the first order sort
if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0)))
{
if(x.mFormatID != y.mFormatID)
{
// formats are sorted numerically except that linear
// PCM is always first
if(x.mFormatID == kAudioFormatLinearPCM)
{
theAnswer = true;
}
else if(y.mFormatID == kAudioFormatLinearPCM)
{
theAnswer = false;
}
else
{
theAnswer = x.mFormatID < y.mFormatID;
}
isDone = true;
}
}
// mixable is always better than non-mixable for linear PCM and should be the second order sort item
if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
{
if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0))
{
theAnswer = true;
isDone = true;
}
else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0))
{
theAnswer = false;
isDone = true;
}
}
// floating point vs integer for linear PCM only
if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
{
if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat))
{
// floating point is better than integer
theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat;
isDone = true;
}
}
// bit depth
if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0)))
{
if(x.mBitsPerChannel != y.mBitsPerChannel)
{
// deeper bit depths are higher quality
theAnswer = x.mBitsPerChannel < y.mBitsPerChannel;
isDone = true;
}
}
// sample rate
if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate))
{
if(fnotequal(x.mSampleRate, y.mSampleRate))
{
// higher sample rates are higher quality
theAnswer = x.mSampleRate < y.mSampleRate;
isDone = true;
}
}
// number of channels
if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0)))
{
if(x.mChannelsPerFrame != y.mChannelsPerFrame)
{
// more channels is higher quality
theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame;
isDone = true;
}
}
return theAnswer;
}
static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
{
UInt32 xFlags = x.mFormatFlags;
UInt32 yFlags = y.mFormatFlags;
// match wildcards
if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0)
return true;
if (x.mFormatID == kAudioFormatLinearPCM)
{
// knock off the all clear flag
xFlags = xFlags & ~kAudioFormatFlagsAreAllClear;
yFlags = yFlags & ~kAudioFormatFlagsAreAllClear;
// if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit.
if (xFlags & yFlags & kAudioFormatFlagIsPacked) {
xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh;
yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh;
}
// if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit.
if (xFlags & yFlags & kAudioFormatFlagIsFloat) {
xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger;
yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger;
}
// if the bit depth is 8 bits or less and the format is packed, we don't care about endianness
if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
{
xFlags = xFlags & ~kAudioFormatFlagIsBigEndian;
}
if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
{
yFlags = yFlags & ~kAudioFormatFlagIsBigEndian;
}
// if the number of channels is 0 or 1, we don't care about non-interleavedness
if (x.mChannelsPerFrame <= 1 && y.mChannelsPerFrame <= 1) {
xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
}
}
return xFlags == yFlags;
}
bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
{
// the semantics for equality are:
// 1) Values must match exactly
// 2) wildcard's are ignored in the comparison
#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name))
return
// check the sample rate
(fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate))
// check the format ids
&& MATCH(mFormatID)
// check the format flags
&& MatchFormatFlags(x, y)
// check the bytes per packet
&& MATCH(mBytesPerPacket)
// check the frames per packet
&& MATCH(mFramesPerPacket)
// check the bytes per frame
&& MATCH(mBytesPerFrame)
// check the channels per frame
&& MATCH(mChannelsPerFrame)
// check the channels per frame
&& MATCH(mBitsPerChannel) ;
}
bool SanityCheck(const AudioStreamBasicDescription& x)
{
return (x.mSampleRate >= 0.);
}

View File

@ -0,0 +1,224 @@
/* 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.
*/
/*=============================================================================
CAStreamBasicDescription.h
=============================================================================*/
#ifndef __CAStreamBasicDescription_h__
#define __CAStreamBasicDescription_h__
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreAudio/CoreAudioTypes.h>
#include <CoreFoundation/CoreFoundation.h>
#else
#include "CoreAudioTypes.h"
#include "CoreFoundation.h"
#endif
#include "CADebugMacros.h"
#include <string.h> // for memset, memcpy
#include <stdio.h> // for FILE *
#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
// define the IsMixable format flag for all versions of the system
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable };
#else
enum { kIsNonMixableFlag = (1L << 6) };
#endif
//=============================================================================
// CAStreamBasicDescription
//
// This is a wrapper class for the AudioStreamBasicDescription struct.
// It adds a number of convenience routines, but otherwise adds nothing
// to the footprint of the original struct.
//=============================================================================
class CAStreamBasicDescription :
public AudioStreamBasicDescription
{
// Constants
public:
static const AudioStreamBasicDescription sEmpty;
// Construction/Destruction
public:
CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); }
CAStreamBasicDescription(const AudioStreamBasicDescription &desc)
{
SetFrom(desc);
}
CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID,
UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
UInt32 inBitsPerChannel, UInt32 inFormatFlags);
// Assignment
CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; }
void SetFrom(const AudioStreamBasicDescription &desc)
{
memcpy(this, &desc, sizeof(AudioStreamBasicDescription));
}
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
//
// interrogation
bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; }
bool PackednessIsSignificant() const
{
Assert(IsPCM(), "PackednessIsSignificant only applies for PCM");
return (SampleWordSize() << 3) != mBitsPerChannel;
}
bool AlignmentIsSignificant() const
{
return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0;
}
bool IsInterleaved() const
{
return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved);
}
// for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these:
UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; }
UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; }
UInt32 NumberChannels() const { return mChannelsPerFrame; }
UInt32 SampleWordSize() const { return (mBytesPerFrame > 0) ? mBytesPerFrame / NumberInterleavedChannels() : 0;}
UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; }
UInt32 BytesToFrames(UInt32 nbytes) const {
Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames");
return nbytes / mBytesPerFrame;
}
bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const
{
return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved();
}
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
//
// manipulation
void SetCanonical(UInt32 nChannels, bool interleaved)
// note: leaves sample rate untouched
{
mFormatID = kAudioFormatLinearPCM;
mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
mBitsPerChannel = 32;
mChannelsPerFrame = nChannels;
mFramesPerPacket = 1;
if (interleaved)
mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(Float32);
else {
mBytesPerPacket = mBytesPerFrame = sizeof(Float32);
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
}
}
void ChangeNumberChannels(UInt32 nChannels, bool interleaved)
// alter an existing format
{
Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats");
UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING
if (wordSize == 0)
wordSize = (mBitsPerChannel + 7) / 8;
mChannelsPerFrame = nChannels;
mFramesPerPacket = 1;
if (interleaved) {
mBytesPerPacket = mBytesPerFrame = nChannels * wordSize;
mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved;
} else {
mBytesPerPacket = mBytesPerFrame = wordSize;
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
}
}
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
//
// other
void Print() const
{
Print (stdout);
}
void Print(FILE* file) const
{
PrintFormat (file, "", "AudioStreamBasicDescription:");
}
void PrintFormat(FILE *f, const char *indent, const char *name) const;
OSStatus Save(CFPropertyListRef *outData) const;
OSStatus Restore(CFPropertyListRef &inData);
// Operations
static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); }
static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription);
static void ResetFormat(AudioStreamBasicDescription& ioDescription);
static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription);
static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate);
#if CoreAudio_Debug
static void PrintToLog(const AudioStreamBasicDescription& inDesc);
#endif
};
bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600))
inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); }
inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); }
inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); }
inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); }
#endif
bool SanityCheck(const AudioStreamBasicDescription& x);
#endif // __CAStreamBasicDescription_h__

View File

@ -0,0 +1,45 @@
/* 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.
*/
/*=============================================================================
CAXException.cpp
=============================================================================*/
#include "CAXException.h"
CAXException::WarningHandler CAXException::sWarningHandler = NULL;

View File

@ -0,0 +1,158 @@
/* 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.
*/
/*=============================================================================
CAXException.h
=============================================================================*/
#ifndef __CAXException_h__
#define __CAXException_h__
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
#include <CoreServices/CoreServices.h>
#else
#include <ConditionalMacros.h>
#include <CoreServices.h>
#endif
#include "CADebugMacros.h"
#include <ctype.h>
#include <stdio.h>
#include <string.h>
// An extended exception class that includes the name of the failed operation
class CAXException {
public:
CAXException(const char *operation, OSStatus err) :
mError(err)
{
if (operation == NULL)
mOperation[0] = '\0';
else if (strlen(operation) >= sizeof(mOperation)) {
memcpy(mOperation, operation, sizeof(mOperation) - 1);
mOperation[sizeof(mOperation) - 1] = '\0';
} else
strcpy(mOperation, operation);
}
char *FormatError(char *str) const
{
return FormatError(str, mError);
}
char mOperation[256];
const OSStatus mError;
// -------------------------------------------------
typedef void (*WarningHandler)(const char *msg, OSStatus err);
/*static void Throw(const char *operation, OSStatus err)
{
throw CAXException(operation, err);
}*/
static char *FormatError(char *str, OSStatus error)
{
// see if it appears to be a 4-char-code
*(UInt32 *)(str + 1) = EndianU32_NtoB(error);
if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
str[0] = str[5] = '\'';
str[6] = '\0';
} else
// no, format it as an integer
sprintf(str, "%ld", error);
return str;
}
static void Warning(const char *s, OSStatus error)
{
if (sWarningHandler)
(*sWarningHandler)(s, error);
}
static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; }
private:
static WarningHandler sWarningHandler;
};
#if DEBUG || CoreAudio_Debug
#define XThrowIfError(error, operation) \
do { \
OSStatus __err = error; \
if (__err) { \
char __buf[12]; \
DebugMessageN2("error %s: %4s\n", CAXException::FormatError(__buf, __err), operation);\
STOP; \
throw CAXException(operation, __err); \
} \
} while (0)
#define XThrowIf(condition, error, operation) \
do { \
if (condition) { \
OSStatus __err = error; \
char __buf[12]; \
DebugMessageN2("error %s: %4s\n", CAXException::FormatError(__buf, __err), operation);\
STOP; \
throw CAXException(operation, __err); \
} \
} while (0)
#else
#define XThrowIfError(error, operation) \
do { \
OSStatus __err = error; \
if (__err) { \
throw CAXException(operation, __err); \
} \
} while (0)
#define XThrowIf(condition, error, operation) \
do { \
if (condition) { \
OSStatus __err = error; \
throw CAXException(operation, __err); \
} \
} while (0)
#endif
#define XThrow(error, operation) XThrowIf(true, error, operation)
#define XThrowIfErr(error) XThrowIfError(error, #error)
#endif // __CAXException_h__

View File

@ -0,0 +1,22 @@
# -*- python -*-
import os
import os.path
import glob
appleutility_files = glob.glob('*.cpp')
Import('env install_prefix')
appleutility = env.Copy()
appleutility.Append(LINKFLAGS='-framework AudioToolbox')
appleutility.Append(LINKFLAGS='-framework AudioUnit')
appleutility.Append(LINKFLAGS='-framework CoreFoundation')
appleutility.Append(LINKFLAGS='-framework CoreServices')
libappleutility = appleutility.SharedLibrary('appleutility', appleutility_files)
if appleutility['COREAUDIO']:
Default(libappleutility)
env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour3'), libappleutility))
env.Alias('tarball', env.Distribute (env['DISTTREE'], ['SConscript'] + appleutility_files + glob.glob('*.h') ))

8
libs/ardour/.cvsignore Normal file
View File

@ -0,0 +1,8 @@
libardour.la
libardour.pc
version.cc
*.lo
*.os
*.mo
*.pot
*.dylib

118
libs/ardour/ChangeLog Normal file
View File

@ -0,0 +1,118 @@
2002-11-24 gettextize <bug-gnu-gettext@gnu.org>
* configure.ac (AC_OUTPUT): Add intl/Makefile,
2002-11-24 gettextize <bug-gnu-gettext@gnu.org>
* Makefile.am (ACLOCAL_AMFLAGS): New variable.
2001-10-26 Paul Davis <pbd>
* playlist.cc (recover_backup): restored the backup recovery code
for playlists.
* diskstream.cc (do_refill): added state_lock to diskstream, just
to be safe.
* session.cc (butler_thread_work): changed Session ISA thread to
HASA thread.
2001-10-23 Paul Davis <pbd>
merged in marcus' patch for edit/mix group save/restore, and
rationalized both it and the existing code for Route::set_state()
2001-10-20 Paul Davis <pbd>
* session.cc (get_state): in get_state, use the public order for routes.
2001-10-18 Paul Davis <pbd>
* playlist.cc (read): stop a muted region from causing a playlist
read error.
2001-10-17 Paul Davis <pbd>
* region.cc (read_at): remove staccato noise caused by not
shifting target buffer when !opaque.
2001-10-15 Paul Davis <pbd>
* region.cc (set_fade_out_active): made region fade in/out optional.
* configure.in: patches from Ben related to libxml++
2001-10-12 Paul Davis <pbd>
* session.cc (XMLRegionFactory): move most XML-based Region
constructor into region.
2001-10-10 Paul Davis <pbd>
* session.cc (load_sources): add whole-file regions when loading
sources.
2001-10-09 Paul Davis <pbd>
* ardour/session.h: fix an ugly bug with a non-reference return type.
2001-10-04 Paul Davis <pbd>
* playlist.cc (split_region): ensure that left region after split
is in the right place.
* auditioner.cc (play_audition): stop existing audition before
starting a new one.
2001-10-03 Paul Davis <pbd>
* session.cc (process): stop regular process() call from operating
on hidden diskstreams and routes. the butler thread still works on
all diskstreams, every time, which might be a mistake.
2001-10-02 Paul Davis <pbd>
* session.cc (set_auto_play_range): added provisional support
for play ranges using session events. added code to use
auditioner.
* auditioner.cc: new file/object to support auditioning.
* route.cc: remove seek() function (didn't exist).
* session.cc (process): use list<DiskStream *> instead of GList
for diskstreams. add auditioner object.
2001-09-30 Paul Davis <pbd>
* playlist.cc (split_region): fix problem with region splitting
not defining two *smaller* regions of the original.
* region.cc (set_position): remove RegionTemplate object.
* playlist.cc (struct RegionSorter ): fix sorting to use position,
not start - whatever was i thinking ?
2001-09-28 Paul Davis <pbd>
* source.cc: emit source creation signal.
* session.cc (first_stage_init): catch all source creation events.
* sndfilesource.cc (init): fix up an off-by-one substr-length
error when creating a sndfilesource.
2001-09-27 Paul Davis <pbd>
* route.cc (operator): correct loop increment bug that caused a
hang when an Insert is added to a Route as a Redirect.
2001-09-25 Paul Davis <pbd>
* session.cc: make new file sources be partially named for their
initial host diskstream.
peak file construction now carried out en-masse at the
end of capture run.

395
libs/ardour/SConscript Normal file
View File

@ -0,0 +1,395 @@
# -*- python -*-
import os
import os.path
import glob
Import('env final_prefix install_prefix final_config_prefix libraries i18n')
ardour = env.Copy()
#
# this defines the version number of libardour
#
domain = 'libardour3'
ardour.Append(DOMAIN = domain, MAJOR = 2, MINOR = 0, MICRO = 0)
ardour.Append(CXXFLAGS = "-DPACKAGE=\\\"" + domain + "\\\"")
ardour.Append(CXXFLAGS=["-DLIBSIGC_DISABLE_DEPRECATED", "-DGLIBMM_EXCEPTIONS_ENABLED"])
ardour.Append(PACKAGE = domain)
ardour.Append(POTFILE = domain + '.pot')
if ardour['IS_OSX']:
ardour.Append (LINKFLAGS="-Xlinker -headerpad -Xlinker 2048")
#
# explicitly reference the control protocol LGPL library for includes
#
ardour.Append(CPPPATH = '#libs/surfaces/control_protocol')
ardour_files=Split("""
amp.cc
analyser.cc
audioanalyser.cc
audio_buffer.cc
audio_diskstream.cc
audioengine.cc
audiofilesource.cc
audio_library.cc
audio_playlist.cc
audio_port.cc
audioregion.cc
audiosource.cc
audio_track.cc
auditioner.cc
auto_bundle.cc
automatable.cc
automation.cc
automation_control.cc
automation_event.cc
base_audio_port.cc
base_midi_port.cc
buffer.cc
buffer_set.cc
chan_count.cc
configuration.cc
control_protocol_manager.cc
control_protocol_search_path.cc
crossfade.cc
curve.cc
cycle_timer.cc
default_click.cc
directory_names.cc
diskstream.cc
enums.cc
filename_extensions.cc
filesystem_paths.cc
filter.cc
find_session.cc
gain.cc
gdither.cc
globals.cc
import.cc
io.cc
io_processor.cc
jack_audio_port.cc
jack_midi_port.cc
jack_port.cc
jack_slave.cc
ladspa_plugin.cc
location.cc
meter.cc
midi_buffer.cc
midi_diskstream.cc
midi_model.cc
midi_playlist.cc
midi_port.cc
midi_region.cc
midi_source.cc
midi_stretch.cc
midi_track.cc
mix.cc
mtc_slave.cc
named_selection.cc
note.cc
panner.cc
parameter.cc
pcm_utils.cc
playlist.cc
playlist_factory.cc
plugin.cc
plugin_insert.cc
plugin_manager.cc
port.cc
port_insert.cc
port_set.cc
processor.cc
quantize.cc
recent_sessions.cc
region.cc
region_factory.cc
resampled_source.cc
reverse.cc
route.cc
route_group.cc
send.cc
session_butler.cc
session.cc
session_click.cc
session_command.cc
session_directory.cc
session_events.cc
session_export.cc
session_midi.cc
session_process.cc
session_state.cc
session_state_utils.cc
session_time.cc
session_transport.cc
session_utils.cc
silentfilesource.cc
smf_reader.cc
smf_source.cc
sndfile_helpers.cc
sndfilesource.cc
sndfileimportable.cc
source.cc
source_factory.cc
tape_file_matcher.cc
template_utils.cc
tempo.cc
track.cc
transient_detector.cc
user_bundle.cc
utils.cc
version.cc
""")
arch_specific_objects = [ ]
osc_files = [ 'osc.cc' ]
vst_files = [ 'vst_plugin.cc', 'session_vst.cc' ]
lv2_files = [ 'lv2_plugin.cc' ]
audiounit_files = [ 'audio_unit.cc' ]
coreaudio_files = [ 'coreaudiosource.cc', 'caimportable.cc' ]
extra_sources = [ ]
timefx_sources = [ ]
if ardour['VST']:
extra_sources += vst_files
ardour.Append(CCFLAGS="-DVST_SUPPORT", CPPPATH="#libs/fst")
if ardour['LV2']:
extra_sources += lv2_files
ardour.Append(CCFLAGS="-DHAVE_SLV2")
if ardour['LIBLO']:
extra_sources += osc_files
ardour.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
ardour.Append(CXXFLAGS="-DDATA_DIR=\\\"" + os.path.join (final_prefix, 'share') + "\\\"")
ardour.Append(CXXFLAGS="-DMODULE_DIR=\\\"" + os.path.join (final_prefix, env['LIBDIR']) + "\\\"")
ardour.Append(CXXFLAGS="-DVAMP_DIR=\\\"" + os.path.join (final_prefix, env['LIBDIR'], 'ardour3', 'vamp') + "\\\"")
ardour.Append(CXXFLAGS="-DCONFIG_DIR=\\\"" + final_config_prefix + "\\\"")
ardour.Append(CXXFLAGS="-DLOCALEDIR=\\\"" + os.path.join (final_prefix, 'share', 'locale') + "\\\"")
ardour.Merge ([ libraries['jack'] ])
#
# See if JACK supports jack_client_open()
#
jack_test_source_file = """
#include <jack/jack.h>
int main(int argc, char **argv)
{
jack_client_open ("foo", 0, 0);
return 0;
}
"""
def CheckJackClientOpen(context):
context.Message('Checking for jack_client_open()...')
result = context.TryLink(jack_test_source_file, '.c')
context.Result(result)
return result
#
# See if JACK supports jack_recompute_total_latencies()
#
jack_test_source_file = """
#include <jack/jack.h>
int main(int argc, char **argv)
{
jack_recompute_total_latencies ((jack_client_t*) 0);
return 0;
}
"""
def CheckJackRecomputeLatencies(context):
context.Message('Checking for jack_recompute_total_latencies()...')
result = context.TryLink(jack_test_source_file, '.c')
context.Result(result)
return result
jack_video_frame_offset_test = """
#include <jack/transport.h>
int main(int argc, char** argv)
{
jack_position_t pos;
pos.valid & JackVideoFrameOffset;
return 0;
}
"""
def CheckJackVideoFrameOffset(context):
context.Message('Checking for JackVideoFrameOffset in jack_position_bits_t enum...')
result = context.TryLink(jack_video_frame_offset_test, '.c')
context.Result(result)
return result
#
# See if JACK supports jack_recompute_total_latency() (single port version)
#
jack_port_latency_test = """
#include <jack/jack.h>
int main(int argc, char **argv)
{
jack_recompute_total_latency ((jack_client_t*) 0, (jack_port_t*) 0);
return 0;
}
"""
def CheckJackRecomputeLatency(context):
context.Message('Checking for jack_recompute_total_latency()...')
result = context.TryLink(jack_port_latency_test, '.c')
context.Result(result)
return result
conf = Configure(ardour, custom_tests = {
'CheckJackClientOpen' : CheckJackClientOpen,
'CheckJackRecomputeLatencies' : CheckJackRecomputeLatencies,
'CheckJackRecomputeLatency' : CheckJackRecomputeLatency,
'CheckJackVideoFrameOffset' : CheckJackVideoFrameOffset
})
if conf.CheckJackClientOpen():
ardour.Append(CXXFLAGS="-DHAVE_JACK_CLIENT_OPEN")
if conf.CheckJackRecomputeLatencies():
ardour.Append(CXXFLAGS="-DHAVE_JACK_RECOMPUTE_LATENCIES")
if conf.CheckJackRecomputeLatency():
ardour.Append(CXXFLAGS="-DHAVE_JACK_RECOMPUTE_LATENCY")
if conf.CheckJackVideoFrameOffset():
ardour.Append(CXXFLAGS="-DHAVE_JACK_VIDEO_SUPPORT")
#
# Optional header files
#
if conf.CheckCHeader('wordexp.h'):
ardour.Append(CXXFLAGS="-DHAVE_WORDEXP")
if conf.CheckCHeader('sys/vfs.h'):
ardour.Append(CXXFLAGS="-DHAVE_SYS_VFS_H")
if conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
ardour.Append(LINKFLAGS="-framework CoreMIDI")
if conf.CheckCHeader('/System/Library/Frameworks/AudioToolbox.framework/Headers/ExtendedAudioFile.h'):
ardour.Append(LINKFLAGS="-framework AudioToolbox")
if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Headers/CoreAudio.h'):
ardour.Append(CXXFLAGS="-DHAVE_WEAK_COREAUDIO")
if conf.CheckCHeader('/System/Library/Frameworks/AudioUnit.framework/Headers/AudioUnit.h') and ardour['AUDIOUNITS']:
ardour.Append(CXXFLAGS="-DHAVE_AUDIOUNITS")
ardour.Append(LINKFLAGS="-framework AudioUnit")
extra_sources += audiounit_files
if ardour['COREAUDIO']:
ardour.Append(CXXFLAGS="-DHAVE_COREAUDIO")
extra_sources += coreaudio_files
if env['CONFIG_ARCH'] == 'apple':
# this next line avoids issues with circular dependencies between libardour and libardour_cp.
# it is based on the (entirely reasonable) assumption that a system with CoreAudio is OS X
#
ardour.Append(LINKFLAGS='-undefined suppress -flat_namespace')
ardour = conf.Finish ()
ardour.Merge ([
libraries['core'],
libraries['fftw3'],
libraries['fftw3f'],
libraries['glib2'],
libraries['glibmm2'],
libraries['lrdf'],
libraries['midi++2'],
libraries['pbd'],
libraries['raptor'],
libraries['samplerate'],
libraries['sigc2'],
libraries['sndfile-ardour'],
libraries['vamp'],
libraries['vamphost'],
libraries['xml']
])
if ardour['RUBBERBAND']:
ardour.Merge ([ libraries['rubberband']])
timefx_sources += [ 'rb_effect.cc' ]
else:
ardour.Merge ([ libraries['soundtouch'] ])
timefx_sources += [ 'st_stretch.cc', 'st_pitch.cc' ]
if ardour['LV2']:
ardour.Merge ([ libraries['slv2'] ])
if ardour['LIBLO']:
ardour.Merge ([ libraries['lo'] ])
if ardour['COREAUDIO'] or ardour['AUDIOUNITS']:
ardour.Merge ([ libraries['appleutility'] ])
def SharedAsmObjectEmitter(target, source, env):
for tgt in target:
tgt.attributes.shared = 1
return (target, source)
env['BUILDERS']['SharedAsmObject'] = Builder (action = '$CXX -c -fPIC $SOURCE -o $TARGET',
emitter = SharedAsmObjectEmitter,
suffix = '$SHOBJSUFFIX',
src_suffix = '.s',
single_source = 1)
#
# handle objects that should always be compiled with -msse in their own
# special environment, which is exactly like "ardour" but unconditionally
# includes -msse
#
always_sse_objects = []
sse_env = ardour.Copy()
sse_env.Append (CXXFLAGS="-msse")
if env['FPU_OPTIMIZATION']:
if env['DIST_TARGET'] == "i386":
arch_specific_objects = env.SharedAsmObject('sse_functions.os', 'sse_functions.s')
always_sse_objects += [ sse_env.SharedObject (source = 'sse_functions_xmm.cc') ]
if env['DIST_TARGET'] == "i686":
arch_specific_objects = env.SharedAsmObject('sse_functions.os', 'sse_functions.s')
always_sse_objects += [ sse_env.SharedObject (source = 'sse_functions_xmm.cc') ]
if env['DIST_TARGET'] == "x86_64":
arch_specific_objects = env.SharedAsmObject('sse_functions_64bit.os', 'sse_functions_64bit.s')
always_sse_objects += [ sse_env.SharedObject (source = 'sse_functions_xmm.cc') ]
libardour = ardour.SharedLibrary('ardour', ardour_files + always_sse_objects + timefx_sources + extra_sources + arch_specific_objects)
Default(libardour)
if env['NLS']:
i18n (ardour, ardour_files + vst_files + coreaudio_files + timefx_sources + audiounit_files, env)
env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour3'), libardour))
env.Alias('version', ardour.VersionBuild(['version.cc', 'ardour/version.h'], []))
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript', 'i18n.h', 'gettext.h' ] +
[ 'sse_functions_xmm.cc', 'sse_functions.s', 'sse_functions_64bit.s' ] +
[ 'rb_effect.cc', 'st_stretch.cc', 'st_pitch.cc' ] +
ardour_files +
osc_files +
vst_files +
coreaudio_files +
audiounit_files +
lv2_files +
glob.glob('po/*.po') + glob.glob('ardour/*.h')))

102
libs/ardour/amp.cc Normal file
View File

@ -0,0 +1,102 @@
/*
Copyright (C) 2006 Paul Davis
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <cstring>
#include <cmath>
#include <algorithm>
#include <ardour/amp.h>
#include <ardour/buffer_set.h>
#include <ardour/audio_buffer.h>
namespace ARDOUR {
/** Apply a declicked gain to the audio buffers of @a bufs */
void
Amp::run_in_place (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity)
{
if (nframes == 0)
return;
if (bufs.count().n_audio() == 0)
return;
// assert(bufs.buffer_capacity(DataType::AUDIO) >= nframes);
// if we don't need to declick, defer to apply_simple_gain
if (initial == target) {
if (target == 0.0) {
for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
memset (i->data(), 0, sizeof (Sample) * nframes);
}
} else if (target != 1.0) {
for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
apply_gain_to_buffer (i->data(), nframes, target);
}
}
return;
}
const nframes_t declick = std::min ((nframes_t)128, nframes);
gain_t delta;
double fractional_shift = -1.0/declick;
double fractional_pos;
gain_t polscale = invert_polarity ? -1.0f : 1.0f;
if (target < initial) {
/* fade out: remove more and more of delta from initial */
delta = -(initial - target);
} else {
/* fade in: add more and more of delta from initial */
delta = target - initial;
}
for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
Sample* const buffer = i->data();
fractional_pos = 1.0;
for (nframes_t nx = 0; nx < declick; ++nx) {
buffer[nx] *= polscale * (initial + (delta * (0.5 + 0.5 * cos (M_PI * fractional_pos))));
fractional_pos += fractional_shift;
}
/* now ensure the rest of the buffer has the target value applied, if necessary. */
if (declick != nframes) {
if (invert_polarity) {
target = -target;
}
if (target == 0.0) {
memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick));
} else if (target != 1.0) {
apply_gain_to_buffer (&buffer[declick], nframes - declick, target);
}
}
}
}
void
Amp::apply_simple_gain (BufferSet& bufs, nframes_t nframes, gain_t target)
{
}
} // namespace ARDOUR

119
libs/ardour/analyser.cc Normal file
View File

@ -0,0 +1,119 @@
/*
Copyright (C) 2008 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <ardour/analyser.h>
#include <ardour/audiofilesource.h>
#include <ardour/transient_detector.h>
#include <pbd/pthread_utils.h>
#include <pbd/convert.h>
using namespace std;
using namespace sigc;
using namespace ARDOUR;
using namespace PBD;
Analyser* Analyser::the_analyser = 0;
Glib::StaticMutex Analyser::analysis_queue_lock = GLIBMM_STATIC_MUTEX_INIT;
Glib::Cond* Analyser::SourcesToAnalyse = 0;
list<boost::weak_ptr<Source> > Analyser::analysis_queue;
Analyser::Analyser ()
{
}
Analyser::~Analyser ()
{
}
static void
analyser_work ()
{
Analyser::work ();
}
void
Analyser::init ()
{
SourcesToAnalyse = new Glib::Cond();
Glib::Thread::create (sigc::ptr_fun (analyser_work), false);
}
void
Analyser::queue_source_for_analysis (boost::shared_ptr<Source> src, bool force)
{
if (!src->can_be_analysed()) {
return;
}
if (!force && src->has_been_analysed()) {
return;
}
Glib::Mutex::Lock lm (analysis_queue_lock);
analysis_queue.push_back (boost::weak_ptr<Source>(src));
SourcesToAnalyse->broadcast ();
}
void
Analyser::work ()
{
PBD::ThreadCreated (pthread_self(), string ("analyser-") + to_string (pthread_self(), std::dec));
while (true) {
analysis_queue_lock.lock ();
wait:
if (analysis_queue.empty()) {
SourcesToAnalyse->wait (analysis_queue_lock);
}
if (analysis_queue.empty()) {
goto wait;
}
boost::shared_ptr<Source> src (analysis_queue.front().lock());
analysis_queue.pop_front();
analysis_queue_lock.unlock ();
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src);
if (afs && afs->length()) {
analyse_audio_file_source (afs);
}
}
}
void
Analyser::analyse_audio_file_source (boost::shared_ptr<AudioFileSource> src)
{
AnalysisFeatureList results;
TransientDetector td (src->sample_rate());
if (td.run (src->get_transients_path(), src.get(), 0, results) == 0) {
src->set_been_analysed (true);
} else {
src->set_been_analysed (false);
}
}

View File

@ -0,0 +1 @@
version.h

44
libs/ardour/ardour/amp.h Normal file
View File

@ -0,0 +1,44 @@
/*
Copyright (C) 2006 Paul Davis
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_amp_h__
#define __ardour_amp_h__
#include <ardour/types.h>
namespace ARDOUR {
class BufferSet;
/** Applies a declick operation to all audio inputs, passing the same number of
* audio outputs, and passing through any other types unchanged.
*
* FIXME: make this a Processor.
*/
class Amp {
public:
static void run_in_place (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity);
static void apply_simple_gain(BufferSet& bufs, nframes_t nframes, gain_t target);
};
} // namespace ARDOUR
#endif // __ardour_amp_h__

View File

@ -0,0 +1,35 @@
#ifndef __ardour_analyser_h__
#define __ardour_analyser_h__
#include <glibmm/thread.h>
#include <boost/shared_ptr.hpp>
namespace ARDOUR {
class AudioFileSource;
class Source;
class TransientDetector;
class Analyser {
public:
Analyser();
~Analyser ();
static void init ();
static void queue_source_for_analysis (boost::shared_ptr<Source>, bool force);
static void work ();
private:
static Analyser* the_analyser;
static Glib::StaticMutex analysis_queue_lock;
static Glib::Cond* SourcesToAnalyse;
static std::list<boost::weak_ptr<Source> > analysis_queue;
static void analyse_audio_file_source (boost::shared_ptr<AudioFileSource>);
};
}
#endif /* __ardour_analyser_h__ */

View File

@ -0,0 +1,87 @@
/*
Copyright (C) 1999 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_ardour_h__
#define __ardour_ardour_h__
#include <map>
#include <string>
#include <limits.h>
#include <signal.h>
#include <pbd/error.h>
#include <pbd/failed_constructor.h>
#include <ardour/configuration.h>
#include <ardour/types.h>
namespace MIDI {
class MachineControl;
class Port;
}
namespace ARDOUR {
class AudioEngine;
class OSC;
extern OSC* osc;
static const nframes_t max_frames = JACK_MAX_FRAMES;
extern sigc::signal<void,std::string> BootMessage;
int init (bool with_vst, bool try_optimization);
int cleanup ();
std::string get_ardour_revision ();
void find_bindings_files (std::map<std::string,std::string>&);
const layer_t max_layer = UCHAR_MAX;
microseconds_t get_microseconds ();
Change new_change ();
extern Change StartChanged;
extern Change LengthChanged;
extern Change PositionChanged;
extern Change NameChanged;
extern Change BoundsChanged;
struct LocaleGuard {
LocaleGuard (const char*);
~LocaleGuard ();
const char* old;
};
static const double SHUTTLE_FRACT_SPEED1=0.48412291827; /* derived from A1,A2 */
void setup_fpu ();
}
/* how do we make these be within the Ardour namespace? */
extern MIDI::Port* default_mmc_port;
extern MIDI::Port* default_mtc_port;
extern MIDI::Port* default_midi_port;
#endif /* __ardour_ardour_h__ */

View File

@ -0,0 +1,121 @@
/*
Copyright (C) 2006 Paul Davis
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_audio_buffer_h__
#define __ardour_audio_buffer_h__
#include <cstring>
#include <ardour/buffer.h>
namespace ARDOUR {
class AudioBuffer : public Buffer
{
public:
AudioBuffer(size_t capacity);
~AudioBuffer();
void silence(nframes_t len, nframes_t offset = 0) {
if (!_silent) {
assert(_capacity > 0);
assert(offset + len <= _capacity);
memset(_data + offset, 0, sizeof (Sample) * len);
if (offset == 0 && len == _capacity) {
_silent = true;
}
}
}
/** Read @a len frames FROM THE START OF @a src into self at @a offset */
void read_from(const Buffer& src, nframes_t len, nframes_t offset) {
assert(&src != this);
assert(_capacity > 0);
assert(src.type() == DataType::AUDIO);
assert(offset + len <= _capacity);
memcpy(_data + offset, ((AudioBuffer&)src).data(), sizeof(Sample) * len);
_silent = src.silent();
}
/** Accumulate (add)@a len frames FROM THE START OF @a src into self at @a offset */
void accumulate_from(const AudioBuffer& src, nframes_t len, nframes_t offset) {
assert(_capacity > 0);
assert(offset + len <= _capacity);
Sample* const dst_raw = _data + offset;
const Sample* const src_raw = src.data();
mix_buffers_no_gain(dst_raw, src_raw, len);
_silent = (src.silent() && _silent);
}
/** Accumulate (add) @a len frames FROM THE START OF @a src into self at @a offset
* scaling by @a gain_coeff */
void accumulate_with_gain_from(const AudioBuffer& src, nframes_t len, nframes_t offset, gain_t gain_coeff) {
assert(_capacity > 0);
assert(offset + len <= _capacity);
Sample* const dst_raw = _data + offset;
const Sample* const src_raw = src.data();
mix_buffers_with_gain (dst_raw, src_raw, len, gain_coeff);
_silent = ( (src.silent() && _silent) || (_silent && gain_coeff == 0) );
}
void apply_gain(gain_t gain, nframes_t len, nframes_t offset=0) {
apply_gain_to_buffer (_data + offset, len, gain);
}
/** Set the data contained by this buffer manually (for setting directly to jack buffer).
*
* Constructor MUST have been passed capacity=0 or this will die (to prevent mem leaks).
*/
void set_data (Sample* data, size_t size) {
assert(!_owns_data); // prevent leaks
_capacity = size;
_size = size;
_data = data;
_silent = false;
}
/** Reallocate the buffer used internally to handle at least @nframes of data
*
* Constructor MUST have been passed capacity!=0 or this will die (to prevent mem leaks).
*/
void resize (size_t nframes);
const Sample* data () const { return _data; }
Sample* data () { return _data; }
const Sample* data(nframes_t nframes, nframes_t offset) const
{ assert(offset + nframes <= _capacity); return _data + offset; }
Sample* data (nframes_t nframes, nframes_t offset)
{ assert(offset + nframes <= _capacity); return _data + offset; }
private:
bool _owns_data;
Sample* _data; ///< Actual buffer contents
};
} // namespace ARDOUR
#endif // __ardour_audio_audio_buffer_h__

View File

@ -0,0 +1,277 @@
/*
Copyright (C) 2000-2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_audio_diskstream_h__
#define __ardour_audio_diskstream_h__
#include <sigc++/signal.h>
#include <cmath>
#include <string>
#include <queue>
#include <map>
#include <vector>
#include <time.h>
#include <pbd/fastlog.h>
#include <pbd/ringbufferNPT.h>
#include <pbd/stateful.h>
#include <pbd/rcu.h>
#include <ardour/ardour.h>
#include <ardour/configuration.h>
#include <ardour/session.h>
#include <ardour/route_group.h>
#include <ardour/route.h>
#include <ardour/port.h>
#include <ardour/utils.h>
#include <ardour/diskstream.h>
#include <ardour/audioplaylist.h>
struct tm;
namespace ARDOUR {
class AudioEngine;
class Send;
class Session;
class AudioPlaylist;
class AudioFileSource;
class IO;
class AudioDiskstream : public Diskstream
{
public:
AudioDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable);
AudioDiskstream (Session &, const XMLNode&);
~AudioDiskstream();
float playback_buffer_load() const;
float capture_buffer_load() const;
string input_source (uint32_t n=0) const {
boost::shared_ptr<ChannelList> c = channels.reader();
if (n < c->size()) {
return (*c)[n]->source ? (*c)[n]->source->name() : "";
} else {
return "";
}
}
Port *input_source_port (uint32_t n=0) const {
boost::shared_ptr<ChannelList> c = channels.reader();
if (n < c->size()) return (*c)[n]->source; return 0;
}
void set_record_enabled (bool yn);
int set_destructive (bool yn);
bool can_become_destructive (bool& requires_bounce) const;
float peak_power(uint32_t n = 0) {
boost::shared_ptr<ChannelList> c = channels.reader();
ChannelInfo* chaninfo = (*c)[n];
float x = chaninfo->peak_power;
chaninfo->peak_power = 0.0f;
if (x > 0.0f) {
return 20.0f * fast_log10(x);
} else {
return minus_infinity();
}
}
boost::shared_ptr<AudioPlaylist> audio_playlist () { return boost::dynamic_pointer_cast<AudioPlaylist>(_playlist); }
int use_playlist (boost::shared_ptr<Playlist>);
int use_new_playlist ();
int use_copy_playlist ();
Sample *playback_buffer (uint32_t n = 0) {
boost::shared_ptr<ChannelList> c = channels.reader();
if (n < c->size())
return (*c)[n]->current_playback_buffer;
return 0;
}
Sample *capture_buffer (uint32_t n = 0) {
boost::shared_ptr<ChannelList> c = channels.reader();
if (n < c->size())
return (*c)[n]->current_capture_buffer;
return 0;
}
boost::shared_ptr<AudioFileSource> write_source (uint32_t n=0) {
boost::shared_ptr<ChannelList> c = channels.reader();
if (n < c->size())
return (*c)[n]->write_source;
return boost::shared_ptr<AudioFileSource>();
}
int add_channel (uint32_t how_many);
int remove_channel (uint32_t how_many);
/* stateful */
XMLNode& get_state(void);
int set_state(const XMLNode& node);
void monitor_input (bool);
static void swap_by_ptr (Sample *first, Sample *last) {
while (first < last) {
Sample tmp = *first;
*first++ = *last;
*last-- = tmp;
}
}
static void swap_by_ptr (Sample *first, Sample *last, nframes_t n) {
while (n--) {
Sample tmp = *first;
*first++ = *last;
*last-- = tmp;
}
}
XMLNode* deprecated_io_node;
protected:
friend class Session;
/* the Session is the only point of access for these
because they require that the Session is "inactive"
while they are called.
*/
void set_pending_overwrite(bool);
int overwrite_existing_buffers ();
void set_block_size (nframes_t);
int internal_playback_seek (nframes_t distance);
int can_internal_playback_seek (nframes_t distance);
int rename_write_sources ();
void reset_write_sources (bool, bool force = false);
void non_realtime_input_change ();
protected:
friend class Auditioner;
int seek (nframes_t which_sample, bool complete_refill = false);
protected:
friend class AudioTrack;
int process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input);
bool commit (nframes_t nframes);
private:
struct ChannelInfo {
ChannelInfo (nframes_t buffer_size, nframes_t speed_buffer_size, nframes_t wrap_buffer_size);
~ChannelInfo ();
Sample *playback_wrap_buffer;
Sample *capture_wrap_buffer;
Sample *speed_buffer;
float peak_power;
boost::shared_ptr<AudioFileSource> fades_source;
boost::shared_ptr<AudioFileSource> write_source;
/// the Port that our audio data comes from
Port *source;
Sample *current_capture_buffer;
Sample *current_playback_buffer;
RingBufferNPT<Sample> *playback_buf;
RingBufferNPT<Sample> *capture_buf;
Sample* scrub_buffer;
Sample* scrub_forward_buffer;
Sample* scrub_reverse_buffer;
RingBufferNPT<Sample>::rw_vector playback_vector;
RingBufferNPT<Sample>::rw_vector capture_vector;
RingBufferNPT<CaptureTransition> * capture_transition_buf;
// the following are used in the butler thread only
nframes_t curr_capture_cnt;
};
typedef std::vector<ChannelInfo*> ChannelList;
/* The two central butler operations */
int do_flush (Session::RunContext context, bool force = false);
int do_refill () { return _do_refill(_mixdown_buffer, _gain_buffer); }
int do_refill_with_alloc ();
int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
nframes_t& start, nframes_t cnt,
ChannelInfo* channel_info, int channel, bool reversed);
void finish_capture (bool rec_monitors_input, boost::shared_ptr<ChannelList>);
void transport_stopped (struct tm&, time_t, bool abort);
void transport_looped (nframes_t transport_frame);
void init (Diskstream::Flag);
void init_channel (ChannelInfo &chan);
void destroy_channel (ChannelInfo &chan);
int use_new_write_source (uint32_t n=0);
int find_and_use_playlist (const string&);
void allocate_temporary_buffers ();
int use_pending_capture_data (XMLNode& node);
void get_input_sources ();
void check_record_status (nframes_t transport_frame, nframes_t nframes, bool can_record);
void set_align_style_from_io();
void setup_destructive_playlist ();
void use_destructive_playlist ();
void engage_record_enable ();
void disengage_record_enable ();
// Working buffers for do_refill (butler thread)
static void allocate_working_buffers();
static void free_working_buffers();
static size_t _working_buffers_size;
static Sample* _mixdown_buffer;
static gain_t* _gain_buffer;
std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources;
SerializedRCUManager<ChannelList> channels;
/* really */
private:
int _do_refill (Sample *mixdown_buffer, float *gain_buffer);
int add_channel_to (boost::shared_ptr<ChannelList>, uint32_t how_many);
int remove_channel_from (boost::shared_ptr<ChannelList>, uint32_t how_many);
};
} // namespace ARDOUR
#endif /* __ardour_audio_diskstream_h__ */

View File

@ -0,0 +1,54 @@
/*
Copyright (C) 2003-2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_audio_library_h__
#define __ardour_audio_library_h__
#include <string>
#include <map>
#include <vector>
using std::vector;
using std::string;
using std::map;
namespace ARDOUR {
class AudioLibrary
{
public:
AudioLibrary ();
~AudioLibrary ();
void set_tags (string member, vector<string> tags);
vector<string> get_tags (string member);
void search_members_and (vector<string>& results, const vector<string> tags);
void save_changes();
private:
string src;
};
extern AudioLibrary* Library;
} // ARDOUR namespace
#endif // __ardour_audio_library_h__

View File

@ -0,0 +1,46 @@
/*
Copyright (C) 2002 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: port.h 712 2006-07-28 01:08:57Z drobilla $
*/
#ifndef __ardour_audio_port_h__
#define __ardour_audio_port_h__
#include <ardour/base_audio_port.h>
namespace ARDOUR {
class AudioPort : public BaseAudioPort, public PortFacade {
public:
~AudioPort();
void reset ();
void cycle_start (nframes_t nframes, nframes_t offset);
void cycle_end (nframes_t nframes, nframes_t offset);
protected:
friend class AudioEngine;
AudioPort (const std::string&, Flags, bool external, nframes_t);
};
} // namespace ARDOUR
#endif /* __ardour_audio_port_h__ */

View File

@ -0,0 +1,80 @@
/*
Copyright (C) 2002-2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_audio_track_h__
#define __ardour_audio_track_h__
#include <ardour/track.h>
namespace ARDOUR {
class Session;
class AudioDiskstream;
class AudioPlaylist;
class RouteGroup;
class AudioTrack : public Track
{
public:
AudioTrack (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal);
AudioTrack (Session&, const XMLNode&);
~AudioTrack ();
int set_mode (TrackMode m);
bool can_use_mode (TrackMode m, bool& bounce_required);
int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
nframes_t offset, bool can_record, bool rec_monitors_input);
boost::shared_ptr<AudioDiskstream> audio_diskstream() const;
int use_diskstream (string name);
int use_diskstream (const PBD::ID& id);
int export_stuff (BufferSet& bufs, nframes_t nframes, nframes_t end_frame);
void freeze (InterThreadInfo&);
void unfreeze ();
void bounce (InterThreadInfo&);
void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
int set_state(const XMLNode& node);
protected:
XMLNode& state (bool full);
int _set_state (const XMLNode&, bool call_base);
private:
int set_diskstream (boost::shared_ptr<AudioDiskstream>, void *);
int deprecated_use_diskstream_connections ();
void set_state_part_two ();
void set_state_part_three ();
};
} // namespace ARDOUR
#endif /* __ardour_audio_track_h__ */

View File

@ -0,0 +1,172 @@
/*
Copyright (C) 2006 Paul Davis
Written by Taybin Rutkin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_audio_unit_h__
#define __ardour_audio_unit_h__
#include <stdint.h>
#include <boost/shared_ptr.hpp>
#include <list>
#include <set>
#include <string>
#include <vector>
#include <ardour/plugin.h>
#include <AudioUnit/AudioUnit.h>
#include <appleutility/AUParamInfo.h>
#include <boost/shared_ptr.hpp>
class CAComponent;
class CAAudioUnit;
class CAComponentDescription;
struct AudioBufferList;
namespace ARDOUR {
class AudioEngine;
class Session;
struct AUParameterDescriptor : public Plugin::ParameterDescriptor {
// additional fields to make operations more efficient
AudioUnitParameterID id;
AudioUnitScope scope;
AudioUnitElement element;
float default_value;
bool automatable;
AudioUnitParameterUnit unit;
};
class AUPlugin : public ARDOUR::Plugin
{
public:
AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAComponent> comp);
AUPlugin (const AUPlugin& other);
virtual ~AUPlugin ();
std::string unique_id () const;
const char * label () const;
const char * name () const { return _info->name.c_str(); }
const char * maker () const { return _info->creator.c_str(); }
uint32_t parameter_count () const;
float default_value (uint32_t port);
nframes_t signal_latency () const;
void set_parameter (uint32_t which, float val);
float get_parameter (uint32_t which) const;
int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
uint32_t nth_parameter (uint32_t which, bool& ok) const;
void activate ();
void deactivate ();
void set_block_size (nframes_t nframes);
int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset);
std::set<uint32_t> automatable() const;
string describe_parameter (uint32_t);
string state_node_name () const { return "audiounit"; }
void print_parameter (uint32_t, char*, uint32_t len) const;
bool parameter_is_audio (uint32_t) const;
bool parameter_is_control (uint32_t) const;
bool parameter_is_input (uint32_t) const;
bool parameter_is_output (uint32_t) const;
XMLNode& get_state();
int set_state(const XMLNode& node);
bool save_preset (string name);
bool load_preset (const string preset_label);
std::vector<std::string> get_presets ();
bool has_editor () const;
bool fixed_io() const { return false; }
int32_t can_support_input_configuration (int32_t in);
int32_t compute_output_streams (int32_t nplugins);
uint32_t output_streams() const;
uint32_t input_streams() const;
boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
boost::shared_ptr<CAComponent> get_comp () const { return comp; }
OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList* ioData);
private:
boost::shared_ptr<CAComponent> comp;
boost::shared_ptr<CAAudioUnit> unit;
AudioStreamBasicDescription streamFormat;
bool initialized;
int format_set;
AudioBufferList* buffers;
UInt32 global_elements;
UInt32 output_elements;
UInt32 input_elements;
int set_output_format ();
int set_input_format ();
int set_stream_format (int scope, uint32_t cnt);
int _set_block_size (nframes_t nframes);
void discover_parameters ();
std::vector<std::pair<uint32_t, uint32_t> > parameter_map;
uint32_t current_maxbuf;
nframes_t current_offset;
nframes_t cb_offset;
vector<Sample*>* current_buffers;
nframes_t frames_processed;
std::vector<AUParameterDescriptor> descriptors;
void init ();
};
typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
class AUPluginInfo : public PluginInfo {
public:
AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
~AUPluginInfo ();
PluginPtr load (Session& session);
static PluginInfoList discover ();
static void get_names (CAComponentDescription&, std::string& name, Glib::ustring& maker);
static std::string stringify_descriptor (const CAComponentDescription&);
private:
boost::shared_ptr<CAComponentDescription> descriptor;
static void discover_music (PluginInfoList&);
static void discover_fx (PluginInfoList&);
static void discover_by_description (PluginInfoList&, CAComponentDescription&);
};
typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
} // namespace ARDOUR
#endif // __ardour_audio_unit_h__

View File

@ -0,0 +1,74 @@
/*
Copyright (C) 2008 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_audioanalyser_h__
#define __ardour_audioanalyser_h__
#include <vector>
#include <string>
#include <ostream>
#include <fstream>
#include <vamp-sdk/Plugin.h>
#include <ardour/audioregion.h>
namespace ARDOUR {
class Readable;
class Session;
class AudioAnalyser {
public:
typedef Vamp::Plugin AnalysisPlugin;
typedef std::string AnalysisPluginKey;
AudioAnalyser (float sample_rate, AnalysisPluginKey key);
virtual ~AudioAnalyser();
/* analysis object should provide a run method
that accepts a path to write the results to (optionally empty)
a Readable* to read data from
and a reference to a type-specific container to return the
results.
*/
void reset ();
protected:
float sample_rate;
AnalysisPlugin* plugin;
AnalysisPluginKey plugin_key;
nframes64_t bufsize;
nframes64_t stepsize;
int initialize_plugin (AnalysisPluginKey name, float sample_rate);
int analyse (const std::string& path, Readable*, uint32_t channel);
/* instances of an analysis object will have this method called
whenever there are results to process. if out is non-null,
the data should be written to the stream it points to.
*/
virtual int use_features (Vamp::Plugin::FeatureSet&, std::ostream*) = 0;
};
} /* namespace */
#endif /* __ardour_audioanalyser_h__ */

View File

@ -0,0 +1,276 @@
/*
Copyright (C) 2002-2004 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_audioengine_h__
#define __ardour_audioengine_h__
#include <list>
#include <set>
#include <cmath>
#include <exception>
#include <string>
#include <sigc++/signal.h>
#include <glibmm/thread.h>
#include <pbd/rcu.h>
#include <ardour/ardour.h>
#include <jack/jack.h>
#include <jack/transport.h>
#include <ardour/types.h>
#include <ardour/data_type.h>
namespace ARDOUR {
class Session;
class Port;
class InternalPort;
class AudioEngine : public sigc::trackable
{
public:
typedef std::set<Port*> Ports;
AudioEngine (std::string client_name);
virtual ~AudioEngine ();
jack_client_t* jack() const;
bool connected() const { return _jack != 0; }
bool is_realtime () const;
std::string client_name() const { return jack_client_name; }
int reconnect_to_jack ();
int disconnect_from_jack();
bool will_reconnect_at_halt ();
void set_reconnect_at_halt (bool);
int stop (bool forever = false);
int start ();
bool running() const { return _running; }
Glib::Mutex& process_lock() { return _process_lock; }
nframes_t frame_rate();
nframes_t frames_per_cycle();
int usecs_per_cycle () const { return _usecs_per_cycle; }
bool get_sync_offset (nframes_t& offset) const;
nframes_t frames_since_cycle_start () {
if (!_running || !_jack) return 0;
return jack_frames_since_cycle_start (_jack);
}
nframes_t frame_time () {
if (!_running || !_jack) return 0;
return jack_frame_time (_jack);
}
nframes_t transport_frame () const {
if (!_running || !_jack) return 0;
return jack_get_current_transport_frame (_jack);
}
int request_buffer_size (nframes_t);
nframes_t set_monitor_check_interval (nframes_t);
float get_cpu_load() {
if (!_running || !_jack) return 0;
return jack_cpu_load (_jack);
}
void set_session (Session *);
void remove_session ();
class PortRegistrationFailure : public std::exception {
public:
PortRegistrationFailure (const char* why = "") {
reason = why;
}
virtual const char *what() const throw() { return reason; }
private:
const char* reason;
};
class NoBackendAvailable : public std::exception {
public:
virtual const char *what() const throw() { return "could not connect to engine backend"; }
};
Port *register_input_port (DataType, const std::string& portname, bool publish);
Port *register_output_port (DataType, const std::string& portname, bool publish);
int unregister_port (Port &);
int connect (const std::string& source, const std::string& destination);
int disconnect (const std::string& source, const std::string& destination);
int disconnect (Port &);
const char ** get_ports (const std::string& port_name_pattern, const std::string& type_name_pattern, uint32_t flags);
uint32_t n_physical_outputs () const;
uint32_t n_physical_inputs () const;
bool can_request_hardware_monitoring ();
void get_physical_outputs (std::vector<std::string>&);
void get_physical_inputs (std::vector<std::string>&);
std::string get_nth_physical_output (DataType type, uint32_t n) {
return get_nth_physical (type, n, JackPortIsInput);
}
std::string get_nth_physical_input (DataType type, uint32_t n) {
return get_nth_physical (type, n, JackPortIsOutput);
}
nframes_t get_port_total_latency (const Port&);
void update_total_latencies ();
void update_total_latency (const Port&);
/** Caller may not delete the object pointed to by the return value
*/
Port *get_port_by_name (const std::string& name, bool keep = true) const;
enum TransportState {
TransportStopped = JackTransportStopped,
TransportRolling = JackTransportRolling,
TransportLooping = JackTransportLooping,
TransportStarting = JackTransportStarting
};
void transport_start ();
void transport_stop ();
void transport_locate (nframes_t);
TransportState transport_state ();
int reset_timebase ();
/* start/stop freewheeling */
int freewheel (bool onoff);
bool freewheeling() const { return _freewheeling; }
/* this signal is sent for every process() cycle while freewheeling.
the regular process() call to session->process() is not made.
*/
sigc::signal<int,nframes_t> Freewheel;
sigc::signal<void> Xrun;
/* this signal is if JACK notifies us of a graph order event */
sigc::signal<void> GraphReordered;
/* this signal is emitted if the sample rate changes */
sigc::signal<void,nframes_t> SampleRateChanged;
/* this signal is sent if JACK ever disconnects us */
sigc::signal<void> Halted;
/* these two are emitted when the engine itself is
started and stopped
*/
sigc::signal<void> Running;
sigc::signal<void> Stopped;
std::string make_port_name_relative (std::string);
std::string make_port_name_non_relative (std::string);
private:
ARDOUR::Session *session;
jack_client_t *_jack;
std::string jack_client_name;
mutable Glib::Mutex _process_lock;
Glib::Cond session_removed;
bool session_remove_pending;
bool _running;
bool _has_run;
nframes_t _buffer_size;
nframes_t _frame_rate;
/// number of frames between each check for changes in monitor input
nframes_t monitor_check_interval;
/// time of the last monitor check in frames
nframes_t last_monitor_check;
/// the number of frames processed since start() was called
nframes_t _processed_frames;
bool _freewheeling;
bool _freewheel_thread_registered;
sigc::slot<int,nframes_t> freewheel_action;
bool reconnect_on_halt;
int _usecs_per_cycle;
SerializedRCUManager<Ports> ports;
Port *register_port (DataType type, const std::string& portname, bool input, bool publish);
int process_callback (nframes_t nframes);
void remove_all_ports ();
Port* get_port (const std::string& short_name);
typedef std::pair<std::string,std::string> PortConnection;
typedef std::list<PortConnection> PortConnections;
PortConnections port_connections;
void remove_connections_for (Port&);
std::string get_nth_physical (DataType type, uint32_t n, int flags);
void port_registration_failure (const std::string& portname);
static int _xrun_callback (void *arg);
static int _graph_order_callback (void *arg);
static int _process_callback (nframes_t nframes, void *arg);
static int _sample_rate_callback (nframes_t nframes, void *arg);
static int _bufsize_callback (nframes_t nframes, void *arg);
static void _jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int, void*);
static int _jack_sync_callback (jack_transport_state_t, jack_position_t*, void *arg);
static void _freewheel_callback (int , void *arg);
void jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int);
int jack_sync_callback (jack_transport_state_t, jack_position_t*);
int jack_bufsize_callback (nframes_t);
int jack_sample_rate_callback (nframes_t);
static void halted (void *);
int connect_to_jack (std::string client_name);
void meter_thread ();
void start_metering_thread ();
void stop_metering_thread ();
Glib::Thread* m_meter_thread;
static gint m_meter_exit;
};
} // namespace ARDOUR
#endif /* __ardour_audioengine_h__ */

View File

@ -0,0 +1,183 @@
/*
Copyright (C) 2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_audiofilesource_h__
#define __ardour_audiofilesource_h__
#include <exception>
#include <time.h>
#include <ardour/audiosource.h>
namespace ARDOUR {
class non_existent_source : public std::exception {
public:
virtual const char *what() const throw() { return "audio file does not exist"; }
};
struct SoundFileInfo {
float samplerate;
uint16_t channels;
int64_t length;
std::string format_name;
int64_t timecode;
};
class AudioFileSource : public AudioSource {
public:
enum Flag {
Writable = 0x1,
CanRename = 0x2,
Broadcast = 0x4,
Removable = 0x8,
RemovableIfEmpty = 0x10,
RemoveAtDestroy = 0x20,
NoPeakFile = 0x40,
Destructive = 0x80
};
virtual ~AudioFileSource ();
bool set_name (const std::string& newname) { return (set_source_name(newname, destructive()) == 0); }
int set_source_name (Glib::ustring newname, bool destructive);
Glib::ustring path() const { return _path; }
Glib::ustring peak_path (Glib::ustring audio_path);
Glib::ustring find_broken_peakfile (Glib::ustring missing_peak_path,
Glib::ustring audio_path);
uint16_t channel() const { return _channel; }
static void set_peak_dir (Glib::ustring dir) { peak_dir = dir; }
static bool get_soundfile_info (Glib::ustring path, SoundFileInfo& _info, std::string& error);
static bool safe_file_extension (Glib::ustring path);
void set_allow_remove_if_empty (bool yn);
void mark_for_remove();
/* this block of methods do nothing for regular file sources, but are significant
for files used in destructive recording.
*/
virtual nframes_t last_capture_start_frame() const { return 0; }
virtual void mark_capture_start (nframes_t) {}
virtual void mark_capture_end () {}
virtual void clear_capture_marks() {}
virtual bool one_of_several_channels () const { return false; }
virtual int update_header (nframes_t when, struct tm&, time_t) = 0;
virtual int flush_header () = 0;
int move_to_trash (const Glib::ustring& trash_dir_name);
static bool is_empty (Session&, Glib::ustring path);
void mark_streaming_write_completed ();
void mark_take (Glib::ustring);
Glib::ustring take_id() const { return _take_id; }
bool is_embedded() const { return _is_embedded; }
static void set_bwf_serial_number (int);
static void set_search_path (Glib::ustring string);
static void set_header_position_offset (nframes_t offset );
int setup_peakfile ();
static sigc::signal<void> HeaderPositionOffsetChanged;
XMLNode& get_state ();
int set_state (const XMLNode&);
bool destructive() const { return (_flags & Destructive); }
virtual bool set_destructive (bool yn) { return false; }
bool can_truncate_peaks() const { return !destructive(); }
Flag flags() const { return _flags; }
void mark_immutable ();
/* this should really be protected, but C++ is getting stricter
and creating slots from protected member functions is starting
to cause issues.
*/
virtual void handle_header_position_change () {}
bool can_be_analysed() const { return _length > 0; }
protected:
/* constructor to be called for existing external-to-session files */
AudioFileSource (Session&, Glib::ustring path, Flag flags);
/* constructor to be called for new in-session files */
AudioFileSource (Session&, Glib::ustring path, Flag flags,
SampleFormat samp_format, HeaderFormat hdr_format);
/* constructor to be called for existing in-session files */
AudioFileSource (Session&, const XMLNode&, bool must_exit = true);
int init (Glib::ustring idstr, bool must_exist);
Glib::ustring _path;
Flag _flags;
Glib::ustring _take_id;
int64_t timeline_position;
bool file_is_new;
uint16_t _channel;
bool _is_embedded;
static bool determine_embeddedness(Glib::ustring path);
static Glib::ustring peak_dir;
static Glib::ustring search_path;
static char bwf_country_code[3];
static char bwf_organization_code[4];
static char bwf_serial_number[13];
static uint64_t header_position_offset;
virtual void set_timeline_position (int64_t pos);
virtual void set_header_timeline_position () = 0;
bool find (Glib::ustring& path, bool must_exist, bool& is_new, uint16_t& chan);
bool removable() const;
bool writable() const { return _flags & Writable; }
static Sample* get_interleave_buffer (nframes_t size);
private:
Glib::ustring old_peak_path (Glib::ustring audio_path);
Glib::ustring broken_peak_path (Glib::ustring audio_path);
};
} // namespace ARDOUR
#endif /* __ardour_audiofilesource_h__ */

View File

@ -0,0 +1,93 @@
/*
Copyright (C) 2003 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_audio_playlist_h__
#define __ardour_audio_playlist_h__
#include <vector>
#include <list>
#include <ardour/ardour.h>
#include <ardour/playlist.h>
namespace ARDOUR {
class Session;
class Region;
class AudioRegion;
class Source;
class AudioPlaylist : public ARDOUR::Playlist
{
public:
typedef std::list<boost::shared_ptr<Crossfade> > Crossfades;
public:
AudioPlaylist (Session&, const XMLNode&, bool hidden = false);
AudioPlaylist (Session&, string name, bool hidden = false);
AudioPlaylist (boost::shared_ptr<const AudioPlaylist>, string name, bool hidden = false);
AudioPlaylist (boost::shared_ptr<const AudioPlaylist>, nframes_t start, nframes_t cnt, string name, bool hidden = false);
~AudioPlaylist ();
void clear (bool with_signals=true);
nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, nframes_t start, nframes_t cnt, uint32_t chan_n=0);
int set_state (const XMLNode&);
sigc::signal<void,boost::shared_ptr<Crossfade> > NewCrossfade;
template<class T> void foreach_crossfade (T *t, void (T::*func)(boost::shared_ptr<Crossfade>));
void crossfades_at (nframes_t frame, Crossfades&);
bool destroy_region (boost::shared_ptr<Region>);
protected:
/* playlist "callbacks" */
void notify_crossfade_added (boost::shared_ptr<Crossfade>);
void flush_notifications ();
void finalize_split_region (boost::shared_ptr<Region> orig, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right);
void refresh_dependents (boost::shared_ptr<Region> region);
void check_dependents (boost::shared_ptr<Region> region, bool norefresh);
void remove_dependents (boost::shared_ptr<Region> region);
private:
Crossfades _crossfades;
Crossfades _pending_xfade_adds;
void crossfade_invalidated (boost::shared_ptr<Region>);
XMLNode& state (bool full_state);
void dump () const;
bool region_changed (Change, boost::shared_ptr<Region>);
void crossfade_changed (Change);
void add_crossfade (boost::shared_ptr<Crossfade>);
void source_offset_changed (boost::shared_ptr<AudioRegion> region);
};
} /* namespace ARDOUR */
#endif /* __ardour_audio_playlist_h__ */

View File

@ -0,0 +1,204 @@
/*
Copyright (C) 2000-2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_audio_region_h__
#define __ardour_audio_region_h__
#include <vector>
#include <list>
#include <pbd/fastlog.h>
#include <pbd/undo.h>
#include <ardour/ardour.h>
#include <ardour/region.h>
#include <ardour/gain.h>
#include <ardour/logcurve.h>
#include <ardour/export.h>
class XMLNode;
namespace ARDOUR {
class Route;
class Playlist;
class Session;
class Filter;
class AudioSource;
class AudioRegion : public Region
{
public:
static Change FadeInChanged;
static Change FadeOutChanged;
static Change FadeInActiveChanged;
static Change FadeOutActiveChanged;
static Change EnvelopeActiveChanged;
static Change ScaleAmplitudeChanged;
static Change EnvelopeChanged;
~AudioRegion();
bool speed_mismatch (float) const;
boost::shared_ptr<AudioSource> audio_source (uint32_t n=0) const;
void set_scale_amplitude (gain_t);
gain_t scale_amplitude() const { return _scale_amplitude; }
void normalize_to (float target_in_dB = 0.0f);
bool envelope_active () const { return _flags & Region::EnvelopeActive; }
bool fade_in_active () const { return _flags & Region::FadeIn; }
bool fade_out_active () const { return _flags & Region::FadeOut; }
boost::shared_ptr<AutomationList> fade_in() { return _fade_in; }
boost::shared_ptr<AutomationList> fade_out() { return _fade_out; }
boost::shared_ptr<AutomationList> envelope() { return _envelope; }
virtual nframes_t read_peaks (PeakData *buf, nframes_t npeaks,
nframes_t offset, nframes_t cnt,
uint32_t chan_n=0, double samples_per_unit= 1.0) const;
/* Readable interface */
virtual nframes64_t read (Sample*, nframes64_t pos, nframes64_t cnt, int channel) const;
virtual nframes64_t readable_length() const { return length(); }
virtual nframes_t read_at (Sample *buf, Sample *mixdown_buf,
float *gain_buf, nframes_t position, nframes_t cnt,
uint32_t chan_n = 0,
nframes_t read_frames = 0,
nframes_t skip_frames = 0) const;
virtual nframes_t master_read_at (Sample *buf, Sample *mixdown_buf,
float *gain_buf,
nframes_t position, nframes_t cnt, uint32_t chan_n=0) const;
virtual nframes_t read_raw_internal (Sample*, nframes_t, nframes_t) const;
XMLNode& state (bool);
int set_state (const XMLNode&);
static void set_default_fade (float steepness, nframes_t len);
bool fade_in_is_default () const;
bool fade_out_is_default () const;
enum FadeShape {
Linear,
Fast,
Slow,
LogA,
LogB
};
void set_fade_in_active (bool yn);
void set_fade_in_shape (FadeShape);
void set_fade_in_length (nframes_t);
void set_fade_in (FadeShape, nframes_t);
void set_fade_out_active (bool yn);
void set_fade_out_shape (FadeShape);
void set_fade_out_length (nframes_t);
void set_fade_out (FadeShape, nframes_t);
void set_envelope_active (bool yn);
void set_default_envelope ();
int separate_by_channel (ARDOUR::Session&, vector<boost::shared_ptr<AudioRegion> >&) const;
/* export */
int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&);
/* xfade/fade interactions */
void suspend_fade_in ();
void suspend_fade_out ();
void resume_fade_in ();
void resume_fade_out ();
int get_transients (AnalysisFeatureList&, bool force_new = false);
private:
friend class RegionFactory;
AudioRegion (boost::shared_ptr<AudioSource>, nframes_t start, nframes_t length);
AudioRegion (boost::shared_ptr<AudioSource>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
AudioRegion (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
AudioRegion (boost::shared_ptr<const AudioRegion>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
AudioRegion (boost::shared_ptr<AudioSource>, const XMLNode&);
AudioRegion (SourceList &, const XMLNode&);
private:
void init ();
void set_default_fades ();
void set_default_fade_in ();
void set_default_fade_out ();
void recompute_gain_at_end ();
void recompute_gain_at_start ();
nframes_t _read_at (const SourceList&, nframes_t limit,
Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, nframes_t position, nframes_t cnt,
uint32_t chan_n = 0,
nframes_t read_frames = 0,
nframes_t skip_frames = 0,
bool raw = false) const;
void recompute_at_start ();
void recompute_at_end ();
void envelope_changed ();
void fade_in_changed ();
void fade_out_changed ();
void source_offset_changed ();
void listen_to_my_curves ();
void listen_to_my_sources ();
boost::shared_ptr<AutomationList> _fade_in;
FadeShape _fade_in_shape;
boost::shared_ptr<AutomationList> _fade_out;
FadeShape _fade_out_shape;
boost::shared_ptr<AutomationList> _envelope;
gain_t _scale_amplitude;
uint32_t _fade_in_disabled;
uint32_t _fade_out_disabled;
protected:
/* default constructor for derived (compound) types */
AudioRegion (Session& s, nframes_t, nframes_t, std::string name);
AudioRegion (boost::shared_ptr<const AudioRegion>);
int set_live_state (const XMLNode&, Change&, bool send);
};
} /* namespace ARDOUR */
/* access from C objects */
extern "C" {
int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t length, intptr_t data, uint32_t n_chan, double samples_per_unit);
uint32_t region_length_from_c (void *arg);
uint32_t sourcefile_length_from_c (void *arg, double);
}
#endif /* __ardour_audio_region_h__ */

View File

@ -0,0 +1,159 @@
/*
Copyright (C) 2000 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_audio_source_h__
#define __ardour_audio_source_h__
#include <list>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <time.h>
#include <glibmm/thread.h>
#include <glibmm/ustring.h>
#include <sigc++/signal.h>
#include <ardour/source.h>
#include <ardour/ardour.h>
#include <pbd/stateful.h>
#include <pbd/xml++.h>
using std::list;
using std::vector;
namespace ARDOUR {
class AudioSource : public Source, public boost::enable_shared_from_this<ARDOUR::AudioSource>
{
public:
AudioSource (Session&, Glib::ustring name);
AudioSource (Session&, const XMLNode&);
virtual ~AudioSource ();
nframes64_t readable_length() const { return _length; }
uint32_t n_channels() const { return 1; }
virtual nframes_t available_peaks (double zoom) const;
/* stopgap until nframes_t becomes nframes64_t. this function is needed by the Readable interface */
virtual nframes64_t read (Sample *dst, nframes64_t start, nframes64_t cnt, int channel) const {
/* XXX currently ignores channel, assuming that source is always mono, which
historically has been true.
*/
return read (dst, (nframes_t) start, (nframes_t) cnt);
}
virtual nframes_t read (Sample *dst, nframes_t start, nframes_t cnt) const;
virtual nframes_t write (Sample *src, nframes_t cnt);
virtual float sample_rate () const = 0;
virtual void mark_for_remove() = 0;
virtual void mark_streaming_write_completed () {}
virtual bool can_truncate_peaks() const { return true; }
void set_captured_for (Glib::ustring str) { _captured_for = str; }
Glib::ustring captured_for() const { return _captured_for; }
uint32_t read_data_count() const { return _read_data_count; }
uint32_t write_data_count() const { return _write_data_count; }
int read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_visual_peak) const;
int build_peaks ();
bool peaks_ready (sigc::slot<void>, sigc::connection&) const;
mutable sigc::signal<void> PeaksReady;
mutable sigc::signal<void,nframes_t,nframes_t> PeakRangeReady;
XMLNode& get_state ();
int set_state (const XMLNode&);
int rename_peakfile (Glib::ustring newpath);
void touch_peakfile ();
static void set_build_missing_peakfiles (bool yn) {
_build_missing_peakfiles = yn;
}
static void set_build_peakfiles (bool yn) {
_build_peakfiles = yn;
}
static bool get_build_peakfiles () {
return _build_peakfiles;
}
virtual int setup_peakfile () { return 0; }
int prepare_for_peakfile_writes ();
void done_with_peakfile_writes (bool done = true);
protected:
static bool _build_missing_peakfiles;
static bool _build_peakfiles;
bool _peaks_built;
mutable Glib::Mutex _lock;
mutable Glib::Mutex _peaks_ready_lock;
Glib::ustring peakpath;
Glib::ustring _captured_for;
mutable uint32_t _read_data_count; // modified in read()
mutable uint32_t _write_data_count; // modified in write()
int initialize_peakfile (bool newfile, Glib::ustring path);
int build_peaks_from_scratch ();
int compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, bool intermediate_peaks_ready_signal);
void truncate_peakfile();
mutable off_t _peak_byte_max; // modified in compute_and_write_peak()
virtual nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const = 0;
virtual nframes_t write_unlocked (Sample *dst, nframes_t cnt) = 0;
virtual Glib::ustring peak_path(Glib::ustring audio_path) = 0;
virtual Glib::ustring find_broken_peakfile (Glib::ustring missing_peak_path, Glib::ustring audio_path) = 0;
void update_length (nframes_t pos, nframes_t cnt);
virtual int read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt,
double samples_per_visual_peak, nframes_t fpp) const;
int compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force,
bool intermediate_peaks_ready_signal, nframes_t frames_per_peak);
private:
int peakfile;
nframes_t peak_leftover_cnt;
nframes_t peak_leftover_size;
Sample* peak_leftovers;
nframes_t peak_leftover_frame;
bool file_changed (Glib::ustring path);
};
}
#endif /* __ardour_audio_source_h__ */

View File

@ -0,0 +1,70 @@
/*
Copyright (C) 2001 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_auditioner_h__
#define __ardour_auditioner_h__
#include <string>
#include <glibmm/thread.h>
#include <ardour/ardour.h>
#include <ardour/audio_track.h>
namespace ARDOUR {
class Session;
class AudioRegion;
class AudioPlaylist;
class Auditioner : public AudioTrack
{
public:
Auditioner (Session&);
~Auditioner ();
void audition_region (boost::shared_ptr<Region>);
ARDOUR::AudioPlaylist& prepare_playlist ();
void audition_current_playlist ();
int play_audition (nframes_t nframes);
void cancel_audition () {
g_atomic_int_set (&_active, 0);
}
bool active() const { return g_atomic_int_get (&_active); }
private:
boost::shared_ptr<AudioRegion> the_region;
nframes_t current_frame;
mutable gint _active;
Glib::Mutex lock;
nframes_t length;
void drop_ports ();
static void *_drop_ports (void *);
void actually_drop_ports ();
void output_changed (IOChange, void*);
};
}; /* namespace ARDOUR */
#endif /* __ardour_auditioner_h__ */

View File

@ -0,0 +1,50 @@
/*
Copyright (C) 2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_auto_bundle_h__
#define __ardour_auto_bundle_h__
#include <vector>
#include <glibmm/thread.h>
#include "ardour/bundle.h"
namespace ARDOUR {
class AutoBundle : public Bundle {
public:
AutoBundle (bool i = true);
AutoBundle (std::string const &, bool i = true);
uint32_t nchannels () const;
const PortList& channel_ports (uint32_t) const;
void set_channels (uint32_t);
void set_port (uint32_t, std::string const &);
private:
/// mutex for _ports;
/// XXX: is this necessary?
mutable Glib::Mutex _ports_mutex;
std::vector<PortList> _ports;
};
}
#endif /* __ardour_auto_bundle_h__ */

View File

@ -0,0 +1,121 @@
/*
Copyright (C) 2000-2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_automatable_h__
#define __ardour_automatable_h__
#include <set>
#include <map>
#include <boost/shared_ptr.hpp>
#include <ardour/session_object.h>
#include <ardour/automation_event.h>
#include <ardour/automation_control.h>
#include <ardour/parameter.h>
namespace ARDOUR {
class Session;
class AutomationControl;
class Automatable : public SessionObject
{
public:
Automatable(Session&, const std::string& name);
virtual ~Automatable() {}
// shorthand for gain, pan, etc
inline boost::shared_ptr<AutomationControl>
control(AutomationType type, bool create_if_missing=false) {
return control(Parameter(type), create_if_missing);
}
virtual boost::shared_ptr<AutomationControl> control(Parameter id, bool create_if_missing=false);
virtual boost::shared_ptr<const AutomationControl> control(Parameter id) const;
boost::shared_ptr<AutomationControl> control_factory(boost::shared_ptr<AutomationList> list);
typedef std::map<Parameter,boost::shared_ptr<AutomationControl> > Controls;
Controls& controls() { return _controls; }
const Controls& controls() const { return _controls; }
virtual void add_control(boost::shared_ptr<AutomationControl>);
virtual void automation_snapshot(nframes_t now, bool force);
bool should_snapshot (nframes_t now) {
return (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval);
}
virtual void transport_stopped(nframes_t now);
virtual bool find_next_event(nframes_t start, nframes_t end, ControlEvent& ev) const;
virtual string describe_parameter(Parameter param);
virtual float default_parameter_value(Parameter param) { return 1.0f; }
virtual void clear_automation();
AutoState get_parameter_automation_state (Parameter param, bool lock = true);
virtual void set_parameter_automation_state (Parameter param, AutoState);
AutoStyle get_parameter_automation_style (Parameter param);
void set_parameter_automation_style (Parameter param, AutoStyle);
void protect_automation ();
void what_has_automation(std::set<Parameter>&) const;
void what_has_visible_automation(std::set<Parameter>&) const;
const std::set<Parameter>& what_can_be_automated() const { return _can_automate_list; }
void mark_automation_visible(Parameter, bool);
Glib::Mutex& automation_lock() const { return _automation_lock; }
static void set_automation_interval (jack_nframes_t frames) {
_automation_interval = frames;
}
static jack_nframes_t automation_interval() {
return _automation_interval;
}
protected:
void can_automate(Parameter);
virtual void auto_state_changed (Parameter which) {}
int set_automation_state(const XMLNode&, Parameter default_param);
XMLNode& get_automation_state();
int load_automation (const std::string& path);
int old_set_automation_state(const XMLNode&);
mutable Glib::Mutex _automation_lock;
Controls _controls;
std::set<Parameter> _visible_controls;
std::set<Parameter> _can_automate_list;
nframes_t _last_automation_snapshot;
static nframes_t _automation_interval;
};
} // namespace ARDOUR
#endif /* __ardour_automatable_h__ */

View File

@ -0,0 +1,64 @@
/*
Copyright (C) 2007 Paul Davis
Author: Dave Robillard
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_automation_control_h__
#define __ardour_automation_control_h__
#include <boost/shared_ptr.hpp>
#include <pbd/controllable.h>
#include <ardour/parameter.h>
namespace ARDOUR {
class AutomationList;
class Session;
class Automatable;
/** A PBD:Controllable with associated automation data (AutomationList)
*/
class AutomationControl : public PBD::Controllable
{
public:
AutomationControl(ARDOUR::Session&,
boost::shared_ptr<ARDOUR::AutomationList>,
std::string name="unnamed controllable");
void set_value(float val);
float get_value() const;
float user_value() const;
void set_list(boost::shared_ptr<ARDOUR::AutomationList>);
boost::shared_ptr<ARDOUR::AutomationList> list() { return _list; }
boost::shared_ptr<const ARDOUR::AutomationList> list() const { return _list; }
Parameter parameter() const;
protected:
ARDOUR::Session& _session;
boost::shared_ptr<ARDOUR::AutomationList> _list;
float _user_value;
};
} // namespace ARDOUR
#endif /* __ardour_automation_control_h__ */

View File

@ -0,0 +1,309 @@
/*
Copyright (C) 2002 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_automation_event_h__
#define __ardour_automation_event_h__
#include <stdint.h>
#include <list>
#include <cmath>
#include <sigc++/signal.h>
#include <glibmm/thread.h>
#include <boost/pool/pool.hpp>
#include <boost/pool/pool_alloc.hpp>
#include <pbd/undo.h>
#include <pbd/xml++.h>
#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/parameter.h>
namespace ARDOUR {
class Curve;
struct ControlEvent {
ControlEvent (double w, double v)
: when (w), value (v), coeff (0) {
}
ControlEvent (const ControlEvent& other)
: when (other.when), value (other.value), coeff (0) {
if (other.coeff) {
create_coeffs();
for (size_t i=0; i < 4; ++i)
coeff[i] = other.coeff[i];
}
}
~ControlEvent() { if (coeff) delete[] coeff; }
void create_coeffs() {
if (!coeff)
coeff = new double[4];
coeff[0] = coeff[1] = coeff[2] = coeff[3] = 0.0;
}
double when;
double value;
double* coeff; ///< double[4] allocated by Curve as needed
};
/* automation lists use a pool allocator that does not use a lock and
allocates 8k of new pointers at a time
*/
typedef boost::fast_pool_allocator<ControlEvent*,
boost::default_user_allocator_new_delete,
boost::details::pool::null_mutex,
8192> ControlEventAllocator;
class AutomationList : public PBD::StatefulDestructible
{
public:
typedef std::list<ControlEvent*,ControlEventAllocator> EventList;
typedef EventList::iterator iterator;
typedef EventList::reverse_iterator reverse_iterator;
typedef EventList::const_iterator const_iterator;
AutomationList (Parameter id, double min_val, double max_val, double default_val);
AutomationList (const XMLNode&, Parameter id);
~AutomationList();
AutomationList (const AutomationList&);
AutomationList (const AutomationList&, double start, double end);
AutomationList& operator= (const AutomationList&);
bool operator== (const AutomationList&);
const Parameter& parameter() const { return _parameter; }
void set_parameter(Parameter p) { _parameter = p; }
void freeze();
void thaw ();
EventList::size_type size() const { return _events.size(); }
bool empty() const { return _events.empty(); }
void reset_default (double val) {
_default_value = val;
}
void clear ();
void x_scale (double factor);
bool extend_to (double);
void slide (iterator before, double distance);
void reposition_for_rt_add (double when);
void rt_add (double when, double value);
void add (double when, double value);
/* this should be private but old-school automation loading needs it in IO/IOProcessor */
void fast_simple_add (double when, double value);
void reset_range (double start, double end);
void erase_range (double start, double end);
void erase (iterator);
void erase (iterator, iterator);
void move_range (iterator start, iterator end, double, double);
void modify (iterator, double, double);
AutomationList* cut (double, double);
AutomationList* copy (double, double);
void clear (double, double);
AutomationList* cut (iterator, iterator);
AutomationList* copy (iterator, iterator);
void clear (iterator, iterator);
bool paste (AutomationList&, double position, float times);
void set_automation_state (AutoState);
AutoState automation_state() const { return _state; }
sigc::signal<void> automation_style_changed;
void set_automation_style (AutoStyle m);
AutoStyle automation_style() const { return _style; }
sigc::signal<void> automation_state_changed;
bool automation_playback() const {
return (_state & Play) || ((_state & Touch) && !_touching);
}
bool automation_write () const {
return (_state & Write) || ((_state & Touch) && _touching);
}
void start_touch ();
void stop_touch ();
bool touching() const { return _touching; }
void set_yrange (double min, double max) {
_min_yval = min;
_max_yval = max;
}
double get_max_y() const { return _max_yval; }
double get_min_y() const { return _min_yval; }
void truncate_end (double length);
void truncate_start (double length);
iterator begin() { return _events.begin(); }
iterator end() { return _events.end(); }
ControlEvent* back() { return _events.back(); }
ControlEvent* front() { return _events.front(); }
const_iterator const_begin() const { return _events.begin(); }
const_iterator const_end() const { return _events.end(); }
std::pair<AutomationList::iterator,AutomationList::iterator> control_points_adjacent (double when);
template<class T> void apply_to_points (T& obj, void (T::*method)(const AutomationList&)) {
Glib::Mutex::Lock lm (_lock);
(obj.*method)(*this);
}
sigc::signal<void> StateChanged;
XMLNode& get_state(void);
int set_state (const XMLNode &s);
XMLNode& state (bool full);
XMLNode& serialize_events ();
void set_max_xval (double);
double get_max_xval() const { return _max_xval; }
double eval (double where) {
Glib::Mutex::Lock lm (_lock);
return unlocked_eval (where);
}
double rt_safe_eval (double where, bool& ok) {
Glib::Mutex::Lock lm (_lock, Glib::TRY_LOCK);
if ((ok = lm.locked())) {
return unlocked_eval (where);
} else {
return 0.0;
}
}
static inline bool time_comparator (const ControlEvent* a, const ControlEvent* b) {
return a->when < b->when;
}
/** Lookup cache for eval functions, range contains equivalent values */
struct LookupCache {
LookupCache() : left(-1) {}
double left; /* leftmost x coordinate used when finding "range" */
std::pair<AutomationList::const_iterator,AutomationList::const_iterator> range;
};
/** Lookup cache for point finding, range contains points between left and right */
struct SearchCache {
SearchCache() : left(-1), right(-1) {}
double left; /* leftmost x coordinate used when finding "range" */
double right; /* rightmost x coordinate used when finding "range" */
std::pair<AutomationList::const_iterator,AutomationList::const_iterator> range;
};
static sigc::signal<void, AutomationList*> AutomationListCreated;
const EventList& events() const { return _events; }
double default_value() const { return _default_value; }
// teeny const violations for Curve
mutable sigc::signal<void> Dirty;
Glib::Mutex& lock() const { return _lock; }
LookupCache& lookup_cache() const { return _lookup_cache; }
SearchCache& search_cache() const { return _search_cache; }
/** Called by locked entry point and various private
* locations where we already hold the lock.
*
* FIXME: Should this be private? Curve needs it..
*/
double unlocked_eval (double x) const;
bool rt_safe_earliest_event (double start, double end, double& x, double& y, bool start_inclusive=false) const;
bool rt_safe_earliest_event_unlocked (double start, double end, double& x, double& y, bool start_inclusive=false) const;
Curve& curve() { return *_curve; }
const Curve& curve() const { return *_curve; }
enum InterpolationStyle {
Discrete,
Linear,
Curved
};
InterpolationStyle interpolation() const { return _interpolation; }
void set_interpolation(InterpolationStyle style) { _interpolation = style; }
private:
/** Called by unlocked_eval() to handle cases of 3 or more control points.
*/
double multipoint_eval (double x) const;
void build_search_cache_if_necessary(double start, double end) const;
bool rt_safe_earliest_event_discrete_unlocked (double start, double end, double& x, double& y, bool inclusive) const;
bool rt_safe_earliest_event_linear_unlocked (double start, double end, double& x, double& y, bool inclusive) const;
AutomationList* cut_copy_clear (double, double, int op);
int deserialize_events (const XMLNode&);
void maybe_signal_changed ();
void mark_dirty ();
void _x_scale (double factor);
mutable LookupCache _lookup_cache;
mutable SearchCache _search_cache;
Parameter _parameter;
InterpolationStyle _interpolation;
EventList _events;
mutable Glib::Mutex _lock;
int8_t _frozen;
bool _changed_when_thawed;
AutoState _state;
AutoStyle _style;
bool _touching;
bool _new_touch;
double _max_xval;
double _min_yval;
double _max_yval;
double _default_value;
bool _sort_pending;
iterator _rt_insertion_point;
double _rt_pos;
Curve* _curve;
};
} // namespace
#endif /* __ardour_automation_event_h__ */

View File

@ -0,0 +1,106 @@
/*
Copyright (C) 2002 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: port.h 712 2006-07-28 01:08:57Z drobilla $
*/
#ifndef __ardour_base_audio_port_h__
#define __ardour_base_audio_port_h__
#include <string>
#include <sigc++/signal.h>
#include <pbd/failed_constructor.h>
#include <ardour/ardour.h>
#include <ardour/port.h>
#include <ardour/audio_buffer.h>
namespace ARDOUR {
class AudioEngine;
class BaseAudioPort : public virtual Port {
public:
virtual ~BaseAudioPort();
DataType type() const { return DataType::AUDIO; }
virtual Buffer& get_buffer () {
assert (_buffer);
return *_buffer;
}
virtual AudioBuffer& get_audio_buffer() {
assert (_buffer);
return *_buffer;
}
void reset ();
void reset_overs () {
/* XXX NOT THREAD SAFE */
_short_overs = 0;
_long_overs = 0;
_overlen = 0;
}
void reset_peak_meter () {
/* XXX NOT THREAD SAFE */
_peak = 0;
}
void reset_meters () {
/* XXX NOT THREAD SAFE */
reset_peak_meter ();
reset_overs ();
}
float peak_db() const { return _peak_db; }
Sample peak() const { return _peak; }
uint32_t short_overs () const { return _short_overs; }
uint32_t long_overs () const { return _long_overs; }
static void set_short_over_length (nframes_t);
static void set_long_over_length (nframes_t);
void set_mixdown_function (void (*func)(const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool));
protected:
BaseAudioPort (const std::string& name, Flags flags);
AudioBuffer* _buffer;
nframes_t _overlen;
Sample _peak;
float _peak_db;
uint32_t _short_overs;
uint32_t _long_overs;
bool _own_buffer;
void (*_mixdown)(const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool);
static void default_mixdown (const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool);
static nframes_t _long_over_length;
static nframes_t _short_over_length;
};
} // namespace ARDOUR
#endif /* __ardour_base_audio_port_h__ */

View File

@ -0,0 +1,67 @@
/*
Copyright (C) 2002 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: port.h 712 2006-07-28 01:08:57Z drobilla $
*/
#ifndef __ardour_base_midi_port_h__
#define __ardour_base_midi_port_h__
#include <sigc++/signal.h>
#include <pbd/failed_constructor.h>
#include <ardour/ardour.h>
#include <ardour/port.h>
#include <ardour/midi_buffer.h>
namespace ARDOUR {
class MidiEngine;
class BaseMidiPort : public virtual Port {
public:
virtual ~BaseMidiPort();
DataType type() const { return DataType::MIDI; }
Buffer& get_buffer() {
assert (_buffer);
return *_buffer;
}
MidiBuffer& get_midi_buffer() {
assert (_buffer);
return *_buffer;
}
size_t capacity() { return _buffer->capacity(); }
size_t size() { return _buffer->size(); }
void set_mixdown_function (void (*func)(const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool));
protected:
BaseMidiPort (const std::string& name, Flags);
MidiBuffer* _buffer;
bool _own_buffer;
void (*_mixdown)(const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool);
static void default_mixdown (const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool);
};
} // namespace ARDOUR
#endif /* __ardour_base_midi_port_h__ */

View File

@ -0,0 +1,92 @@
/*
Copyright (C) 2006 Paul Davis
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_buffer_h__
#define __ardour_buffer_h__
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <boost/utility.hpp>
#include <ardour/types.h>
#include <ardour/data_type.h>
#include <ardour/runtime_functions.h>
namespace ARDOUR {
/** A buffer of recordable/playable data.
*
* This is a datatype-agnostic base class for all buffers (there are no
* methods to actually access the data). This provides a way for code that
* doesn't care about the data type to still deal with buffers (which is
* why the base class can't be a template).
*
* To actually read/write buffer contents, use the appropriate derived class.
*/
class Buffer : public boost::noncopyable
{
public:
virtual ~Buffer() {}
/** Factory function */
static Buffer* create(DataType type, size_t capacity);
/** Maximum capacity of buffer.
* Note in some cases the entire buffer may not contain valid data, use size. */
size_t capacity() const { return _capacity; }
/** Amount of valid data in buffer. Use this over capacity almost always. */
size_t size() const { return _size; }
/** Type of this buffer.
* Based on this you can static cast a Buffer* to the desired type. */
DataType type() const { return _type; }
bool silent() const { return _silent; }
/** Reallocate the buffer used internally to handle at least @a size_t units of data.
*
* The buffer is not silent after this operation. the @a capacity argument
* passed to the constructor must have been non-zero.
*/
virtual void resize(size_t) = 0;
/** Clear (eg zero, or empty) buffer starting at TIME @a offset */
virtual void silence(nframes_t len, nframes_t offset=0) = 0;
/** Clear the entire buffer */
virtual void clear() { silence(_capacity, 0); }
virtual void read_from(const Buffer& src, nframes_t offset, nframes_t len) = 0;
protected:
Buffer(DataType type, size_t capacity)
: _type(type), _capacity(capacity), _size(0), _silent(true)
{}
DataType _type;
size_t _capacity;
size_t _size;
bool _silent;
};
} // namespace ARDOUR
#endif // __ardour_buffer_h__

View File

@ -0,0 +1,159 @@
/*
Copyright (C) 2006 Paul Davis
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_buffer_set_h__
#define __ardour_buffer_set_h__
#include <cassert>
#include <vector>
#include <ardour/chan_count.h>
#include <ardour/data_type.h>
namespace ARDOUR {
class Buffer;
class AudioBuffer;
class MidiBuffer;
class PortSet;
/** A set of buffers of various types.
*
* These are mainly accessed from Session and passed around as scratch buffers
* (eg as parameters to run() methods) to do in-place signal processing.
*
* There are two types of counts associated with a BufferSet - available,
* and the 'use count'. Available is the actual number of allocated buffers
* (and so is the maximum acceptable value for the use counts).
*
* The use counts are how things determine the form of their input and inform
* others the form of their output (eg what they did to the BufferSet).
* Setting the use counts is realtime safe.
*/
class BufferSet
{
public:
BufferSet();
~BufferSet();
void clear();
void attach_buffers(PortSet& ports);
void ensure_buffers(const ChanCount& count, size_t buffer_capacity);
void ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity);
const ChanCount& available() const { return _available; }
ChanCount& available() { return _available; }
const ChanCount& count() const { return _count; }
ChanCount& count() { return _count; }
void set_count(const ChanCount& count) { _count = count; }
size_t buffer_capacity(DataType type) const;
Buffer& get(DataType type, size_t i)
{
assert(i <= _count.get(type));
return *_buffers[type][i];
}
AudioBuffer& get_audio(size_t i)
{
return (AudioBuffer&)get(DataType::AUDIO, i);
}
MidiBuffer& get_midi(size_t i)
{
return (MidiBuffer&)get(DataType::MIDI, i);
}
void read_from(BufferSet& in, jack_nframes_t nframes, jack_nframes_t offset=0);
// ITERATORS
// FIXME: this is a filthy copy-and-paste mess
// FIXME: litter these with assertions
class audio_iterator {
public:
AudioBuffer& operator*() { return _set.get_audio(_index); }
AudioBuffer* operator->() { return &_set.get_audio(_index); }
audio_iterator& operator++() { ++_index; return *this; } // yes, prefix only
bool operator==(const audio_iterator& other) { return (_index == other._index); }
bool operator!=(const audio_iterator& other) { return (_index != other._index); }
private:
friend class BufferSet;
audio_iterator(BufferSet& list, size_t index) : _set(list), _index(index) {}
BufferSet& _set;
size_t _index;
};
audio_iterator audio_begin() { return audio_iterator(*this, 0); }
audio_iterator audio_end() { return audio_iterator(*this, _count.n_audio()); }
class iterator {
public:
Buffer& operator*() { return _set.get(_type, _index); }
Buffer* operator->() { return &_set.get(_type, _index); }
iterator& operator++() { ++_index; return *this; } // yes, prefix only
bool operator==(const iterator& other) { return (_index == other._index); }
bool operator!=(const iterator& other) { return (_index != other._index); }
iterator operator=(const iterator& other) { _set = other._set; _type = other._type; _index = other._index; return *this; }
private:
friend class BufferSet;
iterator(BufferSet& list, DataType type, size_t index)
: _set(list), _type(type), _index(index) {}
BufferSet& _set;
DataType _type;
size_t _index;
};
iterator begin(DataType type) { return iterator(*this, type, 0); }
iterator end(DataType type) { return iterator(*this, type, _count.get(type)); }
private:
typedef std::vector<Buffer*> BufferVec;
/// Vector of vectors, indexed by DataType
std::vector<BufferVec> _buffers;
/// Use counts (there may be more actual buffers than this)
ChanCount _count;
/// Available counts (number of buffers actually allocated)
ChanCount _available;
/// Whether we (don't) 'own' the contained buffers (otherwise we mirror a PortSet)
bool _is_mirror;
};
} // namespace ARDOUR
#endif // __ardour_buffer_set_h__

View File

@ -0,0 +1,73 @@
/*
Copyright (C) 2002-2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_bundle_h__
#define __ardour_bundle_h__
#include <string>
#include <sigc++/signal.h>
#include "ardour/data_type.h"
namespace ARDOUR {
typedef std::vector<std::string> PortList;
/**
* A set of `channels', each of which is associated with 0 or more JACK ports.
*/
class Bundle {
public:
Bundle () : _type (DataType::AUDIO) {}
Bundle (bool i) : _type (DataType::AUDIO), _ports_are_inputs (i) {}
Bundle (std::string const & n, bool i = true) : _name (n), _type (DataType::AUDIO), _ports_are_inputs (i) {}
virtual ~Bundle() {}
/**
* @return Number of channels that this Bundle has.
*/
virtual uint32_t nchannels () const = 0;
virtual const PortList& channel_ports (uint32_t) const = 0;
void set_name (std::string const & n) {
_name = n;
NameChanged ();
}
std::string name () const { return _name; }
sigc::signal<void> NameChanged;
void set_type (DataType t) { _type = t; }
DataType type () const { return _type; }
void set_ports_are_inputs () { _ports_are_inputs = true; }
void set_ports_are_outputs () { _ports_are_inputs = false; }
bool ports_are_inputs () const { return _ports_are_inputs; }
bool ports_are_outputs () const { return !_ports_are_inputs; }
private:
std::string _name;
ARDOUR::DataType _type;
bool _ports_are_inputs;
};
}
#endif /* __ardour_bundle_h__ */

View File

@ -0,0 +1,48 @@
/*
Copyright (C) 2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_ca_importable_source_h__
#define __ardour_ca_importable_source_h__
#include <pbd/failed_constructor.h>
#include <ardour/types.h>
#include <ardour/importable_source.h>
#include <appleutility/CAAudioFile.h>
namespace ARDOUR {
class CAImportableSource : public ImportableSource {
public:
CAImportableSource (const std::string& path);
virtual ~CAImportableSource();
nframes_t read (Sample* buffer, nframes_t nframes);
uint32_t channels() const;
nframes_t length() const;
nframes_t samplerate() const;
void seek (nframes_t pos);
protected:
mutable CAAudioFile af;
};
}
#endif /* __ardour_ca_importable_source_h__ */

View File

@ -0,0 +1,126 @@
/*
Copyright (C) 2006 Paul Davis
Author: Dave Robillard
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_chan_count_h__
#define __ardour_chan_count_h__
#include <ardour/data_type.h>
#include <cassert>
namespace ARDOUR {
/** A count of channels, possibly with many types.
*
* Operators are defined so this may safely be used as if it were a simple
* (single-typed) integer count of channels.
*/
class ChanCount {
public:
ChanCount() { reset(); }
// Convenience constructor for making single-typed streams (stereo, mono, etc)
ChanCount(DataType type, uint32_t channels)
{
reset();
set(type, channels);
}
void reset()
{
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
_counts[*t] = 0;
}
}
void set(DataType t, uint32_t count) { assert(t != DataType::NIL); _counts[t] = count; }
uint32_t get(DataType t) const { assert(t != DataType::NIL); return _counts[t]; }
inline uint32_t n_audio() const { return _counts[DataType::AUDIO]; }
inline void set_audio(uint32_t a) { _counts[DataType::AUDIO] = a; }
inline uint32_t n_midi() const { return _counts[DataType::MIDI]; }
inline void set_midi(uint32_t m) { _counts[DataType::MIDI] = m; }
uint32_t n_total() const
{
uint32_t ret = 0;
for (uint32_t i=0; i < DataType::num_types; ++i)
ret += _counts[i];
return ret;
}
bool operator==(const ChanCount& other) const
{
for (uint32_t i=0; i < DataType::num_types; ++i)
if (_counts[i] != other._counts[i])
return false;
return true;
}
bool operator!=(const ChanCount& other) const
{
return ! (*this == other);
}
bool operator<(const ChanCount& other) const
{
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
if (_counts[*t] > other._counts[*t]) {
return false;
}
}
return (*this != other);
}
bool operator<=(const ChanCount& other) const
{
return ( (*this < other) || (*this == other) );
}
bool operator>(const ChanCount& other) const
{
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
if (_counts[*t] < other._counts[*t]) {
return false;
}
}
return (*this != other);
}
bool operator>=(const ChanCount& other) const
{
return ( (*this > other) || (*this == other) );
}
static const ChanCount INFINITE;
static const ChanCount ZERO;
private:
uint32_t _counts[DataType::num_types];
};
} // namespace ARDOUR
#endif // __ardour_chan_count_h__

View File

@ -0,0 +1,45 @@
/*
Copyright (C) 2004 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_click_h__
#define __ardour_click_h__
#include <ardour/io.h>
namespace ARDOUR {
class ClickIO : public IO
{
public:
ClickIO (Session& s, const string& name,
int input_min = -1, int input_max = -1,
int output_min = -1, int output_max = -1)
: IO (s, name, input_min, input_max, output_min, output_max) {}
~ClickIO() {}
protected:
uint32_t pans_required () const { return 1; }
};
}; /* namespace ARDOUR */
#endif /*__ardour_click_h__ */

View File

@ -0,0 +1,106 @@
/*
Copyright (C) 1999 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_configuration_h__
#define __ardour_configuration_h__
#include <map>
#include <vector>
#include <sys/types.h>
#include <string>
#include <pbd/stateful.h>
#include <ardour/types.h>
#include <ardour/utils.h>
#include <ardour/configuration_variable.h>
class XMLNode;
namespace ARDOUR {
class Configuration : public PBD::Stateful
{
public:
Configuration();
virtual ~Configuration();
std::map<std::string,XMLNode> midi_ports;
void map_parameters (sigc::slot<void,const char*> theSlot);
int load_state ();
int save_state ();
/// calls Stateful::*instant_xml methods using
/// ARDOUR::user_config_directory for the directory argument
void add_instant_xml (XMLNode&);
XMLNode * instant_xml (const std::string& str);
int set_state (const XMLNode&);
XMLNode& get_state (void);
XMLNode& get_variables (sigc::slot<bool,ConfigVariableBase::Owner>, std::string which_node = "Config");
void set_variables (const XMLNode&, ConfigVariableBase::Owner owner);
void set_current_owner (ConfigVariableBase::Owner);
XMLNode* control_protocol_state () { return _control_protocol_state; }
sigc::signal<void,const char*> ParameterChanged;
/* define accessor methods */
#undef CONFIG_VARIABLE
#undef CONFIG_VARIABLE_SPECIAL
#define CONFIG_VARIABLE(Type,var,name,value) \
Type get_##var () const { return var.get(); } \
bool set_##var (Type val) { bool ret = var.set (val, current_owner); if (ret) { ParameterChanged (name); } return ret; }
#define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) \
Type get_##var () const { return var.get(); } \
bool set_##var (Type val) { bool ret = var.set (val, current_owner); if (ret) { ParameterChanged (name); } return ret; }
#include "ardour/configuration_vars.h"
#undef CONFIG_VARIABLE
#undef CONFIG_VARIABLE_SPECIAL
private:
/* declare variables */
#undef CONFIG_VARIABLE
#undef CONFIG_VARIABLE_SPECIAL
#define CONFIG_VARIABLE(Type,var,name,value) ConfigVariable<Type> var;
#define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) ConfigVariableWithMutation<Type> var;
#include "ardour/configuration_vars.h"
#undef CONFIG_VARIABLE
#undef CONFIG_VARIABLE_SPECIAL
ConfigVariableBase::Owner current_owner;
XMLNode* _control_protocol_state;
XMLNode& state (sigc::slot<bool,ConfigVariableBase::Owner>);
bool save_config_options_predicate (ConfigVariableBase::Owner owner);
};
extern Configuration *Config;
extern gain_t speed_quietning; /* see comment in configuration.cc */
} // namespace ARDOUR
#endif /* __ardour_configuration_h__ */

View File

@ -0,0 +1,184 @@
/*
Copyright (C) 2000-2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_configuration_variable_h__
#define __ardour_configuration_variable_h__
#include <sstream>
#include <ostream>
#include <iostream>
#include <pbd/xml++.h>
namespace ARDOUR {
class ConfigVariableBase {
public:
enum Owner {
Default = 0x1,
System = 0x2,
Config = 0x4,
Session = 0x8,
Interface = 0x10
};
ConfigVariableBase (std::string str) : _name (str), _owner (Default) {}
virtual ~ConfigVariableBase() {}
std::string name() const { return _name; }
Owner owner() const { return _owner; }
virtual void add_to_node (XMLNode& node) = 0;
virtual bool set_from_node (const XMLNode& node, Owner owner) = 0;
void show_stored_value (const std::string&);
static void set_show_stored_values (bool yn);
protected:
std::string _name;
Owner _owner;
static bool show_stores;
void notify ();
void miss ();
};
template<class T>
class ConfigVariable : public ConfigVariableBase
{
public:
ConfigVariable (std::string str) : ConfigVariableBase (str) {}
ConfigVariable (std::string str, T val) : ConfigVariableBase (str), value (val) {}
virtual bool set (T val, Owner owner = ARDOUR::ConfigVariableBase::Config) {
if (val == value) {
miss ();
return false;
}
value = val;
_owner = (ConfigVariableBase::Owner)(_owner |owner);
notify ();
return true;
}
T get() const {
return value;
}
void add_to_node (XMLNode& node) {
std::stringstream ss;
ss << value;
show_stored_value (ss.str());
XMLNode* child = new XMLNode ("Option");
child->add_property ("name", _name);
child->add_property ("value", ss.str());
node.add_child_nocopy (*child);
}
bool set_from_node (const XMLNode& node, Owner owner) {
if (node.name() == "Config") {
/* ardour.rc */
const XMLProperty* prop;
XMLNodeList nlist;
XMLNodeConstIterator niter;
XMLNode* child;
nlist = node.children();
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
child = *niter;
if (child->name() == "Option") {
if ((prop = child->property ("name")) != 0) {
if (prop->value() == _name) {
if ((prop = child->property ("value")) != 0) {
std::stringstream ss;
ss << prop->value();
ss >> value;
_owner = (ConfigVariableBase::Owner)(_owner |owner);
return true;
}
}
}
}
}
} else if (node.name() == "Options") {
/* session file */
XMLNodeList olist;
XMLNodeConstIterator oiter;
XMLNode* option;
const XMLProperty* opt_prop;
olist = node.children();
for (oiter = olist.begin(); oiter != olist.end(); ++oiter) {
option = *oiter;
if (option->name() == _name) {
if ((opt_prop = option->property ("val")) != 0) {
std::stringstream ss;
ss << opt_prop->value();
ss >> value;
_owner = (ConfigVariableBase::Owner)(_owner |owner);
return true;
}
}
}
}
return false;
}
protected:
virtual T get_for_save() { return value; }
T value;
};
template<class T>
class ConfigVariableWithMutation : public ConfigVariable<T>
{
public:
ConfigVariableWithMutation (std::string name, T val, T (*m)(T))
: ConfigVariable<T> (name, val), mutator (m) {}
bool set (T val, ConfigVariableBase::Owner owner) {
if (unmutated_value != val) {
unmutated_value = val;
return ConfigVariable<T>::set (mutator (val), owner);
}
return false;
}
protected:
virtual T get_for_save() { return unmutated_value; }
T unmutated_value;
T (*mutator)(T);
};
}
#endif /* __ardour_configuration_variable_h__ */

View File

@ -0,0 +1,176 @@
/*
Copyright (C) 2000-2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* IO connection */
CONFIG_VARIABLE (AutoConnectOption, output_auto_connect, "output-auto-connect", AutoConnectOption (0))
CONFIG_VARIABLE (AutoConnectOption, input_auto_connect, "input-auto-connect", AutoConnectOption (0))
CONFIG_VARIABLE (std::string, auditioner_output_left, "auditioner-output-left", "default")
CONFIG_VARIABLE (std::string, auditioner_output_right, "auditioner-output-right", "default")
/* MIDI and MIDI related */
CONFIG_VARIABLE (std::string, mtc_port_name, "mtc-port-name", "default")
CONFIG_VARIABLE (std::string, mmc_port_name, "mmc-port-name", "default")
CONFIG_VARIABLE (std::string, midi_port_name, "midi-port-name", "default")
CONFIG_VARIABLE (bool, trace_midi_input, "trace-midi-input", false)
CONFIG_VARIABLE (bool, trace_midi_output, "trace-midi-output", false)
CONFIG_VARIABLE (bool, send_mtc, "send-mtc", false)
CONFIG_VARIABLE (bool, send_mmc, "send-mmc", true)
CONFIG_VARIABLE (bool, mmc_control, "mmc-control", true)
CONFIG_VARIABLE (bool, midi_feedback, "midi-feedback", false)
CONFIG_VARIABLE (uint8_t, mmc_receive_device_id, "mmc-receive-device-id", 0)
CONFIG_VARIABLE (uint8_t, mmc_send_device_id, "mmc-send-device-id", 0)
/* control surfaces */
CONFIG_VARIABLE (uint32_t, feedback_interval_ms, "feedback-interval-ms", 100)
CONFIG_VARIABLE (bool, use_tranzport, "use-tranzport", false)
CONFIG_VARIABLE (std::string, mackie_emulation, "mackie-emulation", "mcu")
CONFIG_VARIABLE (RemoteModel, remote_model, "remote-model", MixerOrdered)
/* disk operations */
CONFIG_VARIABLE (uint32_t, minimum_disk_io_bytes, "minimum-disk-io-bytes", 1024 * 256)
CONFIG_VARIABLE (float, audio_track_buffer_seconds, "track-buffer-seconds", 5.0)
CONFIG_VARIABLE (float, midi_track_buffer_seconds, "midi-track-buffer-seconds", 1.0)
CONFIG_VARIABLE (uint32_t, disk_choice_space_threshold, "disk-choice-space-threshold", 57600000)
CONFIG_VARIABLE (SampleFormat, native_file_data_format, "native-file-data-format", ARDOUR::FormatFloat)
CONFIG_VARIABLE (HeaderFormat, native_file_header_format, "native-file-header-format", ARDOUR::WAVE)
CONFIG_VARIABLE (bool, auto_analyse_audio, "auto-analyse-audio", false)
/* OSC */
CONFIG_VARIABLE (uint32_t, osc_port, "osc-port", 3819)
CONFIG_VARIABLE (bool, use_osc, "use-osc", false)
/* crossfades */
CONFIG_VARIABLE (CrossfadeModel, xfade_model, "xfade-model", FullCrossfade)
CONFIG_VARIABLE (bool, auto_xfade, "auto-xfade", true)
CONFIG_VARIABLE (float, short_xfade_seconds, "short-xfade-seconds", 0.015)
CONFIG_VARIABLE (bool, xfades_active, "xfades-active", true)
CONFIG_VARIABLE (bool, xfades_visible, "xfades-visible", true)
CONFIG_VARIABLE (uint32_t, destructive_xfade_msecs, "destructive-xfade-msecs", 2)
/* editing related */
CONFIG_VARIABLE (EditMode, edit_mode, "edit-mode", Slide)
CONFIG_VARIABLE (LayerModel, layer_model, "layer-model", MoveAddHigher)
CONFIG_VARIABLE (bool, link_region_and_track_selection, "link-region-and-track-selection", false)
CONFIG_VARIABLE (std::string, keyboard_layout_name, "keyboard-layout-name", "ansi")
/* monitoring, mute, solo etc */
CONFIG_VARIABLE (bool, mute_affects_pre_fader, "mute-affects-pre-fader", true)
CONFIG_VARIABLE (bool, mute_affects_post_fader, "mute-affects-post-fader", true)
CONFIG_VARIABLE (bool, mute_affects_control_outs, "mute-affects-control-outs", true)
CONFIG_VARIABLE (bool, mute_affects_main_outs, "mute-affects-main-outs", true)
CONFIG_VARIABLE (MonitorModel, monitoring_model, "monitoring-model", ExternalMonitoring)
CONFIG_VARIABLE (SoloModel, solo_model, "solo-model", InverseMute)
CONFIG_VARIABLE (bool, solo_latched, "solo-latched", true)
CONFIG_VARIABLE (bool, latched_record_enable, "latched-record-enable", false)
CONFIG_VARIABLE (bool, all_safe, "all-safe", false)
CONFIG_VARIABLE (bool, show_solo_mutes, "show-solo-mutes", false)
CONFIG_VARIABLE (bool, tape_machine_mode, "tape-machine-mode", false)
/* click */
CONFIG_VARIABLE (bool, clicking, "clicking", false)
CONFIG_VARIABLE (std::string, click_sound, "click-sound", "")
CONFIG_VARIABLE (std::string, click_emphasis_sound, "click-emphasis-sound", "")
/* transport control and related */
CONFIG_VARIABLE (bool, auto_play, "auto-play", false)
CONFIG_VARIABLE (bool, auto_return, "auto-return", false)
CONFIG_VARIABLE (bool, auto_input, "auto-input", true)
CONFIG_VARIABLE (bool, punch_in, "punch-in", false)
CONFIG_VARIABLE (bool, punch_out, "punch-out", false)
CONFIG_VARIABLE (bool, plugins_stop_with_transport, "plugins-stop-with-transport", false)
CONFIG_VARIABLE (bool, do_not_record_plugins, "do-not-record-plugins", false)
CONFIG_VARIABLE (bool, stop_recording_on_xrun, "stop-recording-on-xrun", false)
CONFIG_VARIABLE (bool, create_xrun_marker, "create-xrun-marker", true)
CONFIG_VARIABLE (bool, stop_at_session_end, "stop-at-session-end", true)
CONFIG_VARIABLE (bool, seamless_loop, "seamless-loop", false)
CONFIG_VARIABLE (nframes_t, preroll, "preroll", 0)
CONFIG_VARIABLE (nframes_t, postroll, "postroll", 0)
CONFIG_VARIABLE (float, rf_speed, "rf-speed", 2.0f)
CONFIG_VARIABLE (float, shuttle_speed_factor, "shuttle-speed-factor", 1.0f)
CONFIG_VARIABLE (float, shuttle_speed_threshold, "shuttle-speed-threshold", 5.0f)
CONFIG_VARIABLE (SlaveSource, slave_source, "slave-source", None)
CONFIG_VARIABLE (ShuttleBehaviour, shuttle_behaviour, "shuttle-behaviour", Sprung)
CONFIG_VARIABLE (ShuttleUnits, shuttle_units, "shuttle-units", Percentage)
CONFIG_VARIABLE (bool, quieten_at_speed, "quieten-at-speed", true)
CONFIG_VARIABLE (bool, primary_clock_delta_edit_cursor, "primary-clock-delta-edit-cursor", false)
CONFIG_VARIABLE (bool, secondary_clock_delta_edit_cursor, "secondary-clock-delta-edit-cursor", false)
CONFIG_VARIABLE (bool, show_track_meters, "show-track-meters", true)
/* timecode and sync */
CONFIG_VARIABLE (bool, jack_time_master, "jack-time-master", true)
CONFIG_VARIABLE (SmpteFormat, smpte_format, "smpte-format", smpte_30)
CONFIG_VARIABLE (bool, use_video_sync, "use-video-sync", false)
CONFIG_VARIABLE (bool, timecode_source_is_synced, "timecode-source-is-synced", true)
CONFIG_VARIABLE (float, video_pullup, "video-pullup", 0.0f)
/* metering */
CONFIG_VARIABLE (float, meter_hold, "meter-hold", 100.0f)
CONFIG_VARIABLE (float, meter_falloff, "meter-falloff", 27.0f)
CONFIG_VARIABLE (nframes_t, over_length_short, "over-length-short", 2)
CONFIG_VARIABLE (nframes_t, over_length_long, "over-length-long", 10)
/* miscellany */
CONFIG_VARIABLE (bool, hiding_groups_deactivates_groups, "hiding-groups-deactivates-groups", true)
CONFIG_VARIABLE (bool, verify_remove_last_capture, "verify-remove-last-capture", true)
CONFIG_VARIABLE (bool, no_new_session_dialog, "no-new-session-dialog", false)
CONFIG_VARIABLE (bool, use_vst, "use-vst", true)
CONFIG_VARIABLE (uint32_t, subframes_per_frame, "subframes-per-frame", 100)
CONFIG_VARIABLE (bool, save_history, "save-history", true)
CONFIG_VARIABLE (int32_t, saved_history_depth, "save-history-depth", 20)
CONFIG_VARIABLE (int32_t, history_depth, "history-depth", 20)
CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", false)
CONFIG_VARIABLE (bool, periodic_safety_backups, "periodic-safety-backups", true)
CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-backup-interval", 120)
CONFIG_VARIABLE (float, automation_interval, "automation-interval", 50)
CONFIG_VARIABLE (bool, sync_all_route_ordering, "sync-all-route-ordering", true)
CONFIG_VARIABLE (bool, only_copy_imported_files, "only-copy-imported-files", true)
CONFIG_VARIABLE (std::string, keyboard_layout, "keyboard-layout", "ansi")
CONFIG_VARIABLE (std::string, default_bindings, "default-bindings", "ardour")
CONFIG_VARIABLE (bool, default_narrow_ms, "default-narrow_ms", false)
CONFIG_VARIABLE (bool, rubberbanding_snaps_to_grid, "rubberbanding-snaps-to-grid", false)
CONFIG_VARIABLE (long, font_scale, "font-scale", 102400)
/* denormal management */
CONFIG_VARIABLE (bool, denormal_protection, "denormal-protection", false)
CONFIG_VARIABLE (DenormalModel, denormal_model, "denormal-model", DenormalNone)
/* BWAV */
CONFIG_VARIABLE (string, bwf_country_code, "bwf-country-code", "US")
CONFIG_VARIABLE (string, bwf_organization_code, "bwf-organization-code", "US")
/* these variables have custom set() methods (e.g. path globbing) */
CONFIG_VARIABLE_SPECIAL(Glib::ustring, raid_path, "raid-path", "", path_expand)

View File

@ -0,0 +1,93 @@
/*
Copyright (C) 2000-2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef ardour_control_protocol_manager_h
#define ardour_control_protocol_manager_h
#include <string>
#include <list>
#include <sigc++/sigc++.h>
#include <glibmm/thread.h>
#include <pbd/stateful.h>
namespace ARDOUR {
class ControlProtocol;
class ControlProtocolDescriptor;
class Session;
struct ControlProtocolInfo {
ControlProtocolDescriptor* descriptor;
ControlProtocol* protocol;
std::string name;
std::string path;
bool requested;
bool mandatory;
bool supports_feedback;
XMLNode* state;
ControlProtocolInfo() : descriptor (0), protocol (0), state (0) {}
~ControlProtocolInfo() { if (state) { delete state; } }
};
class ControlProtocolManager : public sigc::trackable, public PBD::Stateful
{
public:
ControlProtocolManager ();
~ControlProtocolManager ();
static ControlProtocolManager& instance() { return *_instance; }
void set_session (Session&);
void discover_control_protocols ();
void foreach_known_protocol (sigc::slot<void,const ControlProtocolInfo*>);
void load_mandatory_protocols ();
ControlProtocol* instantiate (ControlProtocolInfo&);
int teardown (ControlProtocolInfo&);
std::list<ControlProtocolInfo*> control_protocol_info;
static const std::string state_node_name;
void set_protocol_states (const XMLNode&);
int set_state (const XMLNode&);
XMLNode& get_state (void);
private:
static ControlProtocolManager* _instance;
Session* _session;
Glib::Mutex protocols_lock;
std::list<ControlProtocol*> control_protocols;
void drop_session ();
int control_protocol_discover (std::string path);
ControlProtocolDescriptor* get_descriptor (std::string path);
ControlProtocolInfo* cpi_by_name (std::string);
};
} // namespace
#endif // ardour_control_protocol_manager_h

View File

@ -0,0 +1,42 @@
/*
Copyright (C) 2007 Tim Mayberry
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef ARDOUR_CONTROL_PROTOCOL_SEARCH_PATH_INCLUDED
#define ARDOUR_CONTROL_PROTOCOL_SEARCH_PATH_INCLUDED
#include <pbd/search_path.h>
namespace ARDOUR {
using PBD::SearchPath;
/**
* return a SearchPath containing directories in which to look for
* control surface plugins.
*
* If ARDOUR_SURFACES_PATH is defined then the SearchPath returned
* will contain only those directories specified in it, otherwise it will
* contain the user and system directories which may contain control
* surface plugins.
*/
SearchPath control_protocol_search_path ();
} // namespace ARDOUR
#endif

View File

@ -0,0 +1,57 @@
/*
Copyright (C) 2000 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __coreaudio_source_h__
#define __coreaudio_source_h__
#include <appleutility/CAAudioFile.h>
#include <ardour/audiofilesource.h>
namespace ARDOUR {
class CoreAudioSource : public AudioFileSource {
public:
CoreAudioSource (ARDOUR::Session&, const XMLNode&);
CoreAudioSource (ARDOUR::Session&, const string& path, int chn, Flag);
~CoreAudioSource ();
float sample_rate() const;
int update_header (nframes_t when, struct tm&, time_t);
int flush_header () {return 0;};
void set_header_timeline_position () {};
static int get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg);
protected:
nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const;
nframes_t write_unlocked (Sample *dst, nframes_t cnt) { return 0; }
private:
mutable CAAudioFile af;
uint16_t n_channels;
void init ();
int safe_read (Sample*, nframes_t start, nframes_t cnt, AudioBufferList&) const;
};
}; /* namespace ARDOUR */
#endif /* __coreaudio_source_h__ */

View File

@ -0,0 +1,179 @@
/*
Copyright (C) 2000 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_overlap_h__
#define __ardour_overlap_h__
#include <vector>
#include <algorithm>
#include <boost/shared_ptr.hpp>
#include <sigc++/signal.h>
#include <pbd/undo.h>
#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/curve.h>
#include <ardour/audioregion.h>
#include <ardour/crossfade_compare.h>
namespace ARDOUR {
class AudioRegion;
class Playlist;
class Crossfade : public ARDOUR::AudioRegion
{
public:
class NoCrossfadeHere: std::exception {
public:
virtual const char *what() const throw() { return "no crossfade should be constructed here"; }
};
/* constructor for "fixed" xfades at each end of an internal overlap */
Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out,
nframes_t position,
nframes_t initial_length,
AnchorPoint);
/* constructor for xfade between two regions that are overlapped in any way
except the "internal" case.
*/
Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out, CrossfadeModel, bool active);
/* copy constructor to copy a crossfade with new regions. used (for example)
when a playlist copy is made
*/
Crossfade (boost::shared_ptr<Crossfade>, boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>);
/* the usual XML constructor */
Crossfade (const Playlist&, XMLNode&);
virtual ~Crossfade();
bool operator== (const ARDOUR::Crossfade&);
XMLNode& get_state (void);
int set_state (const XMLNode&);
boost::shared_ptr<ARDOUR::AudioRegion> in() const { return _in; }
boost::shared_ptr<ARDOUR::AudioRegion> out() const { return _out; }
nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, nframes_t position, nframes_t cnt,
uint32_t chan_n,
nframes_t read_frames = 0,
nframes_t skip_frames = 0) const;
bool refresh ();
uint32_t upper_layer () const {
return std::max (_in->layer(), _out->layer());
}
uint32_t lower_layer () const {
return std::min (_in->layer(), _out->layer());
}
bool involves (boost::shared_ptr<ARDOUR::AudioRegion> region) const {
return _in == region || _out == region;
}
bool involves (boost::shared_ptr<ARDOUR::AudioRegion> a, boost::shared_ptr<ARDOUR::AudioRegion> b) const {
return (_in == a && _out == b) || (_in == b && _out == a);
}
nframes_t overlap_length() const;
void invalidate();
sigc::signal<void,boost::shared_ptr<Region> > Invalidated;
sigc::signal<void,Change> StateChanged;
bool covers (nframes_t frame) const {
return _position <= frame && frame < _position + _length;
}
OverlapType coverage (nframes_t start, nframes_t end) const;
static void set_buffer_size (nframes_t);
bool active () const { return _active; }
void set_active (bool yn);
bool following_overlap() const { return _follow_overlap; }
bool can_follow_overlap() const;
void set_follow_overlap (bool yn);
AutomationList& fade_in() { return _fade_in; }
AutomationList& fade_out() { return _fade_out; }
nframes_t set_length (nframes_t);
bool is_dependent() const { return true; }
bool depends_on (boost::shared_ptr<Region> other) const {
return other == _in || other == _out;
}
static nframes_t short_xfade_length() { return _short_xfade_length; }
static void set_short_xfade_length (nframes_t n);
static Change ActiveChanged;
static Change FollowOverlapChanged;
private:
friend struct CrossfadeComparePtr;
friend class AudioPlaylist;
static nframes_t _short_xfade_length;
boost::shared_ptr<ARDOUR::AudioRegion> _in;
boost::shared_ptr<ARDOUR::AudioRegion> _out;
bool _active;
bool _in_update;
OverlapType overlap_type;
AnchorPoint _anchor_point;
bool _follow_overlap;
bool _fixed;
int32_t layer_relation;
mutable AutomationList _fade_in;
mutable AutomationList _fade_out;
static Sample* crossfade_buffer_out;
static Sample* crossfade_buffer_in;
void initialize ();
int compute (boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>, CrossfadeModel);
bool update ();
protected:
nframes_t read_raw_internal (Sample*, nframes_t, nframes_t) const;
};
} // namespace ARDOUR
#endif /* __ardour_overlap_h__ */

View File

@ -0,0 +1,42 @@
/*
Copyright (C) 2003 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_crossfade_compare_h__
#define __ardour_crossfade_compare_h__
/* this exists so that playlist.h doesn't have to include crossfade.h
*/
namespace ARDOUR {
class Crossfade;
struct CrossfadeComparePtr {
bool operator() (const Crossfade *a, const Crossfade *b) const;
};
enum AnchorPoint {
StartOfIn,
EndOfIn,
EndOfOut
};
}
#endif /* __ardour_crossfade_compare_h__ */

View File

@ -0,0 +1,62 @@
/*
Copyright (C) 2001-2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_curve_h__
#define __ardour_curve_h__
#include <sys/types.h>
#include <boost/utility.hpp>
#include <sigc++/signal.h>
#include <glibmm/thread.h>
#include <pbd/undo.h>
#include <list>
#include <algorithm>
#include <ardour/automation_event.h>
namespace ARDOUR {
class Curve : public boost::noncopyable
{
public:
Curve (const AutomationList& al);
bool rt_safe_get_vector (double x0, double x1, float *arg, int32_t veclen);
void get_vector (double x0, double x1, float *arg, int32_t veclen);
void solve ();
private:
double unlocked_eval (double where);
double multipoint_eval (double x);
void _get_vector (double x0, double x1, float *arg, int32_t veclen);
void on_list_dirty() { _dirty = true; }
bool _dirty;
const AutomationList& _list;
};
} // namespace ARDOUR
extern "C" {
void curve_get_vector_from_c (void *arg, double, double, float*, int32_t);
}
#endif /* __ardour_curve_h__ */

View File

@ -0,0 +1,50 @@
/*
Copyright (C) 2002 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_cycle_timer_h__
#define __ardour_cycle_timer_h__
#include <string>
#include <iostream>
#include <ardour/cycles.h>
class CycleTimer {
private:
static float cycles_per_usec;
cycles_t _entry;
cycles_t _exit;
std::string _name;
public:
CycleTimer(std::string name) : _name (name){
if (cycles_per_usec == 0) {
cycles_per_usec = get_mhz ();
}
_entry = get_cycles();
}
~CycleTimer() {
_exit = get_cycles();
std::cerr << _name << ": " << (float) (_exit - _entry) / cycles_per_usec << " (" << _entry << ", " << _exit << ')' << endl;
}
static float get_mhz ();
};
#endif /* __ardour_cycle_timer_h__ */

221
libs/ardour/ardour/cycles.h Normal file
View File

@ -0,0 +1,221 @@
/*
Copyright (C) 2001 Paul Davis
Code derived from various headers from the Linux kernel
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_cycles_h__
#define __ardour_cycles_h__
#include <stdint.h>
#if defined(__i386__) || defined(__x86_64__)
/*
* Standard way to access the cycle counter on i586+ CPUs.
* Currently only used on SMP.
*
* If you really have a SMP machine with i486 chips or older,
* compile for that, and this will just always return zero.
* That's ok, it just means that the nicer scheduling heuristics
* won't work for you.
*
* We only use the low 32 bits, and we'd simply better make sure
* that we reschedule before that wraps. Scheduling at least every
* four billion cycles just basically sounds like a good idea,
* regardless of how fast the machine is.
*/
typedef uint64_t cycles_t;
extern cycles_t cacheflush_time;
#define rdtscll(val) \
__asm__ __volatile__("rdtsc" : "=A" (val))
static inline cycles_t get_cycles (void)
{
uint32_t long ret;
rdtscll(ret);
return ret;
}
#elif defined(__powerpc__)
#define CPU_FTR_601 0x00000100
typedef uint32_t cycles_t;
/*
* For the "cycle" counter we use the timebase lower half.
* Currently only used on SMP.
*/
extern cycles_t cacheflush_time;
static inline cycles_t get_cycles(void)
{
cycles_t ret = 0;
__asm__ __volatile__(
"98: mftb %0\n"
"99:\n"
".section __ftr_fixup,\"a\"\n"
" .long %1\n"
" .long 0\n"
" .long 98b\n"
" .long 99b\n"
".previous"
: "=r" (ret) : "i" (CPU_FTR_601));
return ret;
}
#elif defined(__ia64__)
/* ia64 */
typedef uint32_t cycles_t;
static inline cycles_t
get_cycles (void)
{
cycles_t ret;
__asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret));
return ret;
}
#elif defined(__alpha__)
/* alpha */
/*
* Standard way to access the cycle counter.
* Currently only used on SMP for scheduling.
*
* Only the low 32 bits are available as a continuously counting entity.
* But this only means we'll force a reschedule every 8 seconds or so,
* which isn't an evil thing.
*/
typedef uint32_t cycles_t;
static inline cycles_t get_cycles (void)
{
cycles_t ret;
__asm__ __volatile__ ("rpcc %0" : "=r"(ret));
return ret;
}
#elif defined(__s390__)
/* s390 */
typedef uint32_t long cycles_t;
static inline cycles_t get_cycles(void)
{
cycles_t cycles;
__asm__("stck 0(%0)" : : "a" (&(cycles)) : "memory", "cc");
return cycles >> 2;
}
#elif defined(__hppa__)
/* hppa/parisc */
#define mfctl(reg) ({ \
uint32_t cr; \
__asm__ __volatile__( \
"mfctl " #reg ",%0" : \
"=r" (cr) \
); \
cr; \
})
typedef uint32_t cycles_t;
static inline cycles_t get_cycles (void)
{
return mfctl(16);
}
#elif defined(__mips__)
/* mips/mipsel */
/*
* Standard way to access the cycle counter.
* Currently only used on SMP for scheduling.
*
* Only the low 32 bits are available as a continuously counting entity.
* But this only means we'll force a reschedule every 8 seconds or so,
* which isn't an evil thing.
*
* We know that all SMP capable CPUs have cycle counters.
*/
#define __read_32bit_c0_register(source, sel) \
({ int __res; \
if (sel == 0) \
__asm__ __volatile__( \
"mfc0\t%0, " #source "\n\t" \
: "=r" (__res)); \
else \
__asm__ __volatile__( \
".set\tmips32\n\t" \
"mfc0\t%0, " #source ", " #sel "\n\t" \
".set\tmips0\n\t" \
: "=r" (__res)); \
__res; \
})
/* #define CP0_COUNT $9 */
#define read_c0_count() __read_32bit_c0_register($9, 0)
typedef uint32_t cycles_t;
static inline cycles_t get_cycles (void)
{
return read_c0_count();
}
/* begin mach */
#elif defined(__APPLE__)
#include <CoreAudio/HostTime.h>
typedef UInt64 cycles_t;
static inline cycles_t get_cycles (void)
{
UInt64 time = AudioGetCurrentHostTime();
return AudioConvertHostTimeToNanos(time);
}
/* end mach */
#else
/* debian: sparc, arm, m68k */
#warning You are compiling libardour on a platform for which ardour/cycles.h needs work
#include <sys/time.h>
typedef long cycles_t;
extern cycles_t cacheflush_time;
static inline cycles_t get_cycles(void)
{
struct timeval tv;
gettimeofday (&tv, NULL);
return tv.tv_usec;
}
#endif
#endif /* __ardour_cycles_h__ */

33
libs/ardour/ardour/dB.h Normal file
View File

@ -0,0 +1,33 @@
/*
Copyright (C) 2001 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_dB_h__
#define __ardour_dB_h__
#include <pbd/fastlog.h>
static inline float dB_to_coefficient (float dB) {
return dB > -318.8f ? pow (10.0f, dB * 0.05f) : 0.0f;
}
static inline float coefficient_to_dB (float coeff) {
return 20.0f * fast_log10 (coeff);
}
#endif /* __ardour_dB_h__ */

View File

@ -0,0 +1,130 @@
/*
Copyright (C) 2006 Paul Davis
Author: Dave Robillard
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_data_type_h__
#define __ardour_data_type_h__
#include <string>
#include <jack/jack.h>
namespace ARDOUR {
/** A type of Data Ardour is capable of processing.
*
* The majority of this class is dedicated to conversion to and from various
* other type representations, simple comparison between then, etc. This code
* is deliberately 'ugly' so other code doesn't have to be.
*/
class DataType
{
public:
/** Numeric symbol for this DataType.
*
* Castable to int for use as an array index (e.g. by ChanCount).
* Note this means NIL is (ntypes-1) and guaranteed to change when
* types are added, so this number is NOT suitable for serialization,
* network, or binary anything.
*
* WARNING: The number of non-NIL entries here must match num_types.
*/
enum Symbol {
AUDIO = 0,
MIDI = 1,
NIL = 2,
};
/** Number of types (not including NIL).
* WARNING: make sure this matches Symbol!
*/
static const uint32_t num_types = 2;
DataType(const Symbol& symbol)
: _symbol(symbol)
{}
/** Construct from a string (Used for loading from XML and Ports)
* The string can be as in an XML file (eg "audio" or "midi"), or a
* Jack type string (from jack_port_type) */
DataType(const std::string& str)
: _symbol(NIL) {
if (str == "audio" || str == JACK_DEFAULT_AUDIO_TYPE)
_symbol = AUDIO;
else if (str == "midi" || str == JACK_DEFAULT_MIDI_TYPE)
_symbol = MIDI;
}
/** Get the Jack type this DataType corresponds to */
const char* to_jack_type() const {
switch (_symbol) {
case AUDIO: return JACK_DEFAULT_AUDIO_TYPE;
case MIDI: return JACK_DEFAULT_MIDI_TYPE;
default: return "";
}
}
/** Inverse of the from-string constructor */
const char* to_string() const {
switch (_symbol) {
case AUDIO: return "audio";
case MIDI: return "midi";
default: return "unknown"; // reeeally shouldn't ever happen
}
}
inline operator uint32_t() const { return (uint32_t)_symbol; }
/** DataType iterator, for writing generic loops that iterate over all
* available types.
*/
class iterator {
public:
iterator(uint32_t index) : _index(index) {}
DataType operator*() { return DataType((Symbol)_index); }
iterator& operator++() { ++_index; return *this; } // yes, prefix only
bool operator==(const iterator& other) { return (_index == other._index); }
bool operator!=(const iterator& other) { return (_index != other._index); }
private:
friend class DataType;
uint32_t _index;
};
static iterator begin() { return iterator(0); }
static iterator end() { return iterator(num_types); }
bool operator==(const Symbol symbol) { return (_symbol == symbol); }
bool operator!=(const Symbol symbol) { return (_symbol != symbol); }
bool operator==(const DataType other) { return (_symbol == other._symbol); }
bool operator!=(const DataType other) { return (_symbol != other._symbol); }
private:
Symbol _symbol; // could be const if not for the string constructor
};
} // namespace ARDOUR
#endif // __ardour_data_type_h__

View File

@ -0,0 +1,23 @@
#ifndef __ardour_directory_names_h__
#define __ardour_directory_names_h__
#include <string>
namespace ARDOUR {
extern const char* const old_sound_dir_name;
extern const char* const sound_dir_name;
extern const char* const midi_dir_name;
extern const char* const dead_sound_dir_name;
extern const char* const dead_midi_dir_name;
extern const char* const interchange_dir_name;
extern const char* const peak_dir_name;
extern const char* const export_dir_name;
extern const char* const templates_dir_name;
extern const char* const surfaces_dir_name;
extern const char* const user_config_dir_name;
};
#endif

View File

@ -0,0 +1,308 @@
/*
Copyright (C) 2000-2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_diskstream_h__
#define __ardour_diskstream_h__
#include <sigc++/signal.h>
#include <cmath>
#include <string>
#include <queue>
#include <map>
#include <vector>
#include <time.h>
#include <pbd/fastlog.h>
#include <pbd/ringbufferNPT.h>
#include <pbd/stateful.h>
#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/configuration.h>
#include <ardour/session.h>
#include <ardour/route_group.h>
#include <ardour/route.h>
#include <ardour/port.h>
#include <ardour/utils.h>
struct tm;
namespace ARDOUR {
class AudioEngine;
class Send;
class Session;
class Playlist;
class IO;
class Diskstream : public SessionObject
{
public:
enum Flag {
Recordable = 0x1,
Hidden = 0x2,
Destructive = 0x4
};
Diskstream (Session &, const string& name, Flag f = Recordable);
Diskstream (Session &, const XMLNode&);
virtual ~Diskstream();
bool set_name (const string& str);
ARDOUR::IO* io() const { return _io; }
void set_io (ARDOUR::IO& io);
virtual float playback_buffer_load() const = 0;
virtual float capture_buffer_load() const = 0;
void set_flag (Flag f) { _flags = Flag (_flags | f); }
void unset_flag (Flag f) { _flags = Flag (_flags & ~f); }
AlignStyle alignment_style() const { return _alignment_style; }
void set_align_style (AlignStyle);
void set_persistent_align_style (AlignStyle a) { _persistent_alignment_style = a; }
nframes_t roll_delay() const { return _roll_delay; }
void set_roll_delay (nframes_t);
bool record_enabled() const { return g_atomic_int_get (&_record_enabled); }
virtual void set_record_enabled (bool yn) = 0;
bool destructive() const { return _flags & Destructive; }
virtual int set_destructive (bool yn) { return -1; }
virtual bool can_become_destructive (bool& requires_bounce) const { return false; }
bool hidden() const { return _flags & Hidden; }
bool recordable() const { return _flags & Recordable; }
bool reversed() const { return _actual_speed < 0.0f; }
double speed() const { return _visible_speed; }
virtual void punch_in() {}
virtual void punch_out() {}
void set_speed (double);
void non_realtime_set_speed ();
virtual void non_realtime_locate (nframes_t location) {};
virtual void playlist_modified ();
boost::shared_ptr<Playlist> playlist () { return _playlist; }
virtual int use_playlist (boost::shared_ptr<Playlist>);
virtual int use_new_playlist () = 0;
virtual int use_copy_playlist () = 0;
nframes_t current_capture_start() const { return capture_start_frame; }
nframes_t current_capture_end() const { return capture_start_frame + capture_captured; }
nframes_t get_capture_start_frame (uint32_t n=0);
nframes_t get_captured_frames (uint32_t n=0);
ChanCount n_channels() { return _n_channels; }
static nframes_t disk_io_frames() { return disk_io_chunk_frames; }
static void set_disk_io_chunk_frames (uint32_t n) { disk_io_chunk_frames = n; }
/* Stateful */
virtual XMLNode& get_state(void) = 0;
virtual int set_state(const XMLNode& node) = 0;
virtual void monitor_input (bool) {}
nframes_t capture_offset() const { return _capture_offset; }
virtual void set_capture_offset ();
bool slaved() const { return _slaved; }
void set_slaved(bool yn) { _slaved = yn; }
int set_loop (Location *loc);
std::list<boost::shared_ptr<Region> >& last_capture_regions () { return _last_capture_regions; }
void handle_input_change (IOChange, void *src);
void remove_region_from_last_capture (boost::weak_ptr<Region> wregion);
sigc::signal<void> RecordEnableChanged;
sigc::signal<void> SpeedChanged;
sigc::signal<void> ReverseChanged;
sigc::signal<void> PlaylistChanged;
sigc::signal<void> AlignmentStyleChanged;
sigc::signal<void,Location *> LoopSet;
static sigc::signal<void> DiskOverrun;
static sigc::signal<void> DiskUnderrun;
protected:
friend class Session;
/* the Session is the only point of access for these because they require
* that the Session is "inactive" while they are called.
*/
virtual void set_pending_overwrite (bool) = 0;
virtual int overwrite_existing_buffers () = 0;
virtual void set_block_size (nframes_t) = 0;
virtual int internal_playback_seek (nframes_t distance) = 0;
virtual int can_internal_playback_seek (nframes_t distance) = 0;
virtual int rename_write_sources () = 0;
virtual void reset_write_sources (bool, bool force = false) = 0;
virtual void non_realtime_input_change () = 0;
uint32_t read_data_count() const { return _read_data_count; }
uint32_t write_data_count() const { return _write_data_count; }
protected:
friend class Auditioner;
virtual int seek (nframes_t which_sample, bool complete_refill = false) = 0;
protected:
friend class Track;
virtual void prepare ();
virtual int process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input) = 0;
virtual bool commit (nframes_t nframes) = 0;
virtual void recover (); /* called if commit will not be called, but process was */
//private:
enum TransitionType {
CaptureStart = 0,
CaptureEnd
};
struct CaptureTransition {
TransitionType type;
nframes_t capture_val; ///< The start or end file frame position
};
/* The two central butler operations */
virtual int do_flush (Session::RunContext context, bool force = false) = 0;
virtual int do_refill () = 0;
/** For non-butler contexts (allocates temporary working buffers) */
virtual int do_refill_with_alloc() = 0;
/* XXX fix this redundancy ... */
virtual void playlist_changed (Change);
virtual void playlist_deleted (boost::weak_ptr<Playlist>);
virtual void transport_stopped (struct tm&, time_t, bool abort) = 0;
virtual void transport_looped (nframes_t transport_frame) = 0;
struct CaptureInfo {
uint32_t start;
uint32_t frames;
};
virtual void init (Flag);
virtual int use_new_write_source (uint32_t n=0) = 0;
virtual int find_and_use_playlist (const string&) = 0;
virtual void allocate_temporary_buffers () = 0;
virtual bool realtime_set_speed (double, bool global_change);
std::list<boost::shared_ptr<Region> > _last_capture_regions;
virtual int use_pending_capture_data (XMLNode& node) = 0;
virtual void get_input_sources () = 0;
virtual void check_record_status (nframes_t transport_frame, nframes_t nframes, bool can_record) = 0;
virtual void set_align_style_from_io() {}
virtual void setup_destructive_playlist () {}
virtual void use_destructive_playlist () {}
static nframes_t disk_io_chunk_frames;
std::vector<CaptureInfo*> capture_info;
Glib::Mutex capture_info_lock;
uint32_t i_am_the_modifier;
ARDOUR::IO* _io;
ChanCount _n_channels;
boost::shared_ptr<Playlist> _playlist;
mutable gint _record_enabled;
double _visible_speed;
double _actual_speed;
/* items needed for speed change logic */
bool _buffer_reallocation_required;
bool _seek_required;
bool force_refill;
nframes_t capture_start_frame;
nframes_t capture_captured;
bool was_recording;
nframes_t adjust_capture_position;
nframes_t _capture_offset;
nframes_t _roll_delay;
nframes_t first_recordable_frame;
nframes_t last_recordable_frame;
int last_possibly_recording;
AlignStyle _alignment_style;
bool _scrubbing;
bool _slaved;
bool _processed;
Location* loop_location;
nframes_t overwrite_frame;
off_t overwrite_offset;
bool pending_overwrite;
bool overwrite_queued;
IOChange input_change_pending;
nframes_t wrap_buffer_size;
nframes_t speed_buffer_size;
uint64_t last_phase;
uint64_t phi;
uint64_t target_phi;
nframes_t file_frame;
nframes_t playback_sample;
nframes_t playback_distance;
bool commit_should_unlock;
uint32_t _read_data_count;
uint32_t _write_data_count;
bool in_set_state;
AlignStyle _persistent_alignment_style;
bool first_input_change;
Glib::Mutex state_lock;
nframes_t scrub_start;
nframes_t scrub_buffer_size;
nframes_t scrub_offset;
sigc::connection ports_created_c;
sigc::connection plmod_connection;
sigc::connection plgone_connection;
Flag _flags;
};
}; /* namespace ARDOUR */
#endif /* __ardour_diskstream_h__ */

107
libs/ardour/ardour/export.h Normal file
View File

@ -0,0 +1,107 @@
/*
Copyright (C) 2000-2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_export_h__
#define __ardour_export_h__
#include <map>
#include <vector>
#include <string>
#include <sigc++/signal.h>
#include <sndfile.h>
#include <samplerate.h>
#include <ardour/ardour.h>
#include <ardour/gdither.h>
using std::map;
using std::vector;
using std::string;
using std::pair;
namespace ARDOUR
{
class Port;
typedef pair<Port *, uint32_t> PortChannelPair;
typedef map<uint32_t, vector<PortChannelPair> > ExportPortMap;
struct ExportSpecification : public SF_INFO, public sigc::trackable {
ExportSpecification();
~ExportSpecification ();
void init ();
void clear ();
int prepare (nframes_t blocksize, nframes_t frame_rate);
int process (nframes_t nframes);
/* set by the user */
string path;
nframes_t sample_rate;
int src_quality;
SNDFILE* out;
uint32_t channels;
ExportPortMap port_map;
nframes_t start_frame;
nframes_t end_frame;
GDitherType dither_type;
bool do_freewheel;
/* used exclusively during export */
nframes_t frame_rate;
GDither dither;
float* dataF;
float* dataF2;
float* leftoverF;
nframes_t leftover_frames;
nframes_t max_leftover_frames;
void* output_data;
nframes_t out_samples_max;
uint32_t sample_bytes;
uint32_t data_width;
nframes_t total_frames;
SF_INFO sfinfo;
SRC_DATA src_data;
SRC_STATE* src_state;
nframes_t pos;
sigc::connection freewheel_connection;
/* shared between UI thread and audio thread */
volatile float progress; /* audio thread sets this */
volatile bool stop; /* UI sets this */
volatile bool running; /* audio thread sets to false when export is done */
int status;
};
} // namespace ARDOUR
#endif /* __ardour_export_h__ */

View File

@ -0,0 +1,17 @@
#ifndef __ardour_filename_extensions_h__
#define __ardour_filename_extensions_h__
namespace ARDOUR {
extern const char* const template_suffix;
extern const char* const statefile_suffix;
extern const char* const pending_suffix;
extern const char* const peakfile_suffix;
extern const char* const backup_suffix;
extern const char* const temp_suffix;
extern const char* const history_suffix;
}
#endif

View File

@ -0,0 +1,50 @@
/*
Copyright (C) 2007 Tim Mayberry
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef ARDOUR_FILESYSTEM_PATHS_INCLUDED
#define ARDOUR_FILESYSTEM_PATHS_INCLUDED
#include <pbd/filesystem.h>
#include <pbd/search_path.h>
namespace ARDOUR {
using namespace PBD;
/**
* @return the path to the directory used to store user specific ardour
* configuration files.
*/
sys::path user_config_directory ();
/**
* @return the path to the directory that contains the system wide ardour
* modules.
*/
sys::path ardour_module_directory ();
SearchPath ardour_search_path ();
SearchPath system_config_search_path ();
SearchPath system_data_search_path ();
} // namespace ARDOUR
#endif

View File

@ -0,0 +1,51 @@
/*
Copyright (C) 2007 Paul Davis
Author: Dave Robillard
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_filter_h__
#define __ardour_filter_h__
#include <vector>
#include <ardour/region.h>
namespace ARDOUR {
class Region;
class Session;
class Filter {
public:
virtual ~Filter() {}
virtual int run (boost::shared_ptr<ARDOUR::Region>) = 0;
std::vector<boost::shared_ptr<ARDOUR::Region> > results;
protected:
Filter (ARDOUR::Session& s) : session(s) {}
int make_new_sources (boost::shared_ptr<ARDOUR::Region>, ARDOUR::SourceList&, std::string suffix = "");
int finish (boost::shared_ptr<ARDOUR::Region>, ARDOUR::SourceList&, std::string region_name = "");
ARDOUR::Session& session;
};
} /* namespace */
#endif /* __ardour_filter_h__ */

43
libs/ardour/ardour/gain.h Normal file
View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2000 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_gain_h__
#define __ardour_gain_h__
#include "ardour.h"
#include "curve.h"
namespace ARDOUR {
struct Gain : public AutomationList {
Gain();
Gain (const Gain&);
Gain& operator= (const Gain&);
static void fill_linear_fade_in (Gain& curve, nframes_t frames);
static void fill_linear_volume_fade_in (Gain& curve, nframes_t frames);
static void fill_linear_fade_out (Gain& curve, nframes_t frames);
static void fill_linear_volume_fade_out (Gain& curve, nframes_t frames);
};
} /* namespace ARDOUR */
#endif /* __ardour_gain_h__ */

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2002 Steve Harris <steve@plugin.org.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef GDITHER_H
#define GDITHER_H
#ifdef __cplusplus
extern "C" {
#endif
#include "gdither_types.h"
/* Create and initialise a state structure, takes a dither type, a number of
* channels and a bit depth as input
*
* The Dither type is one of
*
* GDitherNone - straight nearest neighbour rounding. Theres no pressing
* reason to do this at 8 or 16 bit, but you might want to at 24, for some
* reason. At the lest it will save you writing int->float conversion code,
* which is arder than it sounds.
*
* GDitherRect - mathematically most accurate, lowest noise floor, but not
* that good for audio. It is the fastest though.
*
* GDitherTri - a happy medium between Rectangular and Shaped, reasonable
* noise floor, not too obvious, quite fast.
*
* GDitherShaped - should have the least audible impact, but has the highest
* noise floor, fairly CPU intensive. Not advisible if your going to apply
* any frequency manipulation afterwards.
*
* channels, sets the number of channels in the output data, output data will
* be written interleaved into the area given to gdither_run(). Set to 1
* if you are not working with interleaved buffers.
*
* bit depth, sets the bit width of the output sample data, it can be one of:
*
* GDither8bit - 8 bit unsiged
* GDither16bit - 16 bit signed
* GDither32bit - 24+bits in upper bits of a 32 bit word
* GDitherFloat - IEEE floating point (32bits)
* GDitherDouble - Double precision IEEE floating point (64bits)
*
* dither_depth, set the number of bits before the signal will be truncated to,
* eg. 16 will produce an output stream with 16bits-worth of signal. Setting to
* zero or greater than the width of the output format will dither to the
* maximum precision allowed by the output format.
*/
GDither gdither_new(GDitherType type, uint32_t channels,
GDitherSize bit_depth, int dither_depth);
/* Frees memory used by gdither_new.
*/
void gdither_free(GDither s);
/* Applies dithering to the supplied signal.
*
* channel is the channel number you are processing (0 - channles-1), length is
* the length of the input, in samples, x is the input samples (float), y is
* where the output samples will be written, it should have the approaprate
* type for the chosen bit depth
*/
void gdither_runf(GDither s, uint32_t channel, uint32_t length,
float *x, void *y);
/* see gdither_runf, vut input argument is double format */
void gdither_run(GDither s, uint32_t channel, uint32_t length,
double *x, void *y);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2002 Steve Harris <steve@plugin.org.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef GDITHER_TYPES_H
#define GDITHER_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
GDitherNone = 0,
GDitherRect,
GDitherTri,
GDitherShaped
} GDitherType;
typedef enum {
GDither8bit = 8,
GDither16bit = 16,
GDither32bit = 32,
GDitherFloat = 25,
GDitherDouble = 54
} GDitherSize;
typedef void *GDither;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2002 Steve Harris <steve@plugin.org.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef GDITHER_TYPES_H
#define GDITHER_TYPES_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define GDITHER_SH_BUF_SIZE 8
#define GDITHER_SH_BUF_MASK 7
/* this must agree with whats in gdither_types.h */
typedef enum {
GDitherNone = 0,
GDitherRect,
GDitherTri,
GDitherShaped
} GDitherType;
typedef enum {
GDither8bit = 8,
GDither16bit = 16,
GDither32bit = 32,
GDitherFloat = 25,
GDitherDouble = 54
} GDitherSize;
typedef struct {
uint32_t phase;
float buffer[GDITHER_SH_BUF_SIZE];
} GDitherShapedState;
typedef struct GDither_s {
GDitherType type;
uint32_t channels;
uint32_t bit_depth;
uint32_t dither_depth;
float scale;
uint32_t post_scale;
float post_scale_fp;
float bias;
int clamp_u;
int clamp_l;
float *tri_state;
GDitherShapedState *shaped_state;
} *GDither;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,43 @@
/*
Copyright (C) 2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_importable_source_h__
#define __ardour_importable_source_h__
#include <pbd/failed_constructor.h>
#include <ardour/types.h>
namespace ARDOUR {
class ImportableSource {
public:
ImportableSource () {}
virtual ~ImportableSource() {}
virtual nframes_t read (Sample* buffer, nframes_t nframes) = 0;
virtual float ratio() const { return 1.0f; }
virtual uint32_t channels() const = 0;
virtual nframes_t length() const = 0;
virtual nframes_t samplerate() const = 0;
virtual void seek (nframes_t pos) = 0;
};
}
#endif /* __ardour_importable_source_h__ */

View File

@ -0,0 +1,55 @@
/*
Copyright (C) 2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: port.h 712 2006-07-28 01:08:57Z drobilla $
*/
#ifndef __ardour_internal_audio_port_h__
#define __ardour_internal_audio_port_h__
#include <sigc++/signal.h>
#include <pbd/failed_constructor.h>
#include <ardour/ardour.h>
#include <ardour/internal_port.h>
#include <ardour/audio_port.h>
namespace ARDOUR {
class AudioEngine;
class InternalAudioPort : public AudioPort, public InternalPort {
public:
void cycle_start(nframes_t nframes) {
_buffer.silence (nframes);
}
AudioBuffer& get_audio_buffer();
void set_mixdown_function (void (*func)(const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t));
void reset ();
protected:
friend class AudioEngine;
InternalAudioPort (const std::string& name, Flags flags);
void (*_mixdown)(const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t);
static void default_mixdown (const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t);
};
} // namespace ARDOUR
#endif /* __ardour_internal_audio_port_h__ */

View File

@ -0,0 +1,82 @@
/*
Copyright (C) 2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_internal_port_h__
#define __ardour_internal_port_h__
#include <list>
#include <sigc++/signal.h>
#include <pbd/failed_constructor.h>
#include <ardour/port.h>
namespace ARDOUR {
class AudioEngine;
class Buffer;
/** Abstract class representing internal (ardour<->ardour only) ports
*/
class InternalPort : public virtual Port {
public:
~InternalPort();
std::string short_name();
int set_name (std::string str);
int connected () const;
int reestablish ();
bool connected_to (const std::string& portname) const;
const char ** get_connections () const;
bool monitoring_input () const { return false; }
void ensure_monitor_input (bool yn) {}
void request_monitor_input (bool yn) {}
nframes_t latency () const { return _latency; }
nframes_t total_latency() const { return _latency; }
void set_latency (nframes_t nframes);
static void connect (InternalPort& src, InternalPort& dst);
static void disconnect (InternalPort& a, InternalPort& b);
protected:
friend class AudioEngine;
InternalPort (const std::string&, DataType type, Flags flags);
int disconnect ();
void recompute_total_latency() const;
std::list<InternalPort*> _connections;
nframes_t _latency;
static AudioEngine* engine;
static void set_engine (AudioEngine* e);
};
} // namespace ARDOUR
#endif /* __ardour_internal_port_h__ */

391
libs/ardour/ardour/io.h Normal file
View File

@ -0,0 +1,391 @@
/*
Copyright (C) 2000 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_io_h__
#define __ardour_io_h__
#include <string>
#include <vector>
#include <cmath>
#include <sigc++/signal.h>
#include <jack/jack.h>
#include <glibmm/thread.h>
#include <pbd/fastlog.h>
#include <pbd/undo.h>
#include <pbd/statefuldestructible.h>
#include <pbd/controllable.h>
#include <ardour/ardour.h>
#include <ardour/automatable.h>
#include <ardour/utils.h>
#include <ardour/curve.h>
#include <ardour/types.h>
#include <ardour/data_type.h>
#include <ardour/port_set.h>
#include <ardour/chan_count.h>
#include <ardour/latent.h>
#include <ardour/automation_control.h>
#include <ardour/user_bundle.h>
using std::string;
using std::vector;
class XMLNode;
namespace ARDOUR {
class Session;
class AudioEngine;
class Bundle;
class AutoBundle;
class Panner;
class PeakMeter;
class Port;
class AudioPort;
class MidiPort;
class BufferSet;
/** A collection of input and output ports with connections.
*
* An IO can contain ports of varying types, making routes/inserts/etc with
* varied combinations of types (eg MIDI and audio) possible.
*/
class IO : public Automatable, public Latent
{
public:
static const string state_node_name;
IO (Session&, const string& name,
int input_min = -1, int input_max = -1,
int output_min = -1, int output_max = -1,
DataType default_type = DataType::AUDIO,
bool public_ports = true);
IO (Session&, const XMLNode&, DataType default_type = DataType::AUDIO);
virtual ~IO();
ChanCount input_minimum() const { return _input_minimum; }
ChanCount input_maximum() const { return _input_maximum; }
ChanCount output_minimum() const { return _output_minimum; }
ChanCount output_maximum() const { return _output_maximum; }
void set_input_minimum (ChanCount n);
void set_input_maximum (ChanCount n);
void set_output_minimum (ChanCount n);
void set_output_maximum (ChanCount n);
bool active() const { return _active; }
void set_active (bool yn);
DataType default_type() const { return _default_type; }
void set_default_type(DataType t) { _default_type = t; }
bool set_name (const string& str);
virtual void silence (nframes_t, nframes_t offset);
void collect_input (BufferSet& bufs, nframes_t nframes, nframes_t offset);
void deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
nframes_t nframes, nframes_t offset);
void just_meter_input (nframes_t start_frame, nframes_t end_frame,
nframes_t nframes, nframes_t offset);
gain_t gain () const { return _desired_gain; }
virtual gain_t effective_gain () const;
void set_denormal_protection (bool yn, void *src);
bool denormal_protection() const { return _denormal_protection; }
void set_phase_invert (bool yn, void *src);
bool phase_invert() const { return _phase_invert; }
Panner& panner() { return *_panner; }
PeakMeter& peak_meter() { return *_meter; }
const Panner& panner() const { return *_panner; }
int ensure_io (ChanCount in, ChanCount out, bool clear, void *src);
int connect_input_ports_to_bundle (boost::shared_ptr<Bundle>, void *src);
int connect_output_ports_to_bundle (boost::shared_ptr<Bundle>, void *src);
std::vector<boost::shared_ptr<Bundle> > bundles_connected_to_inputs ();
std::vector<boost::shared_ptr<Bundle> > bundles_connected_to_outputs ();
boost::shared_ptr<AutoBundle> bundle_for_inputs () { return _bundle_for_inputs; }
boost::shared_ptr<AutoBundle> bundle_for_outputs () { return _bundle_for_outputs; }
int add_input_port (string source, void *src, DataType type = DataType::NIL);
int add_output_port (string destination, void *src, DataType type = DataType::NIL);
int remove_input_port (Port *, void *src);
int remove_output_port (Port *, void *src);
int set_input (Port *, void *src);
int connect_input (Port *our_port, string other_port, void *src);
int connect_output (Port *our_port, string other_port, void *src);
int disconnect_input (Port *our_port, string other_port, void *src);
int disconnect_output (Port *our_port, string other_port, void *src);
int disconnect_inputs (void *src);
int disconnect_outputs (void *src);
nframes_t signal_latency() const { return _own_latency; }
nframes_t output_latency() const;
nframes_t input_latency() const;
void set_port_latency (nframes_t);
void update_port_total_latencies ();
const PortSet& inputs() const { return _inputs; }
const PortSet& outputs() const { return _outputs; }
Port *output (uint32_t n) const {
if (n < _outputs.num_ports()) {
return _outputs.port(n);
} else {
return 0;
}
}
Port *input (uint32_t n) const {
if (n < _inputs.num_ports()) {
return _inputs.port(n);
} else {
return 0;
}
}
AudioPort* audio_input(uint32_t n) const;
AudioPort* audio_output(uint32_t n) const;
MidiPort* midi_input(uint32_t n) const;
MidiPort* midi_output(uint32_t n) const;
const ChanCount& n_inputs () const { return _inputs.count(); }
const ChanCount& n_outputs () const { return _outputs.count(); }
void attach_buffers(ChanCount ignored);
sigc::signal<void> active_changed;
sigc::signal<void,IOChange,void*> input_changed;
sigc::signal<void,IOChange,void*> output_changed;
virtual XMLNode& state (bool full);
XMLNode& get_state (void);
int set_state (const XMLNode&);
static int disable_connecting (void);
static int enable_connecting (void);
static int disable_ports (void);
static int enable_ports (void);
static int disable_panners (void);
static int reset_panners (void);
static sigc::signal<int> PortsLegal;
static sigc::signal<int> PannersLegal;
static sigc::signal<int> ConnectingLegal;
/// raised when the number of input or output ports changes
static sigc::signal<void,ChanCount> PortCountChanged;
static sigc::signal<int> PortsCreated;
static void update_meters();
private:
static sigc::signal<void> Meter;
static Glib::StaticMutex m_meter_signal_lock;
sigc::connection m_meter_connection;
public:
/* automation */
struct GainControl : public AutomationControl {
GainControl (std::string name, IO& i, boost::shared_ptr<AutomationList> al)
: AutomationControl (i._session, al, name)
, _io (i)
{}
void set_value (float val);
float get_value (void) const;
IO& _io;
};
boost::shared_ptr<GainControl> gain_control() {
return _gain_control;
}
boost::shared_ptr<const GainControl> gain_control() const {
return _gain_control;
}
void clear_automation ();
void set_parameter_automation_state (Parameter, AutoState);
virtual void transport_stopped (nframes_t now);
virtual void automation_snapshot (nframes_t now, bool force);
void start_pan_touch (uint32_t which);
void end_pan_touch (uint32_t which);
void defer_pan_reset ();
void allow_pan_reset ();
/* the session calls this for master outs before
anyone else. controls outs too, at some point.
*/
XMLNode *pending_state_node;
int ports_became_legal ();
private:
mutable Glib::Mutex io_lock;
protected:
Panner* _panner;
BufferSet* _output_buffers; //< Set directly to output port buffers
bool _active;
gain_t _gain;
gain_t _effective_gain;
gain_t _desired_gain;
Glib::Mutex declick_lock;
PortSet _outputs;
PortSet _inputs;
PeakMeter* _meter;
bool no_panner_reset;
bool _phase_invert;
bool _denormal_protection;
XMLNode* deferred_state;
DataType _default_type;
bool _public_ports;
virtual void set_deferred_state() {}
void reset_panner ();
virtual uint32_t pans_required() const
{ return _inputs.count().n_audio(); }
boost::shared_ptr<GainControl> _gain_control;
virtual void set_gain (gain_t g, void *src);
void inc_gain (gain_t delta, void *src);
bool apply_gain_automation;
virtual int load_automation (std::string path);
/* AudioTrack::deprecated_use_diskstream_connections() needs these */
int set_inputs (const string& str);
int set_outputs (const string& str);
static bool connecting_legal;
static bool ports_legal;
BufferSet& output_buffers() { return *_output_buffers; }
private:
friend class Send;
static bool panners_legal;
int connecting_became_legal ();
int panners_became_legal ();
sigc::connection connection_legal_c;
sigc::connection port_legal_c;
sigc::connection panner_legal_c;
ChanCount _input_minimum; ///< minimum number of input channels (0 for no minimum)
ChanCount _input_maximum; ///< maximum number of input channels (ChanCount::INFINITE for no maximum)
ChanCount _output_minimum; ///< minimum number of output channels (0 for no minimum)
ChanCount _output_maximum; ///< maximum number of output channels (ChanCount::INFINITE for no maximum)
boost::shared_ptr<AutoBundle> _bundle_for_inputs; ///< a bundle representing our inputs
boost::shared_ptr<AutoBundle> _bundle_for_outputs; ///< a bundle representing our outputs
struct UserBundleInfo {
UserBundleInfo (IO*, boost::shared_ptr<UserBundle> b);
boost::shared_ptr<UserBundle> bundle;
sigc::connection configuration_will_change;
sigc::connection configuration_has_changed;
sigc::connection ports_will_change;
sigc::connection ports_have_changed;
};
std::vector<UserBundleInfo> _bundles_connected_to_outputs; ///< user bundles connected to our outputs
std::vector<UserBundleInfo> _bundles_connected_to_inputs; ///< user bundles connected to our inputs
static int parse_io_string (const string&, vector<string>& chns);
static int parse_gain_string (const string&, vector<string>& chns);
int set_sources (vector<string>&, void *src, bool add);
int set_destinations (vector<string>&, void *src, bool add);
int ensure_inputs (ChanCount, bool clear, bool lockit, void *src);
int ensure_outputs (ChanCount, bool clear, bool lockit, void *src);
void check_bundles_connected_to_inputs ();
void check_bundles_connected_to_outputs ();
void check_bundles (std::vector<UserBundleInfo>&, const PortSet&);
void bundle_configuration_will_change ();
void bundle_configuration_has_changed ();
void bundle_ports_will_change (int);
void bundle_ports_have_changed (int);
int create_ports (const XMLNode&);
int make_connections (const XMLNode&);
void setup_peak_meters ();
void meter ();
bool ensure_inputs_locked (ChanCount, bool clear, void *src);
bool ensure_outputs_locked (ChanCount, bool clear, void *src);
std::string build_legal_port_name (DataType type, bool for_input);
int32_t find_input_port_hole (const char* base);
int32_t find_output_port_hole (const char* base);
void create_bundles_for_inputs_and_outputs ();
void setup_bundles_for_inputs_and_outputs ();
void maybe_add_input_bundle_to_list (boost::shared_ptr<Bundle>, std::vector<boost::shared_ptr<Bundle> >*);
void maybe_add_output_bundle_to_list (boost::shared_ptr<Bundle>, std::vector<boost::shared_ptr<Bundle> >*);
};
} // namespace ARDOUR
#endif /*__ardour_io_h__ */

View File

@ -0,0 +1,86 @@
/*
Copyright (C) 2001 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_redirect_h__
#define __ardour_redirect_h__
#include <string>
#include <vector>
#include <set>
#include <map>
#include <boost/shared_ptr.hpp>
#include <sigc++/signal.h>
#include <glibmm/thread.h>
#include <pbd/undo.h>
#include <ardour/ardour.h>
#include <ardour/processor.h>
#include <ardour/io.h>
#include <ardour/automation_event.h>
using std::map;
using std::set;
using std::string;
using std::vector;
class XMLNode;
namespace ARDOUR {
class Session;
/** A mixer strip element (Processor) with Jack ports (IO).
*/
class IOProcessor : public Processor
{
public:
IOProcessor (Session&, const string& name, Placement,
int input_min = -1, int input_max = -1, int output_min = -1, int output_max = -1);
IOProcessor (const IOProcessor&);
virtual ~IOProcessor ();
virtual ChanCount output_streams() const { return _io->n_outputs(); }
virtual ChanCount input_streams () const { return _io->n_inputs(); }
virtual ChanCount natural_output_streams() const { return _io->n_outputs(); }
virtual ChanCount natural_input_streams () const { return _io->n_inputs(); }
boost::shared_ptr<IO> io() { return _io; }
boost::shared_ptr<const IO> io() const { return _io; }
virtual void automation_snapshot (nframes_t now, bool force) { _io->automation_snapshot(now, force); }
virtual void run_in_place (BufferSet& in, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) = 0;
void silence (nframes_t nframes, nframes_t offset);
sigc::signal<void,IOProcessor*,bool> AutomationPlaybackChanged;
sigc::signal<void,IOProcessor*,uint32_t> AutomationChanged;
XMLNode& state (bool full_state);
int set_state (const XMLNode&);
protected:
boost::shared_ptr<IO> _io;
};
} // namespace ARDOUR
#endif /* __ardour_redirect_h__ */

View File

@ -0,0 +1,51 @@
/*
Copyright (C) 2002 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: port.h 712 2006-07-28 01:08:57Z drobilla $
*/
#ifndef __ardour_jack_audio_port_h__
#define __ardour_jack_audio_port_h__
#include <sigc++/signal.h>
#include <pbd/failed_constructor.h>
#include <ardour/ardour.h>
#include <ardour/jack_port.h>
#include <ardour/audio_port.h>
namespace ARDOUR {
class AudioEngine;
class JackAudioPort : public JackPort, public BaseAudioPort {
public:
void cycle_start (nframes_t nframes, nframes_t offset) {
_buffer->set_data ((Sample*) jack_port_get_buffer (_port, nframes) + offset, nframes);
}
int reestablish ();
protected:
friend class AudioPort;
JackAudioPort (const std::string& name, Flags flags, AudioBuffer* buf);
AudioBuffer* _source_buffer;
};
} // namespace ARDOUR
#endif /* __ardour_jack_audio_port_h__ */

View File

@ -0,0 +1,52 @@
/*
Copyright (C) 2002 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: port.h 712 2006-07-28 01:08:57Z drobilla $
*/
#ifndef __ardour_jack_midi_port_h__
#define __ardour_jack_midi_port_h__
#include <sigc++/signal.h>
#include <pbd/failed_constructor.h>
#include <ardour/ardour.h>
#include <jack/jack.h>
#include <jack/midiport.h>
#include <ardour/port.h>
#include <ardour/jack_port.h>
#include <ardour/base_midi_port.h>
#include <ardour/midi_buffer.h>
namespace ARDOUR {
class MidiEngine;
class JackMidiPort : public JackPort, public BaseMidiPort {
public:
void cycle_start (nframes_t nframes, nframes_t offset);
void cycle_end (nframes_t nframes, nframes_t offset);
void set_buffer (MidiBuffer& buf);
protected:
friend class MidiPort;
JackMidiPort (const std::string&, Flags, MidiBuffer*);
};
} // namespace ARDOUR
#endif /* __ardour_jack_midi_port_h__ */

Some files were not shown because too many files have changed in this diff Show More