first and last commit
This commit is contained in:
commit
1bf4efd552
2612 files changed
+636500
No files matched your search
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* AudioUnit_AE2.h
|
||||
* CAServices-Aspen
|
||||
*
|
||||
* Created by richardp on 11/28/11.
|
||||
* Copyright 2011 Apple, Inc. All rights reserved.
|
||||
*
|
||||
* Serves as the base class for AudioUnits on AE2
|
||||
*/
|
||||
|
||||
#ifndef __AudioUnit_AE2_h__
|
||||
#define __AudioUnit_AE2_h__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "AudioUnitProperties_AE2.h"
|
||||
|
||||
/**
|
||||
* AUBase_AE2 is the wrapper to go from AE2 land to CoreAudio land.
|
||||
* For instance, we assume input channels are 16-bit, whereas CoreAudio
|
||||
* AudioUnit may require floats. These modules do the translation.
|
||||
*
|
||||
* This is not intended to be parity with AudioUnits, but a crippled
|
||||
* version.
|
||||
*/
|
||||
|
||||
class AUBase_AE2
|
||||
{
|
||||
public:
|
||||
AUBase_AE2() {}
|
||||
virtual ~AUBase_AE2() {}
|
||||
|
||||
virtual OSStatus Initialize() { return noErr; }
|
||||
|
||||
virtual void Process(const void *inSourceP,
|
||||
void *inDestP,
|
||||
uint32_t inFramesToProcess) {}
|
||||
|
||||
// for parameters
|
||||
virtual OSStatus SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue value) { return kAudioUnitErr_InvalidParameter; }
|
||||
virtual AudioUnitParameterValue GetParameter(AudioUnitParameterID paramID) { return 0; }
|
||||
|
||||
// for properties
|
||||
virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID, uint32_t& outDataSize, bool& outWritable) { return kAudioUnitErr_InvalidProperty; }
|
||||
virtual OSStatus GetProperty(AudioUnitPropertyID inID, void* outData) { return kAudioUnitErr_InvalidProperty; }
|
||||
virtual OSStatus SetProperty(AudioUnitPropertyID inID, const void* inData, uint32_t inDataSize) { return kAudioUnitErr_InvalidProperty; }
|
||||
};
|
||||
|
||||
#endif // __AudioUnit_AE2_h__
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* AUComponent_AE2.h
|
||||
* Stripped down version of AUComponent just for what AE2 needs
|
||||
*
|
||||
* Copyright 2010 Apple Computer. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AUCOMPONENT_AE2__
|
||||
#define __AUCOMPONENT_AE2__
|
||||
|
||||
/*!
|
||||
@enum Audio unit errors
|
||||
@discussion These are the various errors that can be returned by AudioUnit... API calls
|
||||
|
||||
@constant kAudioUnitErr_InvalidProperty
|
||||
The property is not supported
|
||||
@constant kAudioUnitErr_InvalidParameter
|
||||
The parameter is not supported
|
||||
@constant kAudioUnitErr_InvalidElement
|
||||
The specified element is not valid
|
||||
@constant kAudioUnitErr_NoConnection
|
||||
There is no connection (generally an audio unit is asked to render but it has
|
||||
not input from which to gather data)
|
||||
@constant kAudioUnitErr_FailedInitialization
|
||||
The audio unit is unable to be initialised
|
||||
@constant kAudioUnitErr_TooManyFramesToProcess
|
||||
When an audio unit is initialised it has a value which specifies the max
|
||||
number of frames it will be asked to render at any given time. If an audio
|
||||
unit is asked to render more than this, this error is returned.
|
||||
@constant kAudioUnitErr_InvalidFile
|
||||
If an audio unit uses external files as a data source, this error is returned
|
||||
if a file is invalid (Apple's DLS synth returns this error)
|
||||
@constant kAudioUnitErr_FormatNotSupported
|
||||
Returned if an input or output format is not supported
|
||||
@constant kAudioUnitErr_Uninitialized
|
||||
Returned if an operation requires an audio unit to be initialised and it is
|
||||
not.
|
||||
@constant kAudioUnitErr_InvalidScope
|
||||
The specified scope is invalid
|
||||
@constant kAudioUnitErr_PropertyNotWritable
|
||||
The property cannot be written
|
||||
@constant kAudioUnitErr_CannotDoInCurrentContext
|
||||
Returned when an audio unit is in a state where it can't perform the requested
|
||||
action now - but it could later. Its usually used to guard a render operation
|
||||
when a reconfiguration of its internal state is being performed.
|
||||
@constant kAudioUnitErr_InvalidPropertyValue
|
||||
The property is valid, but the value of the property being provided is not
|
||||
@constant kAudioUnitErr_PropertyNotInUse
|
||||
Returned when a property is valid, but it hasn't been set to a valid value at
|
||||
this time.
|
||||
@constant kAudioUnitErr_Initialized
|
||||
Indicates the operation cannot be performed because the audio unit is
|
||||
initialized.
|
||||
@constant kAudioUnitErr_InvalidOfflineRender
|
||||
Used to indicate that the offline render operation is invalid. For instance,
|
||||
when the audio unit needs to be pre-flighted,
|
||||
but it hasn't been.
|
||||
@constant kAudioUnitErr_Unauthorized
|
||||
Returned by either Open or Initialise, this error is used to indicate that the
|
||||
audio unit is not authorised, that it cannot be used. A host can then present
|
||||
a UI to notify the user the audio unit is not able to be used in its current
|
||||
state.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kAudioUnitErr_InvalidProperty = -10879,
|
||||
kAudioUnitErr_InvalidParameter = -10878,
|
||||
kAudioUnitErr_InvalidElement = -10877,
|
||||
kAudioUnitErr_NoConnection = -10876,
|
||||
kAudioUnitErr_FailedInitialization = -10875,
|
||||
kAudioUnitErr_TooManyFramesToProcess = -10874,
|
||||
kAudioUnitErr_InvalidFile = -10871,
|
||||
kAudioUnitErr_FormatNotSupported = -10868,
|
||||
kAudioUnitErr_Uninitialized = -10867,
|
||||
kAudioUnitErr_InvalidScope = -10866,
|
||||
kAudioUnitErr_PropertyNotWritable = -10865,
|
||||
kAudioUnitErr_CannotDoInCurrentContext = -10863,
|
||||
kAudioUnitErr_InvalidPropertyValue = -10851,
|
||||
kAudioUnitErr_PropertyNotInUse = -10850,
|
||||
kAudioUnitErr_Initialized = -10849,
|
||||
kAudioUnitErr_InvalidOfflineRender = -10848,
|
||||
kAudioUnitErr_Unauthorized = -10847
|
||||
};
|
||||
|
||||
/*!
|
||||
@typedef AudioUnitPropertyID
|
||||
@discussion Type used for audio unit properties.
|
||||
Properties are used to describe the state of an audio unit (for instance,
|
||||
the input or output audio format)
|
||||
*/
|
||||
typedef UInt32 AudioUnitPropertyID;
|
||||
/*!
|
||||
@typedef AudioUnitScope
|
||||
@discussion Type used for audio unit scopes. Apple reserves the 0 < 1024 range for
|
||||
audio unit scope identifiers.
|
||||
Scopes are used to delineate a major attribute of an audio unit
|
||||
(for instance, global, input, output)
|
||||
*/
|
||||
typedef UInt32 AudioUnitScope;
|
||||
/*!
|
||||
@typedef AudioUnitElement
|
||||
@discussion Type used for audio unit elements.
|
||||
Scopes can have one or more member, and a member of a scope is
|
||||
addressed / described by its element
|
||||
For instance, input bus 1 is input scope, element 1
|
||||
*/
|
||||
typedef UInt32 AudioUnitElement;
|
||||
/*!
|
||||
@typedef AudioUnitParameterID
|
||||
@discussion Type used for audio unit parameters.
|
||||
Parameters are typically used to control and set render state
|
||||
(for instance, filter cut-off frequency)
|
||||
*/
|
||||
typedef UInt32 AudioUnitParameterID;
|
||||
/*!
|
||||
@typedef AudioUnitParameterValue
|
||||
@discussion Type used for audio unit parameter values.
|
||||
The value of a given parameter is specified using this type
|
||||
(typically a Float32)
|
||||
*/
|
||||
typedef Float32 AudioUnitParameterValue;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Render flags
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
/* these are obsolete, were never implemented: */
|
||||
/* kAudioUnitRenderAction_Accumulate = (1 << 0) */
|
||||
/* kAudioUnitRenderAction_UseProvidedBuffer = (1 << 1) */
|
||||
kAudioUnitRenderAction_PreRender = (1 << 2),
|
||||
kAudioUnitRenderAction_PostRender = (1 << 3),
|
||||
kAudioUnitRenderAction_OutputIsSilence = (1 << 4),
|
||||
/* Provides hint on return from Render(). if set, the buffer contains all zeroes */
|
||||
kAudioOfflineUnitRenderAction_Preflight = (1 << 5),
|
||||
kAudioOfflineUnitRenderAction_Render = (1 << 6),
|
||||
kAudioOfflineUnitRenderAction_Complete = (1 << 7),
|
||||
// this flag is set if on the post-render call an error was returned by the AUs render
|
||||
// in this case, the error can be retrieved through the lastRenderError property
|
||||
// and the ioData handed to the post-render notification will be invalid.
|
||||
kAudioUnitRenderAction_PostRenderError = (1 << 8)
|
||||
};
|
||||
|
||||
typedef UInt32 AudioUnitRenderActionFlags;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#include "AUNull.h"
|
||||
#include "string.h"
|
||||
#include <debug.h>
|
||||
|
||||
#define GENERATE_SAWTOOTH 0
|
||||
|
||||
AUNull *
|
||||
AUNull::Create_AUNull(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize)
|
||||
{
|
||||
AUNull *This = new AUNull;
|
||||
if (This)
|
||||
{
|
||||
if (This->InitWith(sampleRate, numChannels, sampleSize))
|
||||
{
|
||||
This->Initialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete This;
|
||||
This = NULL;
|
||||
}
|
||||
}
|
||||
return This;
|
||||
}
|
||||
|
||||
AUNull::AUNull()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AUNull::InitWith(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize)
|
||||
{
|
||||
mSampleRate = sampleRate;
|
||||
mNumChannels = numChannels;
|
||||
mSampleSize = sampleSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
AUNull::~AUNull()
|
||||
{
|
||||
}
|
||||
|
||||
#if GENERATE_SAWTOOTH
|
||||
static int16_t currentValue = 0;
|
||||
static const uint32_t kFreq = 600;
|
||||
#endif
|
||||
|
||||
void
|
||||
AUNull::Process(const void *inSourceP,
|
||||
void *inDestP,
|
||||
UInt32 inFramesToProcess)
|
||||
{
|
||||
#if GENERATE_SAWTOOTH
|
||||
uint16_t amountToAdd = (0x10000L * kFreq) / mSampleRate;
|
||||
int16_t *dst = static_cast<int16_t*>(inDestP);
|
||||
size_t i = 0;
|
||||
for (i = 0; i < (inFramesToProcess * mNumChannels); ++i)
|
||||
{
|
||||
*dst++ = currentValue;
|
||||
currentValue += amountToAdd;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* AUNull.h
|
||||
*
|
||||
* Created by richardp on 11/28/11.
|
||||
* Copyright 2011 Apple, Inc. All rights reserved.
|
||||
*
|
||||
* Does necessary translation between AE2 and CA AU speaker protection
|
||||
*/
|
||||
|
||||
#ifndef __AUNull_h__
|
||||
#define __AUNull_h__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "AudioUnitProperties_AE2.h"
|
||||
#include "AUBase_AE2.h"
|
||||
|
||||
class IIRFilter;
|
||||
|
||||
/**
|
||||
* AUNull just passes input to output
|
||||
* Assumes audio data is 16-bit stereo
|
||||
*/
|
||||
class AUNull : public AUBase_AE2
|
||||
{
|
||||
public:
|
||||
static AUNull* Create_AUNull(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize);
|
||||
virtual ~AUNull();
|
||||
|
||||
virtual void Process(const void *inSourceP,
|
||||
void *inDestP,
|
||||
UInt32 inFramesToProcess);
|
||||
|
||||
private:
|
||||
AUNull();
|
||||
bool InitWith(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize);
|
||||
|
||||
// some constants
|
||||
typedef AUBase_AE2 super;
|
||||
size_t mSampleRate;
|
||||
size_t mNumChannels;
|
||||
size_t mSampleSize;
|
||||
};
|
||||
|
||||
#endif // __AUNull_h__
|
||||
|
||||
@@ -0,0 +1,458 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#if USE_SIDETONE
|
||||
#include "AUSidetone.h"
|
||||
#include "IIRFiltersA5.h"
|
||||
#include "VolumeA5.h"
|
||||
#include "string.h"
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
// a basic fixed 16-bit mono 44.1 description
|
||||
static AudioStreamBasicDescription kDefaultMonoFormat = { 44100.0, 'lpcm', 0xC, 2, 1, 2, 1, 16, 0 };
|
||||
|
||||
static void SetDefaultSidetoneEQ(BiquadDescriptor *biquadValues, size_t numBands, uint32_t sampleRate)
|
||||
{
|
||||
size_t i = 0;
|
||||
if (i < numBands)
|
||||
{
|
||||
biquadValues[i].filterType = kAUNBandEQFilterType_2ndOrderButterworthLowPass;
|
||||
biquadValues[i].frequencyInHertz = (sampleRate == 8000) ? 3800.0f : 7400.0f;
|
||||
biquadValues[i].gain = 0.f;
|
||||
biquadValues[i].bw = 0.05;
|
||||
biquadValues[i].bypassBand = 0.f;
|
||||
++i;
|
||||
}
|
||||
if (i < numBands)
|
||||
{
|
||||
biquadValues[i].filterType = kAUNBandEQFilterType_2ndOrderButterworthHighPass;
|
||||
biquadValues[i].frequencyInHertz = (sampleRate == 8000) ? 200.0f : 100.0f;
|
||||
biquadValues[i].gain = 0.f;
|
||||
biquadValues[i].bw = 0.05;
|
||||
biquadValues[i].bypassBand = 0.f;
|
||||
++i;
|
||||
}
|
||||
|
||||
for (; i < numBands; ++i)
|
||||
{
|
||||
biquadValues[i].filterType = 0;
|
||||
biquadValues[i].frequencyInHertz = 100.0f;
|
||||
biquadValues[i].gain = 0.f;
|
||||
biquadValues[i].bw = 0.05;
|
||||
biquadValues[i].bypassBand = 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AUSidetone *
|
||||
AUSidetone::Create_AUSidetone(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize)
|
||||
{
|
||||
AUSidetone *This = new AUSidetone;
|
||||
if (This)
|
||||
{
|
||||
if (This->InitWith(sampleRate, numChannels, sampleSize))
|
||||
{
|
||||
This->Initialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete This;
|
||||
This = NULL;
|
||||
}
|
||||
}
|
||||
return This;
|
||||
}
|
||||
|
||||
|
||||
AUSidetone::AUSidetone() :
|
||||
mSampleRate(44100),
|
||||
mNumChannels(1),
|
||||
mSidetoneEQ(NULL),
|
||||
mVolume(NULL),
|
||||
mNumberBands(kMaxNumBands),
|
||||
mBiquadValues(NULL),
|
||||
mVolumeInDB(kDefaultSidetoneGain),
|
||||
mSidetoneEQBypass(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AUSidetone::InitWith(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize)
|
||||
{
|
||||
if (sampleSize != 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mSampleRate = sampleRate;
|
||||
mNumChannels = numChannels;
|
||||
|
||||
AudioStreamBasicDescription thisFormat = kDefaultMonoFormat;
|
||||
thisFormat.mSampleRate = mSampleRate;
|
||||
thisFormat.mBytesPerPacket *= mNumChannels;
|
||||
thisFormat.mBytesPerFrame *= mNumChannels;
|
||||
thisFormat.mChannelsPerFrame *= mNumChannels;
|
||||
thisFormat.mBitsPerChannel *= mNumChannels;
|
||||
|
||||
mSidetoneEQ = NewAE2IIRFilter(&thisFormat, &thisFormat, kMaxNumBands);
|
||||
dprintf(DEBUG_INFO, "sidetone eq %p\n", mSidetoneEQ);
|
||||
mBiquadValues = new BiquadDescriptor[mNumberBands];
|
||||
if (mBiquadValues)
|
||||
{
|
||||
SetDefaultSidetoneEQ(mBiquadValues, mNumberBands, mSampleRate);
|
||||
if (mSidetoneEQ)
|
||||
{
|
||||
mVolume = NewVolume(thisFormat);
|
||||
dprintf(DEBUG_INFO, "volume %p\n", mVolume);
|
||||
if (mVolume)
|
||||
{
|
||||
if ((SetAE2IIRFilter(mSidetoneEQ, &thisFormat, mNumberBands, mBiquadValues) == noErr) &&
|
||||
(SetGain(mVolume, mVolumeInDB) == noErr))
|
||||
{
|
||||
dprintf(DEBUG_INFO, "it is all good\n");
|
||||
return true;
|
||||
}
|
||||
DeleteVolume(mVolume);
|
||||
mVolume = NULL;
|
||||
}
|
||||
DeleteAE2IIRFilter(mSidetoneEQ);
|
||||
mSidetoneEQ = NULL;
|
||||
}
|
||||
delete [] mBiquadValues;
|
||||
mBiquadValues = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
AUSidetone::~AUSidetone()
|
||||
{
|
||||
DeleteAE2IIRFilter(mSidetoneEQ);
|
||||
mSidetoneEQ = NULL;
|
||||
DeleteVolume(mVolume);
|
||||
mVolume = NULL;
|
||||
delete [] mBiquadValues;
|
||||
mBiquadValues = NULL;
|
||||
}
|
||||
|
||||
|
||||
// These conversion routines are for translating from UInt32 of the AP/AE2 bridge
|
||||
// to the floating point of the internal representation. Scaling and offsets applied here.
|
||||
Float32 AudioUnitParameterValue_To_BypassBand(AudioUnitParameterValue value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t((value == 0) ? 0.f : 1.f));
|
||||
return (value == 0) ? 0.f : 1.f;
|
||||
}
|
||||
|
||||
|
||||
AudioUnitParameterValue BypassBand_To_AudioUnitParameterValue(Float32 value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t((value == 0.f) ? 0 : 1));
|
||||
return (value == 0.f) ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
UInt32 AudioUnitParameterValue_To_FilterType(AudioUnitParameterValue value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
AudioUnitParameterValue FilterType_To_AudioUnitParameterValue(UInt32 value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
Float32 AudioUnitParameterValue_To_Frequency(AudioUnitParameterValue value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
AudioUnitParameterValue Frequency_To_AudioUnitParameterValue(Float32 value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
Float32 AudioUnitParameterValue_To_Gain(AudioUnitParameterValue value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(-96.0 + (value)));
|
||||
return -96.0 + (value);
|
||||
}
|
||||
|
||||
|
||||
AudioUnitParameterValue Gain_To_AudioUnitParameterValue(Float32 value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t((value) - (-96.0)));
|
||||
return (value) - (-96.0);
|
||||
}
|
||||
|
||||
|
||||
Float32 AudioUnitParameterValue_To_Bandwidth(AudioUnitParameterValue value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value / 100.0f));
|
||||
return value / 100.0f;
|
||||
}
|
||||
|
||||
|
||||
AudioUnitParameterValue Bandwidth_To_AudioUnitParameterValue(Float32 value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(value * 100.0f));
|
||||
return value * 100.0f;
|
||||
}
|
||||
|
||||
|
||||
Float32 AudioUnitParameterValue_To_VolumeInDB(AudioUnitParameterValue value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t(-96.0 + (value)));
|
||||
return -96.0 + (value);
|
||||
}
|
||||
|
||||
|
||||
AudioUnitParameterValue VolumeInDB_To_AudioUnitParameterValue(Float32 value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "%s %d value %d\n", __FUNCTION__, uint32_t(value), uint32_t((value) - (-96.0)));
|
||||
return (value) - (-96.0);
|
||||
}
|
||||
|
||||
|
||||
OSStatus
|
||||
AUSidetone::SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue value)
|
||||
{
|
||||
dprintf(DEBUG_INFO, "SetParameter %d value %d\n", paramID, uint32_t(value));
|
||||
if (paramID == kAUVolume_InDB)
|
||||
{
|
||||
mVolumeInDB = AudioUnitParameterValue_To_VolumeInDB(value);
|
||||
return SetGain(mVolume, mVolumeInDB);
|
||||
}
|
||||
|
||||
AudioStreamBasicDescription thisFormat = kDefaultMonoFormat;
|
||||
thisFormat.mSampleRate = mSampleRate;
|
||||
thisFormat.mBytesPerPacket *= mNumChannels;
|
||||
thisFormat.mBytesPerFrame *= mNumChannels;
|
||||
thisFormat.mChannelsPerFrame *= mNumChannels;
|
||||
thisFormat.mBitsPerChannel *= mNumChannels;
|
||||
|
||||
// get the index
|
||||
uint32_t which = paramID % 1000;
|
||||
uint32_t type = (paramID / 1000)*1000;
|
||||
bool success = false;
|
||||
if (which < mNumberBands)
|
||||
{
|
||||
success = true;
|
||||
switch (type)
|
||||
{
|
||||
case kAUNBandEQParam_BypassBand:
|
||||
mBiquadValues[which].bypassBand = AudioUnitParameterValue_To_BypassBand(value);
|
||||
break;
|
||||
case kAUNBandEQParam_FilterType:
|
||||
mBiquadValues[which].filterType = AudioUnitParameterValue_To_FilterType(value);
|
||||
break;
|
||||
case kAUNBandEQParam_Frequency:
|
||||
mBiquadValues[which].frequencyInHertz = AudioUnitParameterValue_To_Frequency(value);
|
||||
break;
|
||||
case kAUNBandEQParam_Gain:
|
||||
mBiquadValues[which].gain = AudioUnitParameterValue_To_Gain(value);
|
||||
break;
|
||||
case kAUNBandEQParam_Bandwidth:
|
||||
mBiquadValues[which].bw = AudioUnitParameterValue_To_Bandwidth(value);
|
||||
break;
|
||||
default:
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus result = 0;
|
||||
if (success)
|
||||
{
|
||||
result = SetAE2IIRFilter(mSidetoneEQ, &thisFormat, mNumberBands, mBiquadValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = super::SetParameter(paramID, value);
|
||||
}
|
||||
dprintf(DEBUG_INFO, "result is %d\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AudioUnitParameterValue
|
||||
AUSidetone::GetParameter(AudioUnitParameterID paramID)
|
||||
{
|
||||
if (paramID == kAUVolume_InDB)
|
||||
{
|
||||
return VolumeInDB_To_AudioUnitParameterValue(mVolumeInDB);
|
||||
}
|
||||
// get the index
|
||||
uint32_t which = paramID % 1000;
|
||||
uint32_t type = (paramID / 1000)*1000;
|
||||
if (which < mNumberBands)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case kAUNBandEQParam_BypassBand:
|
||||
return BypassBand_To_AudioUnitParameterValue(mBiquadValues[which].bypassBand);
|
||||
case kAUNBandEQParam_FilterType:
|
||||
return FilterType_To_AudioUnitParameterValue(mBiquadValues[which].filterType);
|
||||
case kAUNBandEQParam_Frequency:
|
||||
return Frequency_To_AudioUnitParameterValue(mBiquadValues[which].frequencyInHertz);
|
||||
case kAUNBandEQParam_Gain:
|
||||
return Gain_To_AudioUnitParameterValue(mBiquadValues[which].gain);
|
||||
case kAUNBandEQParam_Bandwidth:
|
||||
return Bandwidth_To_AudioUnitParameterValue(mBiquadValues[which].bw);
|
||||
}
|
||||
}
|
||||
return super::GetParameter(paramID);
|
||||
}
|
||||
|
||||
|
||||
OSStatus
|
||||
AUSidetone::GetPropertyInfo(AudioUnitPropertyID inID, uint32_t& outDataSize, bool& outWritable)
|
||||
{
|
||||
OSStatus result = -1;
|
||||
switch (inID)
|
||||
{
|
||||
case kAUSongbird_SidetoneState:
|
||||
result = GetPropertyInfo(kAUSongbird_SidetoneEQBlockData, outDataSize, outWritable);
|
||||
if (noErr == result)
|
||||
{
|
||||
// leave room for the mVolume field of the AU_SidetoneState;
|
||||
outDataSize += offsetof(AU_SidetoneState, mFilterDescription);
|
||||
}
|
||||
break;
|
||||
case kAUSongbird_SidetoneEQBlockData:
|
||||
outDataSize = sizeof(AU_BiquadFilterDescription) - sizeof(AU_BiquadFilter) + mNumberBands * sizeof(AU_BiquadFilter);
|
||||
outWritable = true;
|
||||
result = noErr;
|
||||
break;
|
||||
default:
|
||||
result = super::GetPropertyInfo(inID, outDataSize, outWritable);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
OSStatus
|
||||
AUSidetone::GetProperty(AudioUnitPropertyID inID, void* outData)
|
||||
{
|
||||
OSStatus result = -1;
|
||||
switch (inID)
|
||||
{
|
||||
case kAUSongbird_SidetoneState:
|
||||
{
|
||||
AU_SidetoneState * state = static_cast<AU_SidetoneState*>(outData);
|
||||
state->mVolume = mVolumeInDB;
|
||||
state->mBypass = mSidetoneEQBypass;
|
||||
void * biquad_filter_description = &state->mFilterDescription;
|
||||
result = GetProperty(kAUSongbird_SidetoneEQBlockData, biquad_filter_description);
|
||||
}
|
||||
break;
|
||||
case kAUSongbird_SidetoneEQBlockData:
|
||||
{
|
||||
AU_BiquadFilterDescription * description = static_cast<AU_BiquadFilterDescription*>(outData);
|
||||
if (description)
|
||||
{
|
||||
description->mBypass = mSidetoneEQBypass;
|
||||
description->mNumberFilters = mNumberBands;
|
||||
BiquadCoefficientsDescriptor * filter = static_cast<BiquadCoefficientsDescriptor*>(static_cast<void*>(description->mFilters));
|
||||
if (filter)
|
||||
{
|
||||
result = GetAE2IIRFilterCoefficients(mSidetoneEQ, mNumberBands, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = super::GetProperty(inID, outData);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
OSStatus
|
||||
AUSidetone::SetProperty(AudioUnitPropertyID inID, const void* inData, uint32_t inDataSize)
|
||||
{
|
||||
OSStatus result = -1;
|
||||
switch (inID)
|
||||
{
|
||||
case kAUSongbird_SidetoneState:
|
||||
{
|
||||
// determine if have a valid data structure
|
||||
if (inDataSize < (offsetof(AU_SidetoneState, mFilterDescription)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
const AU_SidetoneState * state = static_cast<const AU_SidetoneState*>(inData);
|
||||
const void * biquad_filter_description = &state->mFilterDescription;
|
||||
result = SetProperty(kAUSongbird_SidetoneEQBlockData, biquad_filter_description, inDataSize - offsetof(AU_SidetoneState, mFilterDescription));
|
||||
if (noErr == result)
|
||||
{
|
||||
mSidetoneEQBypass = state->mBypass;
|
||||
mVolumeInDB = state->mVolume;
|
||||
result = SetGain(mVolume, mVolumeInDB);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kAUSongbird_SidetoneEQBlockData:
|
||||
{
|
||||
// determine if we are talking to a valid structure
|
||||
if (inDataSize < sizeof(AU_BiquadFilterDescription) - sizeof(AU_BiquadFilter))
|
||||
{
|
||||
break;
|
||||
}
|
||||
const AU_BiquadFilterDescription * description = static_cast<const AU_BiquadFilterDescription*>(inData);
|
||||
if (inDataSize < ((sizeof(AU_BiquadFilterDescription) - sizeof(AU_BiquadFilter) + (sizeof(AU_BiquadFilter) * description->mNumberFilters))))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (description->mNumberFilters > kMaxNumBands)
|
||||
{
|
||||
break;
|
||||
}
|
||||
const BiquadCoefficientsDescriptor * filter = static_cast<const BiquadCoefficientsDescriptor*>(static_cast<const void*>(description->mFilters));
|
||||
result = SetAE2IIRFilterCoefficients(mSidetoneEQ, description->mNumberFilters, static_cast<const BiquadCoefficientsDescriptor*>(filter));
|
||||
if (!result)
|
||||
{
|
||||
mSidetoneEQBypass = description->mBypass;
|
||||
mNumberBands = description->mNumberFilters;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = super::SetProperty(inID, inData, inDataSize);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AUSidetone::Process(const void *inSourceP,
|
||||
void *inDestP,
|
||||
UInt32 inFramesToProcess)
|
||||
{
|
||||
if (!mSidetoneEQBypass)
|
||||
{
|
||||
ProcessAE2IIRFilter(mSidetoneEQ, inFramesToProcess, inSourceP, inDestP);
|
||||
}
|
||||
ProcessVolumeInplace(mVolume, inFramesToProcess, inDestP);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* AUSidetone.h
|
||||
*
|
||||
* Created by richardp on 11/28/11.
|
||||
* Copyright 2011 Apple, Inc. All rights reserved.
|
||||
*
|
||||
* Does necessary translation between AE2 and CA AU speaker protection
|
||||
*/
|
||||
|
||||
#ifndef __AUSidetone_h__
|
||||
#define __AUSidetone_h__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "AudioUnitProperties_AE2.h"
|
||||
#include "AUBase_AE2.h"
|
||||
|
||||
struct AE2_IIRFilter;
|
||||
struct AE2_Volume;
|
||||
struct BiquadDescriptor;
|
||||
|
||||
/**
|
||||
* AUSidetone implements the sidetone eq and gain.
|
||||
*
|
||||
* These values are hard-coded for now.
|
||||
*/
|
||||
class AUSidetone : public AUBase_AE2
|
||||
{
|
||||
public:
|
||||
static AUSidetone* Create_AUSidetone(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize);
|
||||
virtual ~AUSidetone();
|
||||
|
||||
virtual void Process(const void *inSourceP,
|
||||
void *inDestP,
|
||||
UInt32 inFramesToProcess);
|
||||
|
||||
// for parameters
|
||||
virtual OSStatus SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue value);
|
||||
virtual AudioUnitParameterValue GetParameter(AudioUnitParameterID paramID);
|
||||
// for properties
|
||||
virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID, uint32_t& outDataSize, bool& outWritable);
|
||||
virtual OSStatus GetProperty(AudioUnitPropertyID inID, void* outData);
|
||||
virtual OSStatus SetProperty(AudioUnitPropertyID inID, const void* inData, uint32_t inDataSize);
|
||||
|
||||
private:
|
||||
AUSidetone();
|
||||
bool InitWith(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize);
|
||||
|
||||
// some constants
|
||||
typedef AUBase_AE2 super;
|
||||
static const size_t kMaxNumBands = 5;
|
||||
static const float kDefaultSidetoneGain = -32.0;
|
||||
|
||||
// Parameters for the AUNBandEQ unit
|
||||
// Note that the parameter IDs listed correspond to band 0 (zero) of the unit. The parameter IDs for
|
||||
// higher bands can be obtained by adding the zero-indexed band number to the corresponding band 0
|
||||
// parameter ID up to the number of bands minus one, where the number of bands is described by the
|
||||
// AUNBandEQ property kAUNBandEQProperty_NumberOfBands. For example, the parameter ID corresponding
|
||||
// to the filter type of band 4 would be kAUNBandEQParam_FilterType + 3.
|
||||
enum {
|
||||
kAUVolume_InDB = 500,
|
||||
// Global, Boolean, 0 or 1, 1
|
||||
kAUNBandEQParam_BypassBand = 1000,
|
||||
// Global, Indexed, 0->kNumAUNBandEQFilterTypes-1, 0
|
||||
kAUNBandEQParam_FilterType = 2000,
|
||||
// Global, Hz, 20->(SampleRate/2), 1000
|
||||
kAUNBandEQParam_Frequency = 3000,
|
||||
// Global, dB, -96->24, 0
|
||||
kAUNBandEQParam_Gain = 4000,
|
||||
// Global, octaves, 0.05->5.0, 0.5
|
||||
kAUNBandEQParam_Bandwidth = 5000
|
||||
};
|
||||
|
||||
uint32_t mSampleRate;
|
||||
uint32_t mNumChannels;
|
||||
AE2_IIRFilter *mSidetoneEQ;
|
||||
AE2_Volume *mVolume;
|
||||
// to hold the coefficients
|
||||
uint32_t mNumberBands;
|
||||
|
||||
BiquadDescriptor *mBiquadValues;
|
||||
|
||||
float mVolumeInDB;
|
||||
bool mSidetoneEQBypass;
|
||||
};
|
||||
|
||||
#endif // __AUSidetone_h__
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
File: AudioUnitProperties_AE2.h
|
||||
|
||||
Contains: Property constants for AudioUnits, stripped down for AE2
|
||||
|
||||
Copyright: (c) 2010 by Apple, Inc., all rights reserved.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __AUDIOUNITPROPERTIES_AE2__
|
||||
#define __AUDIOUNITPROPERTIES_AE2__
|
||||
|
||||
#include "CoreAudioTypes_AE2.h"
|
||||
#include "AUComponent_AE2.h"
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Core Implementation
|
||||
#pragma mark -
|
||||
/*!
|
||||
@enum Audio Unit scope types
|
||||
@abstract The scope IDs for audio units define basic roles and contexts for an audio unit's state.
|
||||
@discussion Each scope is a discrete context. Apple reserves scope IDs from 0 through 1024.
|
||||
|
||||
@constant kAudioUnitScope_Global The context for audio unit characteristics that apply to the audio unit as a
|
||||
whole
|
||||
@constant kAudioUnitScope_Input The context for audio data coming into an audio unit
|
||||
@constant kAudioUnitScope_Output The context for audio data leaving an audio unit
|
||||
@constant kAudioUnitScope_Group A context specific to the control scope of parameters (for instance,
|
||||
MIDI Channels is an example of this scope)
|
||||
@constant kAudioUnitScope_Part A distinct rendering context. For instance a single timbre in a multi-timbral
|
||||
instrument, a single loop in a multi looping capable looper unit, etc.
|
||||
@constant kAudioUnitScope_Layer A context which functions as a layer within a part and allows
|
||||
grouped control of Cell-scope parameters.
|
||||
An example is the percussive attack layer for an electric organ instrument
|
||||
@constant kAudioUnitScope_Note A scope that can be used to apply changes to an individual note. The
|
||||
elementID used with this scope is the unique note ID returned from
|
||||
a started note (see MusicDeviceStartNote)
|
||||
@constant kAudioUnitScope_Cell A scope which represents the finest level of granularity within an AU.
|
||||
The individual sample zones and envelope generators within a synth are an
|
||||
example of this.
|
||||
*/
|
||||
enum {
|
||||
kAudioUnitScope_Global = 0,
|
||||
kAudioUnitScope_Input = 1,
|
||||
kAudioUnitScope_Output = 2
|
||||
};
|
||||
|
||||
//=====================================================================================================================
|
||||
#pragma mark - Parameter Definitions
|
||||
|
||||
// assume kAudioUnitParameterUnit_Generic if not found in this enum
|
||||
/*!
|
||||
@enum AudioUnitParameterUnit
|
||||
@constant kAudioUnitParameterUnit_Generic
|
||||
untyped value generally between 0.0 and 1.0
|
||||
@constant kAudioUnitParameterUnit_Indexed
|
||||
takes an integer value (good for menu selections)
|
||||
@constant kAudioUnitParameterUnit_Boolean
|
||||
0.0 means FALSE, non-zero means TRUE
|
||||
@constant kAudioUnitParameterUnit_Percent
|
||||
usually from 0 -> 100, sometimes -50 -> +50
|
||||
@constant kAudioUnitParameterUnit_Seconds
|
||||
absolute or relative time
|
||||
@constant kAudioUnitParameterUnit_SampleFrames
|
||||
one sample frame equals (1.0/sampleRate) seconds
|
||||
@constant kAudioUnitParameterUnit_Phase
|
||||
-180 to 180 degrees
|
||||
@constant kAudioUnitParameterUnit_Rate
|
||||
rate multiplier, for playback speed, etc. (e.g. 2.0 == twice as fast)
|
||||
@constant kAudioUnitParameterUnit_Hertz
|
||||
absolute frequency/pitch in cycles/second
|
||||
@constant kAudioUnitParameterUnit_Cents
|
||||
unit of relative pitch
|
||||
@constant kAudioUnitParameterUnit_RelativeSemiTones
|
||||
useful for coarse detuning
|
||||
@constant kAudioUnitParameterUnit_MIDINoteNumber
|
||||
absolute pitch as defined in the MIDI spec (exact freq may depend on tuning table)
|
||||
@constant kAudioUnitParameterUnit_MIDIController
|
||||
a generic MIDI controller value from 0 -> 127
|
||||
@constant kAudioUnitParameterUnit_Decibels
|
||||
logarithmic relative gain
|
||||
@constant kAudioUnitParameterUnit_LinearGain
|
||||
linear relative gain
|
||||
@constant kAudioUnitParameterUnit_Degrees
|
||||
-180 to 180 degrees, similar to phase but more general (good for 3D coord system)
|
||||
@constant kAudioUnitParameterUnit_EqualPowerCrossfade
|
||||
0 -> 100, crossfade mix two sources according to sqrt(x) and sqrt(1.0 - x)
|
||||
@constant kAudioUnitParameterUnit_MixerFaderCurve1
|
||||
0.0 -> 1.0, pow(x, 3.0) -> linear gain to simulate a reasonable mixer channel fader response
|
||||
@constant kAudioUnitParameterUnit_Pan
|
||||
standard left to right mixer pan
|
||||
@constant kAudioUnitParameterUnit_Meters
|
||||
distance measured in meters
|
||||
@constant kAudioUnitParameterUnit_AbsoluteCents
|
||||
absolute frequency measurement :
|
||||
if f is freq in hertz then absoluteCents = 1200 * log2(f / 440) + 6900
|
||||
@constant kAudioUnitParameterUnit_Octaves
|
||||
octaves in relative pitch where a value of 1 is equal to 1200 cents
|
||||
@constant kAudioUnitParameterUnit_BPM
|
||||
beats per minute, ie tempo
|
||||
@constant kAudioUnitParameterUnit_Beats
|
||||
time relative to tempo, i.e., 1.0 at 120 BPM would equal 1/2 a second
|
||||
@constant kAudioUnitParameterUnit_Milliseconds
|
||||
parameter is expressed in milliseconds
|
||||
@constant kAudioUnitParameterUnit_Ratio
|
||||
for compression, expansion ratio, etc.
|
||||
@constant kAudioUnitParameterUnit_CustomUnit
|
||||
this is the parameter unit type for parameters that present a custom unit name
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kAudioUnitParameterUnit_Generic = 0,
|
||||
kAudioUnitParameterUnit_Indexed = 1,
|
||||
kAudioUnitParameterUnit_Boolean = 2,
|
||||
kAudioUnitParameterUnit_Percent = 3,
|
||||
kAudioUnitParameterUnit_Seconds = 4,
|
||||
kAudioUnitParameterUnit_SampleFrames = 5,
|
||||
kAudioUnitParameterUnit_Phase = 6,
|
||||
kAudioUnitParameterUnit_Rate = 7,
|
||||
kAudioUnitParameterUnit_Hertz = 8,
|
||||
kAudioUnitParameterUnit_Cents = 9,
|
||||
kAudioUnitParameterUnit_RelativeSemiTones = 10,
|
||||
kAudioUnitParameterUnit_MIDINoteNumber = 11,
|
||||
kAudioUnitParameterUnit_MIDIController = 12,
|
||||
kAudioUnitParameterUnit_Decibels = 13,
|
||||
kAudioUnitParameterUnit_LinearGain = 14,
|
||||
kAudioUnitParameterUnit_Degrees = 15,
|
||||
kAudioUnitParameterUnit_EqualPowerCrossfade = 16,
|
||||
kAudioUnitParameterUnit_MixerFaderCurve1 = 17,
|
||||
kAudioUnitParameterUnit_Pan = 18,
|
||||
kAudioUnitParameterUnit_Meters = 19,
|
||||
kAudioUnitParameterUnit_AbsoluteCents = 20,
|
||||
kAudioUnitParameterUnit_Octaves = 21,
|
||||
kAudioUnitParameterUnit_BPM = 22,
|
||||
kAudioUnitParameterUnit_Beats = 23,
|
||||
kAudioUnitParameterUnit_Milliseconds = 24,
|
||||
kAudioUnitParameterUnit_Ratio = 25,
|
||||
kAudioUnitParameterUnit_CustomUnit = 26
|
||||
};
|
||||
/*!
|
||||
@typedef AudioUnitParameterUnit
|
||||
*/
|
||||
typedef UInt32 AudioUnitParameterUnit;
|
||||
|
||||
/*!
|
||||
@struct AudioUnitParameterInfo
|
||||
@field name
|
||||
UNUSED - set to zero - UTF8 encoded C string (originally).
|
||||
@field unitName
|
||||
only valid if kAudioUnitParameterUnit_CustomUnit is set. If kAudioUnitParameterUnit_CustomUnit
|
||||
is set, this field must contain a valid CFString.
|
||||
@field clumpID
|
||||
only valid if kAudioUnitParameterFlag_HasClump
|
||||
@field cfNameString
|
||||
only valid if kAudioUnitParameterFlag_HasCFNameString
|
||||
@field unit
|
||||
if the "unit" field contains a value not in the enum above, then assume
|
||||
kAudioUnitParameterUnit_Generic
|
||||
@field minValue
|
||||
@field maxValue
|
||||
@field defaultValue
|
||||
@field flags
|
||||
Due to some vagaries about the ways in which Parameter's CFNames have been described, it was
|
||||
necessary to add a flag: kAudioUnitParameterFlag_CFNameRelease
|
||||
In normal usage a parameter name is essentially a static object, but sometimes an audio unit will
|
||||
generate parameter names dynamically.. As these are expected to be CFStrings, in that case
|
||||
the host should release those names when it is finished with them, but there was no way
|
||||
to communicate this distinction in behavior.
|
||||
Thus, if an audio unit will (or could) generate a name dynamically, it should set this flag in
|
||||
the parameter's info. The host should check for this flag, and if present, release the parameter
|
||||
name when it is finished with it.
|
||||
*/
|
||||
typedef struct AudioUnitParameterInfo
|
||||
{
|
||||
//char name[52];
|
||||
//CFStringRef unitName;
|
||||
UInt32 clumpID;
|
||||
//CFStringRef cfNameString;
|
||||
AudioUnitParameterUnit unit;
|
||||
AudioUnitParameterValue minValue;
|
||||
AudioUnitParameterValue maxValue;
|
||||
AudioUnitParameterValue defaultValue;
|
||||
UInt32 flags;
|
||||
} AudioUnitParameterInfo;
|
||||
|
||||
/*!
|
||||
@enum Audio Unit Parameter Flags
|
||||
@discussion Bit positions 18, 17, and 16 are set aside for display scales. Bit 19 is reserved.
|
||||
@constant kAudioUnitParameterFlag_CFNameRelease
|
||||
@constant kAudioUnitParameterFlag_MeterReadOnly
|
||||
@constant kAudioUnitParameterFlag_DisplayMask
|
||||
@constant kAudioUnitParameterFlag_DisplaySquareRoot
|
||||
@constant kAudioUnitParameterFlag_DisplaySquared
|
||||
@constant kAudioUnitParameterFlag_DisplayCubed
|
||||
@constant kAudioUnitParameterFlag_DisplayCubeRoot
|
||||
@constant kAudioUnitParameterFlag_DisplayExponential
|
||||
@constant kAudioUnitParameterFlag_HasClump
|
||||
@constant kAudioUnitParameterFlag_ValuesHaveStrings
|
||||
@constant kAudioUnitParameterFlag_DisplayLogarithmic
|
||||
@constant kAudioUnitParameterFlag_IsHighResolution
|
||||
@constant kAudioUnitParameterFlag_NonRealTime
|
||||
@constant kAudioUnitParameterFlag_CanRamp
|
||||
@constant kAudioUnitParameterFlag_ExpertMode
|
||||
@constant kAudioUnitParameterFlag_HasCFNameString
|
||||
@constant kAudioUnitParameterFlag_IsGlobalMeta
|
||||
@constant kAudioUnitParameterFlag_IsElementMeta
|
||||
@constant kAudioUnitParameterFlag_IsReadable
|
||||
@constant kAudioUnitParameterFlag_IsWritable
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kAudioUnitParameterFlag_CFNameRelease = (1L << 4),
|
||||
kAudioUnitParameterFlag_MeterReadOnly = (1L << 15),
|
||||
|
||||
// bit positions 18,17,16 are set aside for display scales. bit 19 is reserved.
|
||||
kAudioUnitParameterFlag_DisplayMask = (7L << 16) | (1L << 22),
|
||||
kAudioUnitParameterFlag_DisplaySquareRoot = (1L << 16),
|
||||
kAudioUnitParameterFlag_DisplaySquared = (2L << 16),
|
||||
kAudioUnitParameterFlag_DisplayCubed = (3L << 16),
|
||||
kAudioUnitParameterFlag_DisplayCubeRoot = (4L << 16),
|
||||
kAudioUnitParameterFlag_DisplayExponential = (5L << 16),
|
||||
kAudioUnitParameterFlag_HasClump = (1L << 20),
|
||||
kAudioUnitParameterFlag_ValuesHaveStrings = (1L << 21),
|
||||
kAudioUnitParameterFlag_DisplayLogarithmic = (1L << 22),
|
||||
kAudioUnitParameterFlag_IsHighResolution = (1L << 23),
|
||||
kAudioUnitParameterFlag_NonRealTime = (1L << 24),
|
||||
kAudioUnitParameterFlag_CanRamp = (1L << 25),
|
||||
kAudioUnitParameterFlag_ExpertMode = (1L << 26),
|
||||
kAudioUnitParameterFlag_HasCFNameString = (1L << 27),
|
||||
kAudioUnitParameterFlag_IsGlobalMeta = (1L << 28),
|
||||
kAudioUnitParameterFlag_IsElementMeta = (1L << 29),
|
||||
kAudioUnitParameterFlag_IsReadable = (1L << 30),
|
||||
kAudioUnitParameterFlag_IsWritable = (1L << 31)
|
||||
};
|
||||
|
||||
typedef struct AUChannelInfo {
|
||||
SInt16 inChannels;
|
||||
SInt16 outChannels;
|
||||
} AUChannelInfo;
|
||||
|
||||
//==================================================================================================
|
||||
/*
|
||||
@constant kAUSongbird_SidetoneEQBlockData
|
||||
@discussion Scope: Global
|
||||
Value Type: blob
|
||||
Access: read/write
|
||||
|
||||
A property to get/set the biquad coefficients of the AE2 SidetoneEQ block as an
|
||||
array of AU_BiquadFilterDescription, sized to be the number of stages.
|
||||
*/
|
||||
|
||||
enum {
|
||||
kAUSongbird_SidetoneEQBlockData = 10000,
|
||||
kAUSongbird_SidetoneState = 10001
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
@struct AU_BiquadFilter
|
||||
@field mBypass
|
||||
Boolean to indicate if biquad is bypassed;
|
||||
@field b0
|
||||
@field b1
|
||||
@field b2
|
||||
@field a1
|
||||
@field a2
|
||||
Fields for biquad coefficients values;
|
||||
*/
|
||||
|
||||
typedef struct AU_BiquadFilter {
|
||||
UInt32 mBypass;
|
||||
Float64 b0, b1, b2, a1, a2;
|
||||
} AU_BiquadFilter;
|
||||
|
||||
/*!
|
||||
@struct AU_BiquadFilterDescription
|
||||
kAUSongbird_SidetoneEQBlockData data structure
|
||||
@field mBypass
|
||||
Boolean to indicate if all biquads are bypassed;
|
||||
@field mNumberFilters
|
||||
Number of active filters in the sidetone eq;
|
||||
@field mFilters
|
||||
variable length sized as mNumberFilters AU_BiquadFilter structures;
|
||||
*/
|
||||
|
||||
typedef struct AU_BiquadFilterDescription {
|
||||
UInt32 mBypass;
|
||||
UInt32 mNumberFilters;
|
||||
AU_BiquadFilter mFilters[1]; // this is a variable length array of mNumberFilters elements
|
||||
} AU_BiquadFilterDescription;
|
||||
|
||||
/*!
|
||||
@struct AU_SidetoneState
|
||||
kAUSongbird_SidetoneState data structure
|
||||
@field mVolume
|
||||
Gain for Sidetone;
|
||||
@field mFilterDescription
|
||||
Filter description for sidetone;
|
||||
*/
|
||||
|
||||
typedef struct AU_SidetoneState {
|
||||
bool mBypass;
|
||||
Float32 mVolume;
|
||||
AU_BiquadFilterDescription mFilterDescription;
|
||||
} AU_SidetoneState;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* CoreAudioTypes_AE2.h
|
||||
* Stripped down version of CoreAudioTypes just for what AE2 needs
|
||||
*
|
||||
* Copyright 2010 Apple Computer. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __COREAUDIOTYPES_AE2__
|
||||
#define __COREAUDIOTYPES_AE2__
|
||||
|
||||
#define CA_PREFER_FIXED_POINT 1
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef double Float64;
|
||||
typedef float Float32;
|
||||
|
||||
typedef SInt32 OSStatus;
|
||||
typedef SInt32 ComponentResult;
|
||||
|
||||
typedef SInt16 AudioSampleType;
|
||||
typedef SInt32 AudioUnitSampleType;
|
||||
|
||||
//XXX find the place where this is really defined
|
||||
enum {
|
||||
noErr = 0
|
||||
};
|
||||
|
||||
/*!
|
||||
@struct AudioStreamBasicDescription
|
||||
@abstract This structure encapsulates all the information for describing the basic
|
||||
format properties of a stream of audio data.
|
||||
@discussion This structure is sufficient to describe any constant bit rate format that has
|
||||
channels that are the same size. Extensions are required for variable bit rate
|
||||
data and for constant bit rate data where the channels have unequal sizes.
|
||||
However, where applicable, the appropriate fields will be filled out correctly
|
||||
for these kinds of formats (the extra data is provided via separate properties).
|
||||
In all fields, a value of 0 indicates that the field is either unknown, not
|
||||
applicable or otherwise is inapproprate for the format and should be ignored.
|
||||
Note that 0 is still a valid value for most formats in the mFormatFlags field.
|
||||
|
||||
In audio data a frame is one sample across all channels. In non-interleaved
|
||||
audio, the per frame fields identify one channel. In interleaved audio, the per
|
||||
frame fields identify the set of n channels. In uncompressed audio, a Packet is
|
||||
one frame, (mFramesPerPacket == 1). In compressed audio, a Packet is an
|
||||
indivisible chunk of compressed data, for example an AAC packet will contain
|
||||
1024 sample frames.
|
||||
@field mSampleRate
|
||||
The number of sample frames per second of the data in the stream.
|
||||
@field mFormatID
|
||||
A four char code indicating the general kind of data in the stream.
|
||||
@field mFormatFlags
|
||||
Flags specific to each format.
|
||||
@field mBytesPerPacket
|
||||
The number of bytes in a packet of data.
|
||||
@field mFramesPerPacket
|
||||
The number of sample frames in each packet of data.
|
||||
@field mBytesPerFrame
|
||||
The number of bytes in a single sample frame of data.
|
||||
@field mChannelsPerFrame
|
||||
The number of channels in each frame of data.
|
||||
@field mBitsPerChannel
|
||||
The number of bits of sample data for each channel in a frame of data.
|
||||
@field mReserved
|
||||
Pads the structure out to force an even 8 byte alignment.
|
||||
*/
|
||||
struct AudioStreamBasicDescription
|
||||
{
|
||||
Float64 mSampleRate;
|
||||
UInt32 mFormatID;
|
||||
UInt32 mFormatFlags;
|
||||
UInt32 mBytesPerPacket;
|
||||
UInt32 mFramesPerPacket;
|
||||
UInt32 mBytesPerFrame;
|
||||
UInt32 mChannelsPerFrame;
|
||||
UInt32 mBitsPerChannel;
|
||||
UInt32 mReserved;
|
||||
};
|
||||
typedef struct AudioStreamBasicDescription AudioStreamBasicDescription;
|
||||
|
||||
|
||||
// SMPTETime is also defined in the CoreVideo headers.
|
||||
#if !defined(__SMPTETime__)
|
||||
#define __SMPTETime__
|
||||
|
||||
/*!
|
||||
@struct SMPTETime
|
||||
@abstract A structure for holding a SMPTE time.
|
||||
@field mSubframes
|
||||
The number of subframes in the full message.
|
||||
@field mSubframeDivisor
|
||||
The number of subframes per frame (typically 80).
|
||||
@field mCounter
|
||||
The total number of messages received.
|
||||
@field mType
|
||||
The kind of SMPTE time using the SMPTE time type constants.
|
||||
@field mFlags
|
||||
A set of flags that indicate the SMPTE state.
|
||||
@field mHours
|
||||
The number of hours in the full message.
|
||||
@field mMinutes
|
||||
The number of minutes in the full message.
|
||||
@field mSeconds
|
||||
The number of seconds in the full message.
|
||||
@field mFrames
|
||||
The number of frames in the full message.
|
||||
*/
|
||||
struct SMPTETime
|
||||
{
|
||||
SInt16 mSubframes;
|
||||
SInt16 mSubframeDivisor;
|
||||
UInt32 mCounter;
|
||||
UInt32 mType;
|
||||
UInt32 mFlags;
|
||||
SInt16 mHours;
|
||||
SInt16 mMinutes;
|
||||
SInt16 mSeconds;
|
||||
SInt16 mFrames;
|
||||
};
|
||||
typedef struct SMPTETime SMPTETime;
|
||||
|
||||
/*!
|
||||
@enum SMPTE Time Types
|
||||
@abstract Constants that describe the type of SMPTE time.
|
||||
@constant kSMPTETimeType24
|
||||
24 Frame
|
||||
@constant kSMPTETimeType25
|
||||
25 Frame
|
||||
@constant kSMPTETimeType30Drop
|
||||
30 Drop Frame
|
||||
@constant kSMPTETimeType30
|
||||
30 Frame
|
||||
@constant kSMPTETimeType2997
|
||||
29.97 Frame
|
||||
@constant kSMPTETimeType2997Drop
|
||||
29.97 Drop Frame
|
||||
@constant kSMPTETimeType60
|
||||
60 Frame
|
||||
@constant kSMPTETimeType5994
|
||||
59.94 Frame
|
||||
@constant kSMPTETimeType60Drop
|
||||
60 Drop Frame
|
||||
@constant kSMPTETimeType5994Drop
|
||||
59.94 Drop Frame
|
||||
@constant kSMPTETimeType50
|
||||
50 Frame
|
||||
@constant kSMPTETimeType2398
|
||||
23.98 Frame
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kSMPTETimeType24 = 0,
|
||||
kSMPTETimeType25 = 1,
|
||||
kSMPTETimeType30Drop = 2,
|
||||
kSMPTETimeType30 = 3,
|
||||
kSMPTETimeType2997 = 4,
|
||||
kSMPTETimeType2997Drop = 5,
|
||||
kSMPTETimeType60 = 6,
|
||||
kSMPTETimeType5994 = 7,
|
||||
kSMPTETimeType60Drop = 8,
|
||||
kSMPTETimeType5994Drop = 9,
|
||||
kSMPTETimeType50 = 10,
|
||||
kSMPTETimeType2398 = 11
|
||||
};
|
||||
|
||||
/*!
|
||||
@enum SMPTE State Flags
|
||||
@abstract Flags that describe the SMPTE time state.
|
||||
@constant kSMPTETimeValid
|
||||
The full time is valid.
|
||||
@constant kSMPTETimeRunning
|
||||
Time is running.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kSMPTETimeValid = (1 << 0),
|
||||
kSMPTETimeRunning = (1 << 1)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@struct AudioTimeStamp
|
||||
@abstract A structure that holds different representations of the same point in time.
|
||||
@field mSampleTime
|
||||
The absolute sample frame time.
|
||||
@field mHostTime
|
||||
The host machine's time base, mach_absolute_time.
|
||||
@field mRateScalar
|
||||
The ratio of actual host ticks per sample frame to the nominal host ticks
|
||||
per sample frame.
|
||||
@field mWordClockTime
|
||||
The word clock time.
|
||||
@field mSMPTETime
|
||||
The SMPTE time.
|
||||
@field mFlags
|
||||
A set of flags indicating which representations of the time are valid.
|
||||
@field mReserved
|
||||
Pads the structure out to force an even 8 byte alignment.
|
||||
*/
|
||||
struct AudioTimeStamp
|
||||
{
|
||||
Float64 mSampleTime;
|
||||
UInt64 mHostTime;
|
||||
Float64 mRateScalar;
|
||||
UInt64 mWordClockTime;
|
||||
SMPTETime mSMPTETime;
|
||||
UInt32 mFlags;
|
||||
UInt32 mReserved;
|
||||
};
|
||||
typedef struct AudioTimeStamp AudioTimeStamp;
|
||||
|
||||
/*!
|
||||
@enum AudioTimeStamp Flags
|
||||
@abstract The flags that indicate which fields in an AudioTimeStamp structure are valid.
|
||||
@constant kAudioTimeStampSampleTimeValid
|
||||
The sample frame time is valid.
|
||||
@constant kAudioTimeStampHostTimeValid
|
||||
The host time is valid.
|
||||
@constant kAudioTimeStampRateScalarValid
|
||||
The rate scalar is valid.
|
||||
@constant kAudioTimeStampWordClockTimeValid
|
||||
The word clock time is valid.
|
||||
@constant kAudioTimeStampSMPTETimeValid
|
||||
The SMPTE time is valid.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kAudioTimeStampSampleTimeValid = (1 << 0),
|
||||
kAudioTimeStampHostTimeValid = (1 << 1),
|
||||
kAudioTimeStampRateScalarValid = (1 << 2),
|
||||
kAudioTimeStampWordClockTimeValid = (1 << 3),
|
||||
kAudioTimeStampSMPTETimeValid = (1 << 4)
|
||||
};
|
||||
|
||||
/*!
|
||||
@enum Commonly Used Combinations of AudioTimeStamp Flags
|
||||
@abstract Some commonly used combinations of AudioTimeStamp flags.
|
||||
@constant kAudioTimeStampSampleHostTimeValid
|
||||
The sample frame time and the host time are valid.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kAudioTimeStampSampleHostTimeValid = (kAudioTimeStampSampleTimeValid | kAudioTimeStampHostTimeValid)
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#include "iop_au_interface.h"
|
||||
#include "AUSidetone.h"
|
||||
#include "AUNull.h"
|
||||
#include <debug.h>
|
||||
|
||||
extern "C" audio_unit_t Create_AUSidetone(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize)
|
||||
{
|
||||
#if USE_SIDETONE
|
||||
AUBase_AE2 *This = AUSidetone::Create_AUSidetone(sampleRate, numChannels, sampleSize);
|
||||
return (audio_unit_t)This;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" audio_unit_t Create_AUNull(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize)
|
||||
{
|
||||
AUBase_AE2 *This = AUNull::Create_AUNull(sampleRate, numChannels, sampleSize);
|
||||
return (audio_unit_t)This;
|
||||
}
|
||||
|
||||
extern "C" void Destroy_AudioUnit(audio_unit_t au)
|
||||
{
|
||||
AUBase_AE2 *This = (AUBase_AE2*)au;
|
||||
delete This;
|
||||
}
|
||||
|
||||
extern "C" int32_t AudioUnit_GetParameter(audio_unit_t au, uint32_t parameter, float *parameterValue)
|
||||
{
|
||||
if (!au)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
AUBase_AE2 *This = (AUBase_AE2*)au;
|
||||
*parameterValue = This->GetParameter((AudioUnitParameterID)parameter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int32_t AudioUnit_SetParameter(audio_unit_t au, uint32_t parameter, float parameterValue)
|
||||
{
|
||||
if (!au)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
AUBase_AE2 *This = (AUBase_AE2*)au;
|
||||
return This->SetParameter((AudioUnitParameterID)parameter, (AudioUnitParameterValue)parameterValue);
|
||||
}
|
||||
|
||||
extern "C" int32_t AudioUnit_GetPropertyInfo(audio_unit_t au, uint32_t propID, uint32_t *outSize, bool *outWritable)
|
||||
{
|
||||
if (!au)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
AUBase_AE2 *This = (AUBase_AE2*)au;
|
||||
return This->GetPropertyInfo(static_cast<AudioUnitPropertyID>(propID), *outSize, *outWritable);
|
||||
}
|
||||
|
||||
extern "C" int32_t AudioUnit_GetProperty(audio_unit_t au, uint32_t propID, void *outData, uint32_t *ioSize)
|
||||
{
|
||||
if (!au)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
uint32_t propSize;
|
||||
bool propWritable;
|
||||
int32_t result = AudioUnit_GetPropertyInfo(au, propID, &propSize, &propWritable);
|
||||
if (result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (propSize > *ioSize)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
*ioSize = propSize;
|
||||
AUBase_AE2 *This = (AUBase_AE2*)au;
|
||||
return This->GetProperty(static_cast<AudioUnitPropertyID>(propID), outData);
|
||||
}
|
||||
|
||||
extern "C" int32_t AudioUnit_SetProperty(audio_unit_t au, uint32_t propID, const void *inData, uint32_t inSize)
|
||||
{
|
||||
if (!au)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
uint32_t propSize;
|
||||
bool propWritable;
|
||||
int32_t result = AudioUnit_GetPropertyInfo(au, propID, &propSize, &propWritable);
|
||||
if (result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if ((!propWritable))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
AUBase_AE2 *This = (AUBase_AE2*)au;
|
||||
return This->SetProperty(static_cast<AudioUnitPropertyID>(propID), inData, inSize);
|
||||
}
|
||||
|
||||
extern "C" void AudioUnit_Process(audio_unit_t au, const void *inSourceP, void *inDestP, uint32_t inFramesToProcess)
|
||||
{
|
||||
if (!au)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
AUBase_AE2 *This = (AUBase_AE2*)au;
|
||||
This->Process(inSourceP, inDestP, inFramesToProcess);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#ifndef _IOP_AU_INTERFACE_H_
|
||||
#define _IOP_AU_INTERFACE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef void * audio_unit_t;
|
||||
|
||||
audio_unit_t Create_AUSidetone(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize);
|
||||
audio_unit_t Create_AUNull(uint32_t sampleRate, uint32_t numChannels, uint32_t sampleSize);
|
||||
|
||||
void Destroy_AudioUnit(audio_unit_t au);
|
||||
|
||||
// parameters are single values that can be adjusted
|
||||
int32_t AudioUnit_GetParameter(audio_unit_t au, uint32_t parameter, float *parameterValue);
|
||||
int32_t AudioUnit_SetParameter(audio_unit_t au, uint32_t parameter, float parameterValue);
|
||||
|
||||
// properties are blocks of data that can be adjusted, usually a private setting between user and unit
|
||||
int32_t AudioUnit_GetPropertyInfo(audio_unit_t au, uint32_t propID, uint32_t *outSize, bool *outWritable);
|
||||
int32_t AudioUnit_GetProperty(audio_unit_t au, uint32_t propID, void *outData, uint32_t *ioSize);
|
||||
int32_t AudioUnit_SetProperty(audio_unit_t au, uint32_t propID, const void *inData, uint32_t inSize);
|
||||
|
||||
void AudioUnit_Process(audio_unit_t au, const void *inSourceP, void *inDestP, uint32_t inFramesToProcess);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _IOP_AU_INTERFACE_H_
|
||||
Reference in new issue
Block a user