Mac os 使用Audio Unit 采集音频

2022-04-28  本文已影响0人  huGh11

需要使用的头文件

#include <AudioUnit/AudioUnit.h>

设置+初始化

    OSStatus status;

    AudioComponentDescription desc;
    desc.componentType = kAudioUnitType_Output;
    desc.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;

    AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);

    status = AudioComponentInstanceNew(inputComponent, &audioUnit);

    UInt32 size = 0;
    

    AudioStreamBasicDescription audioFormat = {0};
    audioFormat.mSampleRate = start_frequency; // 这里是对应的采样率
    audioFormat.mFormatID = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
    audioFormat.mFramesPerPacket = 1;
    audioFormat.mChannelsPerFrame = 1;
    audioFormat.mBitsPerChannel = 16;
    audioFormat.mBytesPerPacket = 2;
    audioFormat.mBytesPerFrame = 2; 

    // 申请格式
    status = AudioUnitSetProperty(audioUnit,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Output,
                                  kInputBus,
                                  &audioFormat,
                                  sizeof(audioFormat));

    

    // 设置回调函数
    AURenderCallbackStruct callbackStruct;
    callbackStruct.inputProc = recordingCallback; // 回调函数
    callbackStruct.inputProcRefCon = (__bridge void *)(self);
    status = AudioUnitSetProperty(audioUnit,
                                  kAudioOutputUnitProperty_SetInputCallback,
                                  kAudioUnitScope_Global,
                                  kInputBus,
                                  &callbackStruct,
                                  sizeof(callbackStruct));
    
    UInt32 preferredBufferSize = (( 20 * audioFormat.mSampleRate) / 1000); // in bytes
    size = sizeof (preferredBufferSize);

    // Mac OS 设置
    status = AudioUnitSetProperty (audioUnit,
                                   kAudioDevicePropertyBufferFrameSize,
                                   kAudioUnitScope_Global,
                                   0,
                                   &preferredBufferSize,
                                   size);
    
    status = AudioUnitGetProperty (audioUnit,
                                   kAudioDevicePropertyBufferFrameSize,
                                   kAudioUnitScope_Global,
                                   0,
                                   &preferredBufferSize,
                                   &size);
    
    // 检查
    size = sizeof(audioFormat);
    status = AudioUnitGetProperty( audioUnit,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Output,
                                  kInputBus,
                                  &audioFormat,
                                  &size);


    // 初始化
    status = AudioUnitInitialize(audioUnit);
// 回调函数
static OSStatus recordingCallback(void *inRefCon,
                                  AudioUnitRenderActionFlags *ioActionFlags,
                                  const AudioTimeStamp *inTimeStamp,
                                  UInt32 inBusNumber,
                                  UInt32 inNumberFrames,
                                  AudioBufferList *ioData) {
          // 这里就可以对数据进行操作了
}

开始

    OSStatus status = AudioOutputUnitStart(audioUnit);
    checkStatus(status);  // 检查status == 0 为成功

结束

   OSStatus status =  AudioOutputUnitStop(audioUnit);
    checkStatus(status);

建议在回调函数里把数据写到本地然后用FFMpeg播放一下看看采集到的数据是否正确

上一篇下一篇

猜你喜欢

热点阅读