1

When I use AUGraph to implemention record and play, I want to get audio data through RenderCallback.There is a problem in remote io unit callback with error kAudioConverterErr_InvalidInputSize(1768846202),I don't know how to solve it.

Is there any other way to get audio data?

NSAssert(NewAUGraph(&_auGraph) == noErr, @"NewAUGraph failed");
const AudioComponentDescription ioComponentDesc = {
    .componentType = kAudioUnitType_Output,
    .componentSubType = kAudioUnitSubType_RemoteIO,
    .componentManufacturer = kAudioUnitManufacturer_Apple,
    .componentFlags = 0,
    .componentFlagsMask = 0
};
AUGraphAddNode(_auGraph, &ioComponentDesc, &_ioNode);

const AudioComponentDescription effectComponent = {
    .componentType = kAudioUnitType_Effect,
    .componentSubType = kAudioUnitSubType_Reverb2,
    .componentManufacturer = kAudioUnitManufacturer_Apple,
    .componentFlags = 0,
    .componentFlagsMask = 0
};
AUGraphAddNode(_auGraph, &effectComponent, &_reverbNode);

const AudioComponentDescription inConvertComponentDesc = {
    .componentType = kAudioUnitType_FormatConverter,
    .componentSubType = kAudioUnitSubType_AUConverter,
    .componentManufacturer = kAudioUnitManufacturer_Apple,
    .componentFlags = 0,
    .componentFlagsMask = 0
};
AUGraphAddNode(_auGraph, &inConvertComponentDesc, &_inConvertNode);

const AudioComponentDescription outConvertComponentDesc = {
    .componentType = kAudioUnitType_FormatConverter,
    .componentSubType = kAudioUnitSubType_AUConverter,
    .componentManufacturer = kAudioUnitManufacturer_Apple,
    .componentFlags = 0,
    .componentFlagsMask = 0
};
AUGraphAddNode(_auGraph, &outConvertComponentDesc, &_outConvertNode);

NSAssert(AUGraphOpen(_auGraph) == noErr, @"AUGraphOpen failed");
AUGraphNodeInfo(_auGraph, _ioNode, NULL, &_ioUnit);
AUGraphNodeInfo(_auGraph, _reverbNode, NULL, &_reverbUnit);
AUGraphNodeInfo(_auGraph, _inConvertNode, NULL, &_inConvertUnit);
AUGraphNodeInfo(_auGraph, _outConvertNode, NULL, &_outConvertUnit);

UInt32 enable = 1;
AudioUnitElement inputBus = 1;
AudioUnitElement outputBus = 0;
AudioUnitSetProperty(_ioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, inputBus, &enable, sizeof(enable));
AudioUnitSetProperty(_ioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, outputBus, &enable, sizeof(enable));

AudioStreamBasicDescription absd;
memset(&absd, 0, sizeof(absd));
absd.mSampleRate = 44100;
absd.mFormatID = kAudioFormatLinearPCM;
absd.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
absd.mBitsPerChannel = 16;
absd.mChannelsPerFrame = 2;
absd.mBytesPerFrame = absd.mBitsPerChannel / 8 * absd.mChannelsPerFrame;
absd.mFramesPerPacket = 1;
absd.mBytesPerPacket = absd.mBytesPerFrame;
AudioUnitSetProperty(_ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, inputBus, &absd, sizeof(absd));
AudioUnitSetProperty(_ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, outputBus, &absd, sizeof(absd));

AURenderCallbackStruct callback = {0};
callback.inputProc = audioUnitRenderCallback;
callback.inputProcRefCon = (__bridge void *)self;
AudioUnitSetProperty(_ioUnit,
                     kAudioUnitProperty_SetRenderCallback,
                     kAudioUnitScope_Input,
                     outputBus,
                     &callback,
                     sizeof(callback));
OSStatus status;

AudioStreamBasicDescription reverbABSD;
memset(&reverbABSD, 0, sizeof(reverbABSD));
reverbABSD.mSampleRate = 44100;
reverbABSD.mFormatID = kAudioFormatLinearPCM;
reverbABSD.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
reverbABSD.mBitsPerChannel = 32;
reverbABSD.mChannelsPerFrame = 2;
reverbABSD.mBytesPerFrame = reverbABSD.mBitsPerChannel / 8;
reverbABSD.mFramesPerPacket = 1;
reverbABSD.mBytesPerPacket = reverbABSD.mBytesPerFrame;
AudioUnitSetProperty(_reverbUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &reverbABSD, sizeof(reverbABSD));
AudioUnitSetProperty(_reverbUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &reverbABSD, sizeof(reverbABSD));
AudioUnitSetParameter(_reverbUnit, kReverb2Param_Gain, kAudioUnitScope_Global, 0, 20, 0);
AudioUnitSetParameter(_reverbUnit, kReverb2Param_DryWetMix, kAudioUnitScope_Global, 0, 50, 0);

status = AudioUnitSetProperty(_outConvertUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &reverbABSD, sizeof(reverbABSD));
status = AudioUnitSetProperty(_outConvertUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &absd, sizeof(absd));

AUGraphConnectNodeInput(_auGraph, _ioNode, 1, _inConvertNode, 0);
AUGraphConnectNodeInput(_auGraph, _inConvertNode, 0, _reverbNode, 0);
AUGraphConnectNodeInput(_auGraph, _reverbNode, 0, _outConvertNode, 0);
static OSStatus audioUnitRenderCallback(void *                             inRefCon,
                                        AudioUnitRenderActionFlags *       ioActionFlags,
                                        const AudioTimeStamp *             inTimeStamp,
                                        UInt32                             inBusNumber,
                                        UInt32                             inNumberFrames,
                                        AudioBufferList * __nullable       ioData)
{
    XLAudioCaptureGraph *THIS = (__bridge XLAudioCaptureGraph *)inRefCon;
    memset(ioData->mBuffers[0].mData, 0, ioData->mBuffers[0].mDataByteSize);
    
    OSStatus status = AudioUnitRender(THIS.outConvertUnit, ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData);
}

The audioUnitRenderCallback status return kAudioConverterErr_InvalidInputSize.

joy-711
  • 11
  • 2

0 Answers0