Hi,
Now, I have a working Audio Unit v3 host, using these objects:
AVAudioEngine *audio_engine;
AVAudioOutputNode *av_output_node;
AVAudioInputNode *av_input_node;
AVAudioUnit *av_audio_unit;
AVAudioSequencer *av_audio_sequencer;
AVAudioFormat *av_format;
You can make use of output and input node of AVAudioEngine while in offline rendering mode.
/* output node */
av_output_node = [audio_engine outputNode];
/* input node */
av_input_node = [audio_engine inputNode];
/* mixer node */
av_audio_mixer_node = [audio_engine mainMixerNode];
/* audio player and audio unit */
[audio_engine attachNode:av_audio_unit];
[audio_engine connect:av_input_node to:av_audio_unit format:av_format];
[audio_engine connect:av_audio_unit to:av_audio_mixer_node format:av_format];
[audio_engine connect:av_audio_mixer_node to:av_output_node format:av_format];
The thing with the input node is you have to provide a block before start AVAudioEngine.
input_success = [av_input_node setManualRenderingInputPCMFormat:av_format
inputBlock:^(AVAudioFrameCount inNumberOfFrames){
AudioBufferList *audio_buffer_list;
guint audio_channels;
guint i;
audio_channels = [av_format channelCount];
audio_buffer_list = (AudioBufferList *) ags_fx_audio_unit_iterate_channel_data->audio_buffer_list;
/* fill av input buffer */
if(ags_fx_audio_unit_iterate_channel_data != NULL){
if(AGS_FX_AUDIO_UNIT_AUDIO_FIXED_BUFFER_SIZE <= inNumberOfFrames){
ags_audio_buffer_util_copy_buffer_to_buffer(NULL,
audio_buffer_list->mBuffers[0].mData, 1, 0,
ags_fx_audio_unit_iterate_channel_data->input + (ags_fx_audio_unit_iterate_sub_block * AGS_FX_AUDIO_UNIT_AUDIO_FIXED_BUFFER_SIZE), 1, 0,
AGS_FX_AUDIO_UNIT_AUDIO_FIXED_BUFFER_SIZE, AGS_AUDIO_BUFFER_UTIL_COPY_FLOAT_TO_FLOAT);
}else{
ags_audio_buffer_util_copy_buffer_to_buffer(NULL,
audio_buffer_list->mBuffers[0].mData, 1, 0,
ags_fx_audio_unit_iterate_channel_data->input + (ags_fx_audio_unit_iterate_sub_block * AGS_FX_AUDIO_UNIT_AUDIO_FIXED_BUFFER_SIZE), 1, 0,
inNumberOfFrames, AGS_AUDIO_BUFFER_UTIL_COPY_FLOAT_TO_FLOAT);
}
}
return((const AudioBufferList *) audio_buffer_list);
}];
if(input_success != YES){
g_warning("set manual rendering input failed");
}