示例代码: XBVoiceTool
步骤:
1.设置AVAudioSession
2.初始化audioUnit
3.设置输出流格式
4.开启麦克风输入
5.设置回调
6.在回调中获取录音数据
设置AVAudioSession
//设置session
NSError *error = nil;
AVAudioSession* session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&error];
[session setActive:YES error:nil];
初始化audioUnit
//初始化audioUnit
AudioComponentDescription inputDesc;
inputDesc.componentType = kAudioUnitType_Output;
inputDesc.componentSubType = kAudioUnitSubType_RemoteIO;
inputDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
inputDesc.componentFlags = 0;
inputDesc.componentFlagsMask = 0;
AudioComponent inputComponent = AudioComponentFindNext(NULL, &inputDesc);
AudioComponentInstanceNew(inputComponent, &audioUnit);
设置输出流格式
//设置输出格式
int mFramesPerPacket = 1;
int mBytesPerFrame = bit * channel / 8;
AudioStreamBasicDescription inputStreamDesc;
inputStreamDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagIsPacked;
inputStreamDesc.mFormatID = kAudioFormatLinearPCM;
inputStreamDesc.mSampleRate = rate;
inputStreamDesc.mFramesPerPacket = mFramesPerPacket;
inputStreamDesc.mBitsPerChannel = bit;
inputStreamDesc.mChannelsPerFrame = channel;
inputStreamDesc.mBytesPerFrame = mBytesPerFrame;
inputStreamDesc.mBytesPerPacket = mFramesPerPacket * mBytesPerFrame;
OSStatus status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
kInputBus,
&inputStreamDesc,
sizeof(inputStreamDesc));
CheckError(status, "setProperty StreamFormat error");
开启麦克风输入
int inputEnable = 1;
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
kInputBus,
&inputEnable,
sizeof(inputEnable));
CheckError(status, "setProperty EnableIO error");
设置回调
//设置回调
AURenderCallbackStruct inputCallBackStruce;
inputCallBackStruce.inputProc = inputCallBackFun;
inputCallBackStruce.inputProcRefCon = (__bridge void * _Nullable)(self);
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Output,
kInputBus,
&inputCallBackStruce,
sizeof(inputCallBackStruce));
CheckError(status, "setProperty InputCallback error");
在回调中获取录音数据
这里获取录音数据后,通过recorder的bl_output提供给外部
static OSStatus inputCallBackFun( void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * __nullable ioData)
{
XBAudioUnitRecorder *recorder = (__bridge XBAudioUnitRecorder *)(inRefCon);
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mData = NULL;
bufferList.mBuffers[0].mDataByteSize = 0;
AudioUnitRender(recorder->audioUnit,
ioActionFlags,
inTimeStamp,
kInputBus,
inNumberFrames,
&bufferList);
if (recorder.bl_outputBlock)
{
recorder.bl_outputBlock(&bufferList);
}
// AudioBuffer buffer = bufferList.mBuffers[0];
// NSData *pcmBlock = [NSData dataWithBytes:buffer.mData length:buffer.mDataByteSize];
//
// NSLog(@"------->>数据%@",pcmBlock);
// NSString *savePath = stroePath;
// if ([[NSFileManager defaultManager] fileExistsAtPath:savePath] == false)
// {
// [[NSFileManager defaultManager] createFileAtPath:savePath contents:nil attributes:nil];
// }
// NSFileHandle * handle = [NSFileHandle fileHandleForWritingAtPath:savePath];
// [handle seekToEndOfFile];
// [handle writeData:pcmBlock];
return noErr;
}