0

我正在开发一个音频捕获应用程序。如何使用 Audio Unit API 在 Mac OS X 上使用 8 kHz 采样率和单通道捕获音频?

这是我尝试过的代码。

    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;
}

在这里,我无法将采样率和每个样本的位数从 32 更改为 16。请任何人帮助我做到这一点。

感谢和问候。

4

3 回答 3

2

Capture with supported format and convert it to 8000 kHz,

With the above code AudioUnitSetProperty is going to be failed.

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

于 2012-08-21T07:15:38.140 回答
0

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

于 2011-11-23T20:45:48.450 回答
0

我有类似的问题,我不得不修改沙盒权限。检查您的应用程序是否是沙盒,您可以访问麦克风。

于 2013-05-09T22:19:09.817 回答