5

如何从 Objective-C 以编程方式更改音量?

我发现了这个问题,Controlling OS X volume in Snow Leopard建议这样做:

Float32 volume = 0.5;
UInt32 size = sizeof(Float32);

AudioObjectPropertyAddress address = {
    kAudioDevicePropertyVolumeScalar,
    kAudioDevicePropertyScopeOutput,
    1 // Use values 1 and 2 here, 0 (master) does not seem to work
};

OSStatus err;
err = AudioObjectSetPropertyData(kAudioObjectSystemObject, &address, 0, NULL, size, &volume);
NSLog(@"status is %i", err);

这对我没有任何作用,并打印出来status is 2003332927

我还尝试使用值2和结构,两者0的结果相同。address

我该如何解决这个问题并使其实际将音量降低到 50%?

4

3 回答 3

13

您需要先获取默认音频设备:

#import <CoreAudio/CoreAudio.h>

AudioObjectPropertyAddress getDefaultOutputDevicePropertyAddress = {
  kAudioHardwarePropertyDefaultOutputDevice,
  kAudioObjectPropertyScopeGlobal,
  kAudioObjectPropertyElementMaster
};

AudioDeviceID defaultOutputDeviceID;
UInt32 volumedataSize = sizeof(defaultOutputDeviceID);
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
                                             &getDefaultOutputDevicePropertyAddress,
                                             0, NULL,
                                             &volumedataSize, &defaultOutputDeviceID);

if(kAudioHardwareNoError != result)
{
  // ... handle error ...
}

然后,您可以在通道 1(左)和通道 2(右)上设置音量。请注意,似乎不支持通道 0(主)(set 命令返回“谁?”)

AudioObjectPropertyAddress volumePropertyAddress = {
  kAudioDevicePropertyVolumeScalar,
  kAudioDevicePropertyScopeOutput,
  1 /*LEFT_CHANNEL*/
};

Float32 volume;
volumedataSize = sizeof(volume);

result = AudioObjectSetPropertyData(defaultOutputDeviceID,
                                    &volumePropertyAddress,
                                    0, NULL,
                                    sizeof(volume), &volume);
if (result != kAudioHardwareNoError) {
  // ... handle error ...
}

希望这能回答你的问题!

于 2013-10-31T07:48:52.070 回答
1

我运行了开发人员工具(即 Xcode 的音频工具)附带的 HALLab 实用程序。这允许您为单个设备打开一个信息窗口,并且该窗口有一个显示通知的选项卡。当我更改系统音量时,我确实看到kAudioDevicePropertyVolumeScalar输出设备的每个通道的属性都发生了变化,正如 Thomas O'Dell 的回答所暗示的那样。kAudioHardwareServiceDeviceProperty_VirtualMasterVolume但是,我也看到主通道上的属性发生变化。这似乎更有希望,因为您不必为所有频道手动设置它并保持它们之间的平衡。

您将使用音频硬件服务AudioHardwareServiceSetPropertyData()中的功能在默认输出设备上进行设置。为了安全起见,您可能首先检查它是否可以使用.AudioHardwareServiceIsPropertySettable()

该属性的文档说:

kAudioHardwareServiceDeviceProperty_VirtualMasterVolume

Float32表示音量控制值的值。

此属性值的范围是 0.0(静音)到 1.0(全级别)。此属性的效果取决于与 HAL 音频对象关联的硬件设备。如果设备具有主音量控制,则此属性对其进行控制。如果设备具有单独的通道音量控件,则此属性适用于由设备的首选多通道布局标识的那些,或者如果设备只有立体声,则适用于首选立体声对。此控件保持其影响的通道之间的相对平衡。

于 2013-10-31T10:06:57.283 回答
0

您可以运行一个 bash 脚本来更改主卷。这可以防止将音频首先设置到一侧:

静音:

execlp("osascript", "osascript", "-e", "set volume output muted true", NULL);

更改音量(0-10 级):

    execlp("osascript", "osascript", "-e", "set volume 5", NULL);
于 2017-02-28T14:50:35.973 回答