Mac OS X中的音频捕获。

时间:2020-12-01 16:45:01

I am developing an audio capture application. How to capture audio on Mac OS X using 8 kHz sampling rate with single chanel using Audio Unit API ?

我正在开发一个音频捕获应用程序。如何在Mac OS X上使用8khz的采样率,使用音频单元API,来捕获音频?

This is the code I have tried.

这是我尝试过的代码。

    Component                   component;
ComponentDescription        description;
OSStatus    err = noErr;
UInt32  param;
AURenderCallbackStruct  callback;

description.componentType = kAudioUnitType_Output;
description.componentSubType = kAudioUnitSubType_HALOutput;
description.componentManufacturer = kAudioUnitManufacturer_Apple;
description.componentFlags = 0;
description.componentFlagsMask = 0;
if(component = FindNextComponent(NULL, &description))
{
    err = OpenAComponent(component, &fAudioUnit);
    if(err != noErr)
    {
        fAudioUnit = NULL;
        return err;
    }
}
param = 1;
err = AudioUnitSetProperty(fAudioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &param, sizeof(UInt32));
if(err == noErr)
{
    param = 0;
    err = AudioUnitSetProperty(fAudioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &param, sizeof(UInt32));
}
param = sizeof(AudioDeviceID);
err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &param, &fInputDeviceID);
if(err != noErr)
{
    fprintf(stderr, "failed to get default input device\n");
    return err;
}
err = AudioUnitSetProperty(fAudioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &fInputDeviceID, sizeof(AudioDeviceID));
if(err != noErr)
{
    fprintf(stderr, "failed to set AU input device\n");
    return err;
}
callback.inputProc = AudioInputProc; 
callback.inputProcRefCon = NULL;
err = AudioUnitSetProperty(fAudioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &callback, sizeof(AURenderCallbackStruct));
param = sizeof(AudioStreamBasicDescription);
err = AudioUnitGetProperty(fAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &fDeviceFormat, &param);
if(err != noErr)
{
    printf("failed to get input device ASBD\n");
    return err;
}
fDeviceFormat.mSampleRate = 8000.0;
fDeviceFormat.mChannelsPerFrame = 1;
fDeviceFormat.mBitsPerChannel = 16;
fDeviceFormat.mFormatID = kAudioFormatLinearPCM;
fDeviceFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
err = AudioUnitSetProperty(fAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &fDeviceFormat, sizeof(AudioStreamBasicDescription));
if(err != noErr)
{
    printf( "failed to set input device ASBD= %4.4s\n",(char *)&err);
    if(err == kAudioUnitErr_FormatNotSupported)
    {
        printf("kAudioUnitErr_FormatNotSupported\n");
    }
    return err;
}
err = AudioUnitGetProperty(fAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &fDeviceFormat, &param);
if(err != noErr)
{
    printf( "failed to get input device ASBD\n");
    return err;
}   
param = sizeof(UInt32);
err = AudioUnitGetProperty(fAudioUnit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, 0, &fAudioSamples, &param);
if(err != noErr)
{
    fprintf(stderr, "failed to get audio sample size\n");
    return err;
}
err = AudioUnitInitialize(fAudioUnit);
if(err != noErr)
{
    fprintf(stderr, "failed to initialize AU\n");
    return err;
}

Here I am unable to change the sample rate and bit per samples from 32 to 16. Please any one help me to do this.

在这里,我无法改变样本速率和每样本从32到16。请大家帮我做这个。

Thanks & Regards.

感谢和问候。

3 个解决方案

#1


2  

Capture with supported format and convert it to 8000 kHz,

以支持的格式捕获并将其转换为8000 kHz,

With the above code AudioUnitSetProperty is going to be failed.

使用上述代码,AudioUnitSetProperty将会失败。

You need to create audio converter using AudioConvertNew and convert your buffer to desired format using AudioConverterConvertBuffer.

您需要使用AudioConvertNew创建音频转换器,并使用AudioConverterConvertBuffer将您的缓冲区转换为所需的格式。

#2


0  

You should check out the source code for SoundFlower. That might help to point you in the right direction.

您应该查看SoundFlower的源代码。这可能会帮助你找到正确的方向。

#3


0  

I had a similar problem, I had to modify sand box permissions. Check if your application is sand boxed, you have access to the microphone.

我有一个类似的问题,我必须修改沙箱的权限。检查你的应用程序是否为沙盒,你可以访问麦克风。

#1


2  

Capture with supported format and convert it to 8000 kHz,

以支持的格式捕获并将其转换为8000 kHz,

With the above code AudioUnitSetProperty is going to be failed.

使用上述代码,AudioUnitSetProperty将会失败。

You need to create audio converter using AudioConvertNew and convert your buffer to desired format using AudioConverterConvertBuffer.

您需要使用AudioConvertNew创建音频转换器,并使用AudioConverterConvertBuffer将您的缓冲区转换为所需的格式。

#2


0  

You should check out the source code for SoundFlower. That might help to point you in the right direction.

您应该查看SoundFlower的源代码。这可能会帮助你找到正确的方向。

#3


0  

I had a similar problem, I had to modify sand box permissions. Check if your application is sand boxed, you have access to the microphone.

我有一个类似的问题,我必须修改沙箱的权限。检查你的应用程序是否为沙盒,你可以访问麦克风。