I'm getting error -1 oostatus from AudioUnitRender in the following context.
The only major difference in my project is that I'm also using the Remote I/O unit for audio output. The audio output works fine. Here is my input callback and my initialization code (with error checking removed for brevity).
I have an AudioUnit with correspondent Callback working properly, But now, I need to send it to a RemoteIO, cause i'm implementing some framework who needs an RemoteIO AudioUnit to work. I have two Audio Unit.
THen... I need the same output i'm getting with this audiounit Reverb2(or mixer) but with another audiounit with type kAudioUnitSubType_RemoteIO.
I am Connecting Audio Units Together Without AU Graph or AVEngine.
I want to Record and add audio effects at the same time in iOS with audio unit.
Got error from AudioUnitRender() function
throwing -10877 ("kAudioUnitErr_InvalidElement")
from AU (0x7fb6de70af30): aufx/rvb2/appl, render err: -1
Initialization:
var desc = AudioComponentDescription()
desc.componentType = kAudioUnitType_Output
desc.componentSubType = kAudioUnitSubType_RemoteIO
desc.componentFlags = 0
desc.componentFlagsMask = 0
desc.componentManufacturer = kAudioUnitManufacturer_Apple
guard let inputComponent = AudioComponentFindNext(nil, &desc) else {
return
}
var maybeAudioUnit: AudioUnit? = nil
AudioComponentInstanceNew(inputComponent, &maybeAudioUnit)
guard let audioUnit = maybeAudioUnit else {
return
}
var one: UInt32 = 1
guard AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &one, 4) == noErr else {
AudioComponentInstanceDispose(audioUnit)
return
}
var audioStreamDescription = audioRecorderNativeStreamDescription(sampleRate: 48000)
guard AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &audioStreamDescription, UInt32(MemoryLayout<AudioStreamBasicDescription>.size)) == noErr else {
AudioComponentInstanceDispose(audioUnit)
return
}
guard AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &audioStreamDescription, UInt32(MemoryLayout<AudioStreamBasicDescription>.size)) == noErr else {
AudioComponentInstanceDispose(audioUnit)
return
}
var callbackStruct = AURenderCallbackStruct()
callbackStruct.inputProc = rendererInputProc
callbackStruct.inputProcRefCon = UnsafeMutableRawPointer(bitPattern: intptr_t(self.id))
guard AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &callbackStruct, UInt32(MemoryLayout<AURenderCallbackStruct>.size)) == noErr else {
AudioComponentInstanceDispose(audioUnit)
return
}
var zero: UInt32 = 1
guard AudioUnitSetProperty(audioUnit, kAudioUnitProperty_ShouldAllocateBuffer, kAudioUnitScope_Output, 0, &zero, 4) == noErr else {
AudioComponentInstanceDispose(audioUnit)
return
}
guard AudioUnitInitialize(audioUnit) == noErr else {
AudioComponentInstanceDispose(audioUnit)
return
}
var reverbcd = AudioComponentDescription()
reverbcd.componentType = kAudioUnitType_Effect
reverbcd.componentSubType = kAudioUnitSubType_Reverb2
reverbcd.componentManufacturer = kAudioUnitManufacturer_Apple
guard let inputComponent2 = AudioComponentFindNext(nil, &reverbcd) else {
return
}
var maybeAudioUnit2: AudioUnit? = nil
AudioComponentInstanceNew(inputComponent2, &maybeAudioUnit2)
guard let audioUnitEffect = maybeAudioUnit2 else {
return
}
let err = AudioUnitSetParameter(audioUnitEffect, kReverb2Param_Gain, kAudioUnitScope_Global, 0, 20, 0);
guard err == noErr else {
print(err)
AudioComponentInstanceDispose(audioUnitEffect)
return
}
let err1 = AudioUnitInitialize(audioUnitEffect)
guard err1 == noErr else {
print(err1)
AudioComponentInstanceDispose(audioUnitEffect)
return
}
var connection = AudioUnitConnection()
connection.destInputNumber = 0
connection.sourceAudioUnit = audioUnitEffect
connection.sourceOutputNumber = 0
let osstatus = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0, &connection, UInt32(MemoryLayout<AudioUnitConnection>.size))
guard osstatus == noErr else {
print(osstatus)
AudioComponentInstanceDispose(audioUnitEffect)
return
}
and start recoding with AudioOutputUnitStart(audioUnit) Here is the callback method.
Input callback:
private func rendererInputProc(refCon: UnsafeMutableRawPointer, ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBusNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>?) -> OSStatus {
let id = Int32(intptr_t(bitPattern: refCon))
withAudioUnitHolder(id, { (holder, queue, holderEffect) in
var buffer = AudioBuffer()
buffer.mNumberChannels = 1;
buffer.mDataByteSize = inNumberFrames * 2;
buffer.mData = malloc(Int(inNumberFrames) * 2)
var bufferList = AudioBufferList(mNumberBuffers: 1, mBuffers: buffer)
var status = noErr
holder.with { audioUnit in
if let audioUnit = audioUnit {
status = AudioUnitRender(audioUnit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList)
} else {
status = kAudioUnitErr_FailedInitialization
}
}
var status2 = noErr
holderEffect.with { audioUnitEffect in
if let audioUnitEffect = audioUnitEffect {
status2 = AudioUnitRender(audioUnitEffect, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList)
} else {
status2 = kAudioUnitErr_FailedInitialization
}
}
print(status2)
if status == noErr {
queue.async {
withAudioRecorderContext(id, { context in
if let context = context {
context.processAndDisposeAudioBuffer(buffer)
} else {
free(buffer.mData)
}
})
}
} else {
free(buffer.mData)
Logger.shared.log("ManagedAudioRecorder", "AudioUnitRender returned \(status)")
}
})
return noErr
}
Can someone please guide me how to connect RemoteIO (kAudioUnitType_Output) unit with the effect unit (kAudioUnitType_Effect) to play audio file with effect.