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:
parent
9c0d7d72d7
commit
449aab3c46
|
@ -0,0 +1 @@
|
|||
.DS_Store
|
|
@ -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
|
||||
|
|
@ -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__
|
|
@ -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 ¶mInfo = 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;
|
||||
}
|
|
@ -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; }
|
||||
};
|
|
@ -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", ¶mValue);
|
||||
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
|
|
@ -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__
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
@ -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
|
@ -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
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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__
|
|
@ -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;
|
||||
}
|
|
@ -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__
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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__
|
|
@ -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__
|
|
@ -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.);
|
||||
}
|
|
@ -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__
|
|
@ -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;
|
|
@ -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__
|
|
@ -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') ))
|
|
@ -0,0 +1,8 @@
|
|||
libardour.la
|
||||
libardour.pc
|
||||
version.cc
|
||||
*.lo
|
||||
*.os
|
||||
*.mo
|
||||
*.pot
|
||||
*.dylib
|
|
@ -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.
|
||||
|
|
@ -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')))
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
version.h
|
|
@ -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__
|
|
@ -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__ */
|
|
@ -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__ */
|
||||
|
|
@ -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__
|
|
@ -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__ */
|
|
@ -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__
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
||||
|
||||
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__
|
|
@ -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__
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__
|
||||
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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)
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__
|
||||
|
|
@ -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
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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
Loading…
Reference in New Issue