AudioUnitGeneratorExample/AUPinkNoise.cpp
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
Pink Noise AU |
*/ |
#include "AUPinkNoise.h" |
#include "AUBaseHelper.h" |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
AUDIOCOMPONENT_ENTRY(AUBaseFactory, AUPinkNoise) |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
AUPinkNoise::AUPinkNoise(AudioUnit component) |
: AUBase(component, 0, 1), |
mPink (NULL) |
{ |
CreateElements(); |
Globals()->UseIndexedParameters(kNumberOfParameters); |
SetParameter(kParam_Volume, kAudioUnitScope_Global, 0, kDefaultValue_Volume, 0); |
SetParameter(kParam_On, kAudioUnitScope_Global, 0, 1, 0); |
} |
void AUPinkNoise::Cleanup() |
{ |
delete mPink; |
mPink = NULL; |
} |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
OSStatus AUPinkNoise::Initialize() |
{ |
const CAStreamBasicDescription & theDesc = GetStreamFormat(kAudioUnitScope_Output, 0); |
mPink = new PinkNoiseGenerator::PinkNoiseGenerator(theDesc.mSampleRate); |
return noErr; |
} |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
OSStatus AUPinkNoise::GetPropertyInfo ( AudioUnitPropertyID inID, |
AudioUnitScope inScope, |
AudioUnitElement inElement, |
UInt32 & outDataSize, |
Boolean & outWritable) |
{ |
if (inScope == kAudioUnitScope_Global) |
{ |
switch (inID) |
{ |
case kAudioUnitProperty_CocoaUI: |
outWritable = false; |
outDataSize = sizeof(AudioUnitCocoaViewInfo); |
return noErr; |
default: |
return kAudioUnitErr_InvalidProperty; |
} |
} |
return AUBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable); |
} |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
OSStatus AUPinkNoise::GetProperty ( AudioUnitPropertyID inID, |
AudioUnitScope inScope, |
AudioUnitElement inElement, |
void * outData) |
{ |
if (inScope == kAudioUnitScope_Global) |
{ |
switch (inID) |
{ |
case kAudioUnitProperty_CocoaUI: |
{ |
CFURLRef bundleURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, |
CFSTR("/System/Library/Frameworks/CoreAudioKit.framework"), |
kCFURLPOSIXPathStyle, |
TRUE); |
if (bundleURL == NULL) return fnfErr; |
CFStringRef className = CFSTR("AUGenericViewFactory"); |
AudioUnitCocoaViewInfo cocoaInfo = { bundleURL, { className } }; |
*((AudioUnitCocoaViewInfo *)outData) = cocoaInfo; |
return noErr; |
} |
} |
} |
return AUBase::GetProperty (inID, inScope, inElement, outData); |
} |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
OSStatus AUPinkNoise::GetParameterInfo(AudioUnitScope inScope, |
AudioUnitParameterID inParameterID, |
AudioUnitParameterInfo &outParameterInfo ) |
{ |
OSStatus result = noErr; |
outParameterInfo.flags = kAudioUnitParameterFlag_IsWritable |
| kAudioUnitParameterFlag_IsReadable; |
if (inScope == kAudioUnitScope_Global) { |
switch(inParameterID) |
{ |
case kParam_Volume: |
AUBase::FillInParameterName (outParameterInfo, kParameterVolumeName, false); |
outParameterInfo.unit = kAudioUnitParameterUnit_LinearGain; |
outParameterInfo.minValue = 0.0; |
outParameterInfo.maxValue = 1; |
outParameterInfo.defaultValue = kDefaultValue_Volume; |
outParameterInfo.flags |= kAudioUnitParameterFlag_DisplaySquareRoot; |
break; |
case kParam_On: |
AUBase::FillInParameterName (outParameterInfo, kParameterOnName, false); |
outParameterInfo.unit = kAudioUnitParameterUnit_Boolean; |
outParameterInfo.minValue = 0.0; |
outParameterInfo.maxValue = 1; |
outParameterInfo.defaultValue = 1; |
break; |
default: |
result = kAudioUnitErr_InvalidParameter; |
break; |
} |
} else { |
result = kAudioUnitErr_InvalidParameter; |
} |
return result; |
} |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
bool AUPinkNoise::StreamFormatWritable( AudioUnitScope scope, |
AudioUnitElement element) |
{ |
return IsInitialized() ? false : true; |
} |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
UInt32 AUPinkNoise::SupportedNumChannels ( const AUChannelInfo** outInfo) |
{ |
static const AUChannelInfo sChannels[1] = { {0, -1} }; |
if (outInfo) *outInfo = sChannels; |
return sizeof (sChannels) / sizeof (AUChannelInfo); |
} |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
UInt32 AUPinkNoise::GetChannelLayoutTags( AudioUnitScope scope, |
AudioUnitElement element, |
AudioChannelLayoutTag * outLayoutTags) |
{ |
if (scope != kAudioUnitScope_Output) COMPONENT_THROW(kAudioUnitErr_InvalidScope); |
if (element != 0) COMPONENT_THROW(kAudioUnitErr_InvalidElement); |
if (outLayoutTags) |
{ |
UInt32 numChannels = GetOutput(element)->GetStreamFormat().NumberChannels(); |
if(numChannels == 1) |
outLayoutTags[0] = kAudioChannelLayoutTag_Mono; |
else if(numChannels == 2) |
outLayoutTags[0] = kAudioChannelLayoutTag_Stereo; |
else if(numChannels == 4) |
outLayoutTags[0] = kAudioChannelLayoutTag_Quadraphonic; |
else if(numChannels == 5) |
outLayoutTags[0] = kAudioChannelLayoutTag_Pentagonal; |
else if(numChannels == 6) |
outLayoutTags[0] = kAudioChannelLayoutTag_Hexagonal; |
else if(numChannels == 8) |
outLayoutTags[0] = kAudioChannelLayoutTag_Octagonal; |
else |
COMPONENT_THROW(kAudioUnitErr_InvalidPropertyValue); |
} |
return 1; |
} |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
UInt32 AUPinkNoise::GetAudioChannelLayout( AudioUnitScope scope, |
AudioUnitElement element, |
AudioChannelLayout * outLayoutPtr, |
Boolean & outWritable) |
{ |
if (scope != kAudioUnitScope_Output) COMPONENT_THROW(kAudioUnitErr_InvalidScope); |
if (element != 0) COMPONENT_THROW(kAudioUnitErr_InvalidElement); |
UInt32 size = mOutputChannelLayout.IsValid() ? mOutputChannelLayout.Size() : 0; |
if (size > 0 && outLayoutPtr) |
memcpy(outLayoutPtr, mOutputChannelLayout, size); |
outWritable = true; |
return size; |
} |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
OSStatus AUPinkNoise::SetAudioChannelLayout( AudioUnitScope scope, |
AudioUnitElement element, |
const AudioChannelLayout * inLayout) |
{ |
if (scope != kAudioUnitScope_Output) return kAudioUnitErr_InvalidScope; |
if (element != 0) return kAudioUnitErr_InvalidElement; |
UInt32 layoutChannels = inLayout ? CAAudioChannelLayout::NumberChannels(*inLayout) : 0; |
if (inLayout != NULL && GetOutput(element)->GetStreamFormat().NumberChannels() != layoutChannels) |
return kAudioUnitErr_InvalidPropertyValue; |
if (inLayout) |
mOutputChannelLayout = inLayout; |
else |
mOutputChannelLayout = CAAudioChannelLayout(); |
return noErr; |
} |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
OSStatus AUPinkNoise::RemoveAudioChannelLayout(AudioUnitScope scope, AudioUnitElement element) |
{ |
if (scope != kAudioUnitScope_Output) return kAudioUnitErr_InvalidScope; |
if (element != 0) return kAudioUnitErr_InvalidElement; |
mOutputChannelLayout = CAAudioChannelLayout(); |
return noErr; |
} |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
OSStatus AUPinkNoise::Render( AudioUnitRenderActionFlags &ioActionFlags, |
const AudioTimeStamp & inTimeStamp, |
UInt32 nFrames) |
{ |
AUOutputElement* outputBus = GetOutput(0); |
outputBus->PrepareBuffer(nFrames); // prepare the output buffer list |
AudioBufferList& outputBufList = outputBus->GetBufferList(); |
AUBufferList::ZeroBuffer(outputBufList); |
// only render if the on parameter is true. Otherwise send the zeroed buffer |
if (Globals()->GetParameter(kParam_On)) |
{ |
for (UInt32 i=0; i < outputBufList.mNumberBuffers; i++) |
mPink->Render((Float32*)outputBufList.mBuffers[i].mData, nFrames, Globals()->GetParameter(kParam_Volume)); |
} |
return noErr; |
} |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-02-19