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
}
`