如何在 Mac 上设置录制和播放音频。 Mac 上的 VOIP 应用程序

Posted

技术标签:

【中文标题】如何在 Mac 上设置录制和播放音频。 Mac 上的 VOIP 应用程序【英文标题】:How to setup for record and playback audio on Mac. VOIP app on Mac 【发布时间】:2016-12-13 18:19:05 【问题描述】:

我想在 Mac 中录制和播放音频。现在,我对 Input/Output/ChannelFormat 的设置有一些问题……我向您展示了我在下面尝试的一些代码。

// Setup audio device
- (OSStatus) setupAudioDevice  // It's oks
    AudioComponentDescription desc;
    AudioComponent comp;

    desc.componentType = kAudioUnitType_Output;
    desc.componentSubType = kAudioUnitSubType_VoiceProcessingIO; // This type support for both ios and Mac

    desc.componentManufacturer = kAudioUnitManufacturer_Apple;
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;

    comp = AudioComponentFindNext(NULL, &desc);
    if (comp == NULL)
    
        return -1;
    

    OSStatus err = AudioComponentInstanceNew(comp, &audioUnit);
    checkStatus(err);

    return err;


//Enable IO
//https://developer.apple.com/library/prerelease/content/technotes/tn2091/_index.html
- (OSStatus) setupEnableIO  // It's ok
    UInt32 enableIO;

    //When using AudioUnitSetProperty the 4th parameter in the method
    //refer to an AudioUnitElement. When using an AudioOutputUnit
    //the input element will be '1' and the output element will be '0'.


    enableIO = 1;
    OSStatus err = AudioUnitSetProperty(audioUnit,
                         kAudioOutputUnitProperty_EnableIO,
                         kAudioUnitScope_Input,
                         kInputBus, // input element
                         &enableIO,
                         sizeof(enableIO));

    checkStatus(err);

    enableIO = 0;
    err = AudioUnitSetProperty(audioUnit,
                         kAudioOutputUnitProperty_EnableIO,
                         kAudioUnitScope_Output,
                         kOutputBus,   //output element
                         &enableIO,
                         sizeof(enableIO));
    checkStatus(err);

    return err;


// Setup Microphone
- (OSStatus) setupMicInput  // It's ok
    AudioObjectPropertyAddress addr;
    UInt32 size = sizeof(AudioDeviceID);
    AudioDeviceID deviceID = 0;

    addr.mSelector = kAudioHardwarePropertyDefaultInputDevice;
    addr.mScope = kAudioObjectPropertyScopeGlobal;
    addr.mElement = kAudioObjectPropertyElementMaster;

    OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, 0, NULL, &size, &deviceID);
    checkStatus(err);

    if (err == noErr) 
        err = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceID, size);
    

    checkStatus(err);
    int m_valueCount = deviceID / sizeof(AudioValueRange) ;
    NSLog(@"Available %d Sample Rates\n",m_valueCount);

    NSLog(@"DeviceName: %@",[self deviceName:deviceID]);
    NSLog(@"BufferSize: %d",[self bufferSize:deviceID]);

    return err;


// Setup Input format
- (OSStatus)setupInputFormat 
    AudioStreamBasicDescription audioFormat;// = [EZAudioUtilities monoFloatFormatWithSampleRate:SampleRate]
    audioFormat.mSampleRate         = SampleRate;
    audioFormat.mFormatID           = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags        =  kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
    audioFormat.mFramesPerPacket    = 1;
    audioFormat.mChannelsPerFrame   = 1;
    audioFormat.mBitsPerChannel     = 8 * sizeof(UInt32);
    audioFormat.mBytesPerPacket     = sizeof(UInt32);
    audioFormat.mBytesPerFrame      = sizeof(UInt32);

    UInt32 size = sizeof(AudioStreamBasicDescription);

    // Apply format
    OSStatus err = AudioUnitSetProperty(audioUnit,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Input,
                                  0,
                                  &audioFormat,
                                  size);
    checkStatus(err);

    err = AudioUnitSetProperty(audioUnit,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Output,
                                  1,
                                  &audioFormat,
                                  size);
    checkStatus(err);

    return err;


//Setup Input Callback
- (OSStatus)setupInputCallback 
    AURenderCallbackStruct callbackStruct;
    callbackStruct.inputProc = recordingCallback;
    callbackStruct.inputProcRefCon = (__bridge void * _Nullable)(self);

    UInt32 size = sizeof(AURenderCallbackStruct);
    OSStatus err = AudioUnitSetProperty(audioUnit,
                                  kAudioOutputUnitProperty_SetInputCallback,
                                  kAudioUnitScope_Global,
                                  0,
                                  &callbackStruct,
                                  size);
    checkStatus(err);

    return err;


//Setup Output Playback
- (OSStatus)setupRenderPlayback 
    // Set output callback
    AURenderCallbackStruct callbackStruct;
    callbackStruct.inputProc = playbackCallback;
    callbackStruct.inputProcRefCon = (__bridge void * _Nullable)(self); 
    UInt32 size = sizeof(AURenderCallbackStruct);
    OSStatus err = AudioUnitSetProperty(audioUnit,
                                  kAudioUnitProperty_SetRenderCallback,
                                  kAudioUnitScope_Input,
                                  1,
                                  &callbackStruct,
                                  size);
    checkStatus(err);
    return err; 

I try to follow this suggestion。但它仍然不起作用。 Here is my example project

【问题讨论】:

所以你展示了所有方便的方法,但你没有展示如何以及何时调用它们。请显示使用这些方法的代码。还有什么是行不通的?有错误吗? @rocky 我在这里发布了我的测试项目github.com/longpham2310/audio-unit-mac-example。你能看看吗! 【参考方案1】:

我认为你应该检查 kAudioFormatLinearPCM 是 signed16 还是 signed32,le 还是 be 那么

audioFormat.mBitsPerChannel     = 8 * sizeof(UInt32);
audioFormat.mBytesPerPacket     = sizeof(UInt32);
audioFormat.mBytesPerFrame      = sizeof(UInt32);

应该相应改变

【讨论】:

以上是关于如何在 Mac 上设置录制和播放音频。 Mac 上的 VOIP 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

使用 OBJC 在 Mac 上录制音频

电脑内部声音怎么录制 Mac在线录制音频

在 Mac 上录制音频

Swift 4 - 在 mac os 上使用 AVAssetWriter 进行 avfoundation 屏幕和音频录制 - 视频冻结

在 Mac 上使用 OpenAL 播放音频时出现随机噪音

mac上录制无声mp3