OSStatus callback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) {
AudioBufferList list;
// redundant
list.mNumberBuffers = 1;
list.mBuffers[0].mData = sampleBuffer;
list.mBuffers[0].mDataByteSize = 2 * inNumberFrames;
list.mBuffers[0].mNumberChannels = 1;
ioData = &list;
AudioUnitRender(instance, ioActionFlags, inTimeStamp, 1, inNumberFrames, ioData);
// the sample buffer now contains samples you can work with
return 0;
}
void init() {
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
desc.componentManufacturer = 0;
AudioComponent component = AudioComponentFindNext(NULL, &desc);
AudioComponentInstanceNew(component, &instance);
UInt32 enableIO;
sampleBuffer = malloc(4 * 1024);
enableIO = 1;
AudioUnitSetProperty(instance,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
1, // input element
&enableIO,
sizeof(enableIO));
enableIO = 0;
AudioUnitSetProperty(instance,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
0, //output element
&enableIO,
sizeof(enableIO));
UInt32 shouldAllocateBuffer = 1;
AudioUnitSetProperty(instance, kAudioUnitProperty_ShouldAllocateBuffer, kAudioUnitScope_Global, 1, &shouldAllocateBuffer, sizeof(shouldAllocateBuffer));
AudioStreamBasicDescription format;
format.mBitsPerChannel = 16;
format.mBytesPerFrame = 2;
format.mBytesPerPacket = 2;
format.mChannelsPerFrame = 1;
format.mFormatFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; //kAudioFormatFlagsCanonical + (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift);
format.mFormatID = kAudioFormatLinearPCM;
format.mFramesPerPacket = 1;
format.mReserved = 0;
format.mSampleRate = 8000.0;
//set format to output scope
err = AudioUnitSetProperty(instance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &format, sizeof(AudioStreamBasicDescription));
AURenderCallbackStruct callback_struct;
callback_struct.inputProc = callback;
callback_struct.inputProcRefCon = instance;
err = AudioUnitSetProperty(instance, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &callback_struct, sizeof(callback_struct));
err = AudioUnitInitialize(instance);
err = AudioOutputUnitStart(instance);
}