以编程方式设置默认音频输出设备的采样率

Setting sampling rate of default audio output device programmatically

我正在开发一个通过 Mac 上的默认音频设备播放声音的应用程序。我想更改默认输出设备的输出采样率和位深度,但它总是给我一个 kAudioUnitErr_PropertyNotWritable 错误代码。

这是我的测试代码:

    AudioStreamBasicDescription streamFormat;
    AudioStreamBasicDescription newStreamFormat;
    newStreamFormat.mSampleRate = 96000;        // the sample rate of the audio stream
    newStreamFormat.mFormatID = kAudioFormatLinearPCM;     // the specific encoding type of audio stream
    newStreamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger;//kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsNonMixable;
    newStreamFormat.mFramesPerPacket = 1;
    newStreamFormat.mChannelsPerFrame = 1;
    newStreamFormat.mBitsPerChannel = 24;
    newStreamFormat.mBytesPerPacket = 2;
    newStreamFormat.mBytesPerFrame = 2;
    
    UInt32 size = sizeof(AudioStreamBasicDescription);

    result = AudioUnitGetProperty(myUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &streamFormat, &size);
    
    result = AudioOutputUnitStop(myUnit);
    result = AudioUnitUninitialize(myUnit);
    
    result = AudioUnitSetProperty(myUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &newStreamFormat, size);
    result = AudioUnitInitialize(myUnit);
    result = AudioOutputUnitStart(myUnit);
    
    result = AudioUnitGetProperty(myUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &streamFormat, &size);
    result = AudioUnitGetProperty(myUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamFormat, &size);

当我在 kAudioUnitScope_Input 上调用设置流格式时,我没有收到任何错误,但是当我在 kAudioUnitScope_Output 上设置它时,如果失败并显示 属性 不可写错误。

必须可以通过编程方式执行此操作(Audio MIDI Setup 可以执行此操作),但我搜索了又搜索,但一直找不到任何解决方案。

我确实发现 this post 这意味着设置设备的输入采样率也会更新输出。我试过了,但是当我回读 属性 时,输出与我在输入中设置的不匹配。

我很确定配置设备不是输出 AudioUnit 的工作。它更像是客户端和音频设备之间的中介。这意味着 AudioUnitSetProperty() 是错误的 API。

因此,如果您想配置设备,请尝试使用 AudioObjectSetPropertyData() 函数在其上设置 kAudioDevicePropertyNominalSampleRate

然后,除非您想要无偿的速率转换,否则您可能希望通过执行您已经在做的事情来确保您的音频单元输入格式与新设备采样率匹配:在输入上调用 AudioUnitSetProperty() (数据进入音频单元)范围。