xcode - 通过 Cocoa 应用程序控制 Mac 上的主音量

标签 xcode macos cocoa volume nsslider

我希望将 NSSlider 合并到 Cocoa 应用程序中来控制 Mac 的主音量。不过,我不想通过 AppleScript 来完成此操作,尽管我知道这可能更容易。

我发现这段代码应该能够做到这一点,但事实并非如此,因为自 10.5 AudioDeviceGetProperty 及其同类以来已被弃用。需要改变什么才能使这项工作正常进行?

- (float) getVolume 
{
float            b_vol;
OSStatus        err;
AudioDeviceID        device;
UInt32            size;
UInt32            channels[2];
float            volume[2];

// get device
size = sizeof device;
err = AudioObjectGetPropertyData(kAudioHardwarePropertyDefaultOutputDevice, &device, <#UInt32 inQualifierDataSize#>, <#const void *inQualifierData#>, &size, <#void *outData#>);
if(err!=noErr) 
{
    NSLog(@"audio-volume error get device");
    return 0.0;
}

// try set master volume (channel 0)
size = sizeof b_vol;
err = AudioDeviceGetProperty(device, 0, 0, kAudioDevicePropertyVolumeScalar, &size, &b_vol);    //kAudioDevicePropertyVolumeScalarToDecibels
if(noErr==err) return b_vol;

// otherwise, try seperate channels
// get channel numbers
size = sizeof(channels);
err = AudioDeviceGetProperty(device, 0, 0,kAudioDevicePropertyPreferredChannelsForStereo, &size,&channels);
if(err!=noErr) NSLog(@"error getting channel-numbers");

size = sizeof(float);
err = AudioDeviceGetProperty(device, channels[0], 0, kAudioDevicePropertyVolumeScalar, &size, &volume[0]);
if(noErr!=err) NSLog(@"error getting volume of channel %d",channels[0]);
err = AudioDeviceGetProperty(device, channels[1], 0, kAudioDevicePropertyVolumeScalar, &size, &volume[1]);
if(noErr!=err) NSLog(@"error getting volume of channel %d",channels[1]);

b_vol = (volume[0]+volume[1])/2.00;

return  b_vol;
}

- (void)setVolume:(float)involume {
OSStatus        err;
AudioDeviceID        device;
UInt32            size;
Boolean            canset    = false;
UInt32            channels[2];
//float            volume[2];

// get default device
size = sizeof device;
printf("setVolume:: value of the volume set =%lf", involume);
err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &device);
if(err!=noErr) {
    NSLog(@"audio-volume error get device");
    return;
}


// try set master-channel (0) volume
size = sizeof canset;
err = AudioDeviceGetPropertyInfo(device, 0, false, kAudioDevicePropertyVolumeScalar, &size, &canset);
if(err==noErr && canset==true) {
    size = sizeof involume;
    err = AudioDeviceSetProperty(device, NULL, 0, false, kAudioDevicePropertyVolumeScalar, size, &involume);
    return;
}

// else, try seperate channes
// get channels
size = sizeof(channels);
err = AudioDeviceGetProperty(device, 0, false, kAudioDevicePropertyPreferredChannelsForStereo, &size,&channels);
if(err!=noErr) {
    NSLog(@"error getting channel-numbers");
    return;
}

// set volume
size = sizeof(float);
err = AudioDeviceSetProperty(device, 0, channels[0], false, kAudioDevicePropertyVolumeScalar, size, &involume);
if(noErr!=err) NSLog(@"error setting volume of channel %d",channels[0]);
err = AudioDeviceSetProperty(device, 0, channels[1], false, kAudioDevicePropertyVolumeScalar, size, &involume);
if(noErr!=err) NSLog(@"error setting volume of channel %d",channels[1]);

}

提前致谢!

最佳答案

这就能解决问题 - 我只是将其从我的一个项目中复制并粘贴出来,因此存在一些无关的变量和函数,但您应该能够了解其要点:

BOOL gotMaster = NO;
BOOL gotLeft = NO;
BOOL gotRight = NO;
float volume = 1, lvolume = 1, rvolume = 1;
float inVolume = 1, inLvolume = 1, inRvolume = 1;
OSStatus result = noErr;
AudioObjectPropertyAddress thePropertyAddress;
UInt32 thePropSize = sizeof(Float32);
thePropertyAddress.mSelector = kAudioDevicePropertyVolumeScalar;
thePropertyAddress.mScope = kAudioDevicePropertyScopeOutput;    
thePropertyAddress.mElement = kAudioObjectPropertyElementMaster;
// see if the device supports volume control, if so, then get it
if (AudioObjectHasProperty(_targetDevice, &thePropertyAddress)) {
  result = AudioObjectGetPropertyData(_targetDevice, &thePropertyAddress, 0, NULL, &thePropSize, &volume);
  if (result) { cwlog("AudioDeviceManager: Error in AudioObjectGetPropertyData: %d", result); return -1; }
  gotMaster = YES;
} else {
  cwlog("AudioDeviceManager: The target device does not support getting the master volume");
}
// see if the device supports left channel volume control, if so, then get it
thePropertyAddress.mElement = 1;
if (AudioObjectHasProperty(_targetDevice, &thePropertyAddress)) {
  result = AudioObjectGetPropertyData(_targetDevice, &thePropertyAddress, 0, NULL, &thePropSize, &lvolume);
  if (result) { cwlog("AudioDeviceManager: Error in AudioObjectGetPropertyData: %d", result); return -1; }
  gotLeft = YES;
} else {
  cwlog("AudioDeviceManager: The target device does not support getting the left channel volume");
}
thePropertyAddress.mElement = 2;
// see if the device supports right channel volume control, if so, then get it
if (AudioObjectHasProperty(_targetDevice, &thePropertyAddress)) {
  result = AudioObjectGetPropertyData(_targetDevice, &thePropertyAddress, 0, NULL, &thePropSize, &rvolume);
  if (result) { cwlog("AudioDeviceManager: Error in AudioObjectGetPropertyData: %d", result); return -1; }
  gotRight = YES;
} else {
  // if the device does not support master volume control, do nothing
  cwlog("AudioDeviceManager: The target device does not support getting the right channel volume");
}
if(!gotMaster && !gotLeft && !gotRight) {
  cwlog("AudioDeviceManager: Could not get any volume settings for %s (%u)", [[self nameOfDevice:_targetDevice] UTF8String], _targetDevice);
  return -1;
}

关于xcode - 通过 Cocoa 应用程序控制 Mac 上的主音量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9230013/

相关文章:

ios - xCode unity-iphone 需要配置文件

ios - 链接器命令失败错误,xcode?

ios - 如何仅存储没有时区和实际时间的日期

macos - 任何围绕从 OSX 守护进程启动 UI 的工作

ios - Xcode 8.1 显示 'try signing in again or contact apple support to resolve account access issue' 我该怎么办?

iphone - 尝试将字符串复制到 Objective-C 中的文本字段中

objective-c - 如何将Cocoa应用程序分解为可重用的功能部分?

xcode - UITableView 动态分组单元格

objective-c - Apple 的服务实现指南 - 示例代码不起作用

objective-c - 如何找出谁调用了方法?