AudioComponentInstance getComponentInstance(OSType type,OSType subType){
AudioComponentDescription desc = {0};
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentSubType = subType;
desc.componentType = type;
AudioComponent ioComponent = AudioComponentFindNext(NULL, &desc);
AudioComponentInstance unit;
AudioComponentInstanceNew(ioComponent, &unit);
return unit;
}
-(void)setUpAudioUnits:(BOOL)offline{
AudioComponentInstance ioUnit = getComponentInstance(kAudioUnitType_Output, kAudioUnitSubType_DefaultOutput);
AudioComponentInstance lowPass = getComponentInstance(kAudioUnitType_Effect, kAudioUnitSubType_LowPassFilter);
AURenderCallbackStruct cbStruct = {renderCallback,(__bridge void *)self};
AudioUnitSetProperty(lowPass, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &cbStruct, sizeof(AURenderCallbackStruct));
AudioUnitInitialize(lowPass);
if (offline) {
AudioBufferList *bufferlist = malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer));//stereo bufferlist
float *left = malloc(sizeof(float) * 1024);
float *right = malloc(sizeof(float) * 1024);
bufferlist->mBuffers[0].mData = left;
bufferlist->mBuffers[1].mData = right;
AudioTimeStamp inTimeStamp;
memset(&inTimeStamp, 0, sizeof(AudioTimeStamp));
inTimeStamp.mFlags = kAudioTimeStampSampleTimeValid;
inTimeStamp.mSampleTime = 0;
AudioUnitRenderActionFlags flag = 0;
for (int i = 0; i < 30; i++) {
bufferlist->mBuffers[0].mDataByteSize = sizeof(float) * 1024;
bufferlist->mBuffers[1].mDataByteSize = sizeof(float) * 1024;
bufferlist->mNumberBuffers = 2;
AudioUnitRender(lowPass, &flag, &inTimeStamp, 0, 1024, bufferlist);
inTimeStamp.mSampleTime += 1024;
}
}
else{
AudioUnitConnection lowPassConn = {0};
lowPassConn.destInputNumber = 0;
lowPassConn.sourceAudioUnit = lowPass;
lowPassConn.sourceOutputNumber = 0;
AudioUnitSetProperty(ioUnit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0, &lowPassConn, sizeof(AudioUnitConnection));
AudioUnitInitialize(ioUnit);
AudioOutputUnitStart(ioUnit);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
AudioUnitSetParameter(lowPass, kLowPassParam_CutoffFrequency, kAudioUnitScope_Global, 0, 200, 0);
});
}
}
OSStatus renderCallback(void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData){
ViewController *self = (__bridge ViewController*)inRefCon;
float *data = "" style="color:rgb(112,61,170)">mBuffers[0].mData;
float *data2 = ioData->mBuffers[1].mData;
for (int i = 0; i < inNumberFrames; i++) {
if (self->increasing) {
self->mySample += 0.01;
if (self->mySample > 1) {
self->increasing = 0;
}
}
else{
self->mySample -= 0.01;
if (self->mySample < -1) {
self->increasing = 1;
}
}
data[i] = self->mySample;
data2[i] = self->mySample;
}
printf("render %f to %f\n",inTimeStamp->mSampleTime,inTimeStamp->mSampleTime + inNumberFrames);
return noErr;
}