Audio Unit is the lowest level interface for iOS Audio and video

Support mixing, balancing, format conversion and real-time INPUT/output for recording, playing, offline rendering and real-time conversations such as voice over Internet Protocol,

Its advantages are powerful function, low delay; The disadvantage is that the cost of learning is high, difficult. Today we are going to focus on the basic usage of the Audio Unit.

1. Set AVAudioSession

NSError *error = nil;

AVAudioSession* session = [AVAudioSession sharedInstance];

[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&error];

[session setActive:YES error:nil];
Copy the code

Create a description audio unit

AudioComponentDescription desc; desc.componentType =kAudioUnitType_Output; desc.componentSubType =kAudioUnitSubType_VoiceProcessingIO; //kAudioUnitSubType_RemoteIO without echo cancellation,,kAudioUnitSubType_VoiceProcessingIO with echo cancellation desc.ponentFlags =0; desc.componentFlagsMask =0; desc.componentManufacturer =kAudioUnitManufacturer_Apple;Copy the code

3. Associated search for audio units

AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);

4. Get the audio unit instance

status = AudioComponentInstanceNew(inputComponent, &audioUnit);

5. Enable recording

UInt32 flag = 1; If falg is 1, the recording function is enabled. If the value is 0, the function is disabled. Status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));Copy the code

6. Enable the playback function

status = AudioUnitSetProperty(audioUnit,

                               kAudioOutputUnitProperty_EnableIO,

                              kAudioUnitScope_Output,

                              kOutputBus,

                              &flag,

                              sizeof(flag));
Copy the code

Create an audio stream description

AudioStreamBasicDescription audioFormat; // Audio is 44100.00 sample rate, 16bit, mono, PCM audioFormat. MSampleRate = 44100.00; audioFormat.mFormatID = kAudioFormatLinearPCM; audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; audioFormat.mFramesPerPacket = 1; audioFormat.mChannelsPerFrame = 1; audioFormat.mBitsPerChannel = 16; audioFormat.mBytesPerPacket = 2; audioFormat.mBytesPerFrame = 2;Copy the code

8. Set the audio stream description for recording and playing

8.1. Set the description of recorded audio stream

status = AudioUnitSetProperty(audioUnit,

                                  kAudioUnitProperty_StreamFormat,

                                  kAudioUnitScope_Output,

                                  kInputBus,

                                  &audioFormat,

                                  sizeof(audioFormat));

Copy the code

8.2. Set the description of the audio stream to play

status = AudioUnitSetProperty(audioUnit,

                                  kAudioUnitProperty_StreamFormat,

                                  kAudioUnitScope_Input,

                                  kOutputBus,

                                  &audioFormat,

                                  sizeof(audioFormat));

Copy the code

9. Set the callback

9.1 Setting the Recorded Callback

AURenderCallbackStruct callbackStruct;

callbackStruct.inputProc = recordingCallback;

callbackStruct.inputProcRefCon = self;



status = AudioUnitSetProperty(audioUnit,

                              kAudioOutputUnitProperty_SetInputCallback,

                              kAudioUnitScope_Global,

                              kInputBus,

                              &callbackStruct,

                              sizeof(callbackStruct));
Copy the code

9.2. Set the playback callback

callbackStruct.inputProc = playbackCallback;

callbackStruct.inputProcRefCon = self;



status = AudioUnitSetProperty(audioUnit,

                              kAudioUnitProperty_SetRenderCallback,

                              kAudioUnitScope_Global,

                              kOutputBus,

                              &callbackStruct,

                              sizeof(callbackStruct));
Copy the code

10. Callback method

10.1 Recorded callback methods

` static OSStatus recordingCallback(void *inRefCon,

                              AudioUnitRenderActionFlags *ioActionFlags,

                              const AudioTimeStamp *inTimeStamp,

                              UInt32 inBusNumber,

                              UInt32 inNumberFrames,

                              AudioBufferList *ioData) {



AudioBufferList *bufferList;

OSStatus status = AudioUnitRender([(shockmanViewController *)inRefCon audioUnit],

                                  ioActionFlags,

                                  inTimeStamp,

                                  inBusNumber,

                                  inNumberFrames,

                                  bufferList);

return noErr;
Copy the code

} `

10.2 Callback method of playback

`static OSStatus playbackCallback(void *inRefCon,

                             AudioUnitRenderActionFlags *ioActionFlags,

                             const AudioTimeStamp *inTimeStamp,

                             UInt32 inBusNumber,

                             UInt32 inNumberFrames,

                             AudioBufferList *ioData) {



return noErr;
Copy the code

} `

11. Initialize AudioUnit

status = AudioUnitInitialize(_audioUnit);

12. Start AudioUnit

OSStatus status = AudioOutputUnitStart(audioUnit);

13. Close the Audio Unit

OSStatus status = AudioOutputUnitStop(audioUnit);

Destroy the Audio Unit

AudioComponentInstanceDispose(audioUnit);

15. Set echo cancellation

//0 on, 1 off

`-(void)openOrCloseEchoCancellation:(UInt32)newEchoCancellationStatus

{

UInt32 echoCancellation;

UInt32 size = sizeof(echoCancellation);

AudioUnitGetProperty(_audioUnit,

                     kAUVoiceIOProperty_BypassVoiceProcessing,

                     kAudioUnitScope_Global,

                     0,

                     &echoCancellation,

                     &size);

if (newEchoCancellationStatus == echoCancellation)

{

    return;

}



AudioUnitSetProperty(_audioUnit,

                     kAUVoiceIOProperty_BypassVoiceProcessing,

                     kAudioUnitScope_Global,

                     0,

                     &newEchoCancellationStatus,

                     sizeof(newEchoCancellationStatus));
Copy the code

}

`