IOS Audio Unit录音


示例代码: 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;
}

你可能感兴趣的:(IOS Audio Unit录音)