Xcode 通过Cocoa应用程序控制Mac上的主卷

Xcode 通过Cocoa应用程序控制Mac上的主卷,xcode,macos,cocoa,volume,nsslider,Xcode,Macos,Cocoa,Volume,Nsslider,我希望将NSSlider合并到控制Mac主卷的Cocoa应用程序中。我不想通过AppleScript实现这一点,尽管我知道这可能更容易 我发现这段代码应该能够做到这一点,但没有做到,因为自10.5 AudioDeviceGetProperty及其同类产品被弃用以来。要使这项工作发挥作用,需要改变什么 - (float) getVolume { float b_vol; OSStatus err; AudioDeviceID device; UI

我希望将NSSlider合并到控制Mac主卷的Cocoa应用程序中。我不想通过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]);

}
-(浮点)getVolume
{
浮动b_vol;
骨性关节炎;
音频设备ID设备;
UInt32尺寸;
UInt32通道[2];
浮动量[2];
//获取设备
尺寸=设备的尺寸;
err=AudioObjectGetPropertyData(kAudioHardwarePropertyDefaultOutputDevice,&device,&size,);
如果(错误!=noErr)
{
NSLog(@“音频音量错误获取设备”);
返回0.0;
}
//尝试设置主卷(通道0)
尺寸=体积的尺寸;
err=AudioDeviceGetProperty(设备,0,0,kAudioDevicePropertyVolumeScalar,&size,&b_vol);//KaudioDevicePropertyVolumeScalartobels
如果(noErr==err)返回b_vol;
//否则,请尝试分离频道
//获取频道号
尺寸=sizeof(通道);
err=AudioDeviceGetProperty(设备、0、0、KaudioDevicePropertyReferredChannelsForTereo、大小和通道);
if(err!=noErr)NSLog(@“获取通道号时出错”);
尺寸=sizeof(浮动);
err=AudioDeviceGetProperty(设备、频道[0]、0、kAudioDevicePropertyVolumeScalar、大小和音量[0]);
如果(noErr!=err)NSLog(@“获取通道%d的卷时出错”,通道[0]);
err=AudioDeviceGetProperty(设备、频道[1]、0、kAudioDevicePropertyVolumeScalar、大小和音量[1]);
如果(noErr!=err)NSLog(@“获取通道%d的卷时出错”,通道[1]);
b_vol=(卷[0]+卷[1])/2.00;
返回b_vol;
}
-(无效)设置卷:(浮动)发票{
骨性关节炎;
音频设备ID设备;
UInt32尺寸;
布尔canset=false;
UInt32通道[2];
//浮动量[2];
//获取默认设备
尺寸=设备的尺寸;
printf(“setVolume::卷集的值=%lf”,involume);
err=音频硬件设备属性(KaudioHardwareProperty默认输出设备、大小和设备);
如果(错误!=noErr){
NSLog(@“音频音量错误获取设备”);
返回;
}
//尝试设置主通道(0)卷
大小=canset的大小;
err=AudioDeviceGetPropertyInfo(设备、0、false、kAudioDevicePropertyVolumeScalar、大小和canset);
if(err==noErr&&canset==true){
大小=发票的大小;
err=AudioDeviceSetProperty(设备、NULL、0、false、kAudioDevicePropertyVolumeScalar、大小和发票);
返回;
}
//否则,请尝试使用单独的通道
//获取频道
尺寸=sizeof(通道);
err=AudioDeviceGetProperty(设备、0、false、KaudioDevicePropertyReferredChannelsForTereo、大小和通道);
如果(错误!=noErr){
NSLog(@“获取通道号时出错”);
返回;
}
//定容
尺寸=sizeof(浮动);
err=AudioDeviceSetProperty(设备、0、通道[0]、false、kAudioDevicePropertyVolumeScalar、大小和发票);
如果(noErr!=err)NSLog(@“设置通道%d的卷时出错”,通道[0]);
err=AudioDeviceSetProperty(设备、0、通道[1]、false、kAudioDevicePropertyVolumeScalar、大小和发票);
如果(noErr!=err)NSLog(@“设置通道%d的卷时出错”,通道[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;
}

这样就可以了-我只是从我的一个项目中复制并粘贴了它,因此有一些无关的变量和函数,但您应该能够了解它的要点:

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

这是破坏StackOverflow的答案类型。您应该提供示例代码和指针,而不是新手直接复制的复制粘贴-(我从三年级就开始编程了(我今年41岁),老实说,我从StackOverflow那里得到了很多帮助,因为我已经将我的技能翻译成了iOS和Cocoa,如果其他人复制我的代码来完成他们的工作,我不会有任何问题。编程需要真正的工作,至少从我的角度来看,我们都可以利用我们所能得到的所有帮助。我不认为没有学习到苹果为cha设计的复杂的碳计划破坏音频设备属性将阻止“noob”的发展。让我们试着善待彼此吧,嗯?这是破坏StackOverflow的答案类型。你的意思是给示例代码和指针,而不是让新手直接复制的复制粘贴。:-(我从三年级就开始编程了(我41岁),老实说,我从StackOverflow那里得到了很多帮助,因为我已经将我的技能翻译成了iOS和Cocoa,如果其他人复制我的代码来完成他们的工作,我不会有任何问题。编程需要真正的工作,至少从我的角度来看,我们都可以利用我们所能得到的所有帮助。我不认为没有学习到苹果为cha设计的复杂的碳计划破坏音频设备属性将阻止“noob”的发展。让我们试着善待彼此吧,嗯?