gpt4 book ai didi

objective-c - 如何在内置输入(OSX Core音频/音频单元)上设置输入电平(增益)?

转载 作者:太空狗 更新时间:2023-10-30 03:36:28 27 4
gpt4 key购买 nike

我有一个OSX应用程序,该应用程序使用音频单元记录音频数据。可以将音频单元的输入设置为任何可用的输入源,包括内置输入。问题是,我从内置输入获得的音频经常被剪切,而在诸如Audacity(甚至Quicktime)之类的程序中,我可以调低输入电平,而不会剪切。

当然,将样本帧乘以一小部分是行不通的,因为我得到的音量较小,但是样本本身在输入时仍会被裁剪。

如何设置该内置输入的输入电平或增益以避免削波问题?

最佳答案

这对我来说可以在MacBook Pro(2011年型号)上设置输入音量。这有点时髦,我不得不尝试设置主声道音量,然后设置每个独立的立体声声道音量,直到找到有效的音量为止。查看代码中的注释,我怀疑判断您的代码是否正常的最佳方法是找到一个可以正常工作的get/set-property组合,然后执行诸如get/set(其他操作)/get之类的操作来验证您的代码是否正确二传手正在工作。

哦,我当然会指出,我不会像在这里那样在getProperty调用中依赖地址中的值保持相同。看来可行,但是在通过引用传递函数时,依靠相同的结构值绝对是不明智的做法。这当然是示例代码,因此请原谅我的懒惰。 ;)

//
// main.c
// testInputVolumeSetter
//

#include <CoreFoundation/CoreFoundation.h>
#include <CoreAudio/CoreAudio.h>

OSStatus setDefaultInputDeviceVolume( Float32 toVolume );

int main(int argc, const char * argv[]) {
OSStatus err;

// Load the Sound system preference, select a default
// input device, set its volume to max. Now set
// breakpoints at each of these lines. As you step over
// them you'll see the input volume change in the Sound
// preference panel.
//
// On my MacBook Pro setting the channel[ 1 ] volume
// on the default microphone input device seems to do
// the trick. channel[ 0 ] reports that it works but
// seems to have no effect and the master channel is
// unsettable.
//
// I do not know how to tell which one will work so
// probably the best thing to do is write your code
// to call getProperty after you call setProperty to
// determine which channel(s) work.
err = setDefaultInputDeviceVolume( 0.0 );
err = setDefaultInputDeviceVolume( 0.5 );
err = setDefaultInputDeviceVolume( 1.0 );
}

// 0.0 == no volume, 1.0 == max volume
OSStatus setDefaultInputDeviceVolume( Float32 toVolume ) {
AudioObjectPropertyAddress address;
AudioDeviceID deviceID;
OSStatus err;
UInt32 size;
UInt32 channels[ 2 ];
Float32 volume;

// get the default input device id
address.mSelector = kAudioHardwarePropertyDefaultInputDevice;
address.mScope = kAudioObjectPropertyScopeGlobal;
address.mElement = kAudioObjectPropertyElementMaster;

size = sizeof(deviceID);
err = AudioObjectGetPropertyData( kAudioObjectSystemObject, &address, 0, nil, &size, &deviceID );

// get the input device stereo channels
if ( ! err ) {
address.mSelector = kAudioDevicePropertyPreferredChannelsForStereo;
address.mScope = kAudioDevicePropertyScopeInput;
address.mElement = kAudioObjectPropertyElementWildcard;
size = sizeof(channels);
err = AudioObjectGetPropertyData( deviceID, &address, 0, nil, &size, &channels );
}

// run some tests to see what channels might respond to volume changes
if ( ! err ) {
Boolean hasProperty;

address.mSelector = kAudioDevicePropertyVolumeScalar;
address.mScope = kAudioDevicePropertyScopeInput;

// On my MacBook Pro using the default microphone input:

address.mElement = kAudioObjectPropertyElementMaster;
// returns false, no VolumeScalar property for the master channel
hasProperty = AudioObjectHasProperty( deviceID, &address );

address.mElement = channels[ 0 ];
// returns true, channel 0 has a VolumeScalar property
hasProperty = AudioObjectHasProperty( deviceID, &address );

address.mElement = channels[ 1 ];
// returns true, channel 1 has a VolumeScalar property
hasProperty = AudioObjectHasProperty( deviceID, &address );
}

// try to get the input volume
if ( ! err ) {
address.mSelector = kAudioDevicePropertyVolumeScalar;
address.mScope = kAudioDevicePropertyScopeInput;

size = sizeof(volume);
address.mElement = kAudioObjectPropertyElementMaster;
// returns an error which we expect since it reported not having the property
err = AudioObjectGetPropertyData( deviceID, &address, 0, nil, &size, &volume );

size = sizeof(volume);
address.mElement = channels[ 0 ];
// returns noErr, but says the volume is always zero (weird)
err = AudioObjectGetPropertyData( deviceID, &address, 0, nil, &size, &volume );

size = sizeof(volume);
address.mElement = channels[ 1 ];
// returns noErr, but returns the correct volume!
err = AudioObjectGetPropertyData( deviceID, &address, 0, nil, &size, &volume );
}

// try to set the input volume
if ( ! err ) {
address.mSelector = kAudioDevicePropertyVolumeScalar;
address.mScope = kAudioDevicePropertyScopeInput;

size = sizeof(volume);

if ( toVolume < 0.0 ) volume = 0.0;
else if ( toVolume > 1.0 ) volume = 1.0;
else volume = toVolume;

address.mElement = kAudioObjectPropertyElementMaster;
// returns an error which we expect since it reported not having the property
err = AudioObjectSetPropertyData( deviceID, &address, 0, nil, size, &volume );

address.mElement = channels[ 0 ];
// returns noErr, but doesn't affect my input gain
err = AudioObjectSetPropertyData( deviceID, &address, 0, nil, size, &volume );

address.mElement = channels[ 1 ];
// success! correctly sets the input device volume.
err = AudioObjectSetPropertyData( deviceID, &address, 0, nil, size, &volume );
}

return err;
}

编辑,以回答您的问题:“[我如何解决?”

在过去的五年左右的时间里,我花了很多时间使用Apple的音频代码,并且在寻找解决方案的位置和方式方面已经发展出一些直觉/过程。我和我的业务伙伴共同编写了第一代iPhone和其他一些设备的原始iHeartRadio应用程序,而我在该项目中的职责之一是音频部分,特别是为iOS编写了AAC Shoutcast流解码器/播放器。当时没有任何文档或开源示例,因此涉及大量的反复试验,我学到了很多。

无论如何,当我阅读您的问题并看到赏金时,我认为这只是悬而未决的结果(即您没有RTFM ;-)。我写了几行代码来设置volume属性,当那行不通时,我真的很感兴趣。

在过程方面,也许您会发现这很有用:

一旦知道这不是一个简单的答案,我便开始考虑如何解决问题。我知道“声音系统偏好设置”可让您设置输入增益,因此我首先用otool对其进行了拆解,以查看Apple是在使用旧的还是新的“音频工具箱”例程(发生时是新的):

尝试使用:
otool -tV /System/Library/PreferencePanes/Sound.prefPane/Contents/MacOS/Sound | bbedit
然后搜索 Audio以查看调用了哪些方法(如果您没有bbedit,则每个Mac开发人员都应使用IMO,将其转储到文件中并在其他文本编辑器中打开)。

我最熟悉旧的,过时的Audio Toolbox例程(该行业已经过时三年了),因此我看了一些Apple的Technotes。他们有一个显示如何使用最新的CoreAudio方法获取默认输入设备并设置其音量的方法,但是正如您无疑看到的那样,它们的代码无法正常工作(至少在我的MBP上如此)。

达到这一点后,我便回到了经过反复试验的事实:开始使用谷歌搜索可能涉及的关键字(例如 AudioObjectSetPropertyDatakAudioDevicePropertyVolumeScalar等),以查找示例用法。

我发现有关CoreAudio并通常使用Apple Toolbox的一件有趣的事情是,那里有很多开源代码,人们可以在其中尝试各种事情(大量的pastebins和GoogleCode项目等)。如果您愿意深入研究这些代码,则通常会直接找到答案或得到一些非常好的想法。

在搜索中,我发现最相关的东西是Apple技术说明,该技术说明显示了如何使用新的Toolbox例程获取默认输入设备和设置主输入增益(即使它在我的硬件上不起作用),并且我找到了一些代码该图显示了在输出设备上按 channel 设置增益。由于输入设备可以是多 channel 的,所以我认为这是要尝试的下一个逻辑方法。

您的问题确实很好,因为至少目前没有Apple提供的正确文档来说明如何做您所要求的。这也是愚蠢的,因为两个 channel 都报告它们设置了音量,但显然只有其中一个设置了(输入麦克风是单声道源,因此这并不奇怪,但是我认为有一个无操作 channel ,也没有关于它的文档苹果上的错误)。

当您开始使用Apple的尖端技术时,这种情况就会非常一致地发生。您可以使用他们的工具箱完成令人惊奇的事情,这将使我研究过的所有其他操作系统都无法自拔,但是花很长时间即可超越他们的文档,尤其是在您尝试做一些中等复杂的事情时。

例如,如果您决定编写内核驱动程序,则会发现IOKit上的文档严重不足。最终,您必须上线并通过源代码进行挖掘,无论是其他人的项目还是OS X的源代码,或两者兼而有之,并且很快您将得出结论,因为我知道该源实际上是最佳答案(即使StackOverflow)非常棒)。

感谢您的观点和您的项目的好运:)

关于objective-c - 如何在内置输入(OSX Core音频/音频单元)上设置输入电平(增益)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11041335/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com