2012-01-21 5 views
5

Как получить доступ к текущему уровню громкости Mac из API Cocoa?Как получить текущий уровень громкости компьютера?

Например: когда я использую Spotify.app в OS X 10.7, и появляется звуковая реклама, и я отказываюсь от тома Mac, приложение приостанавливает показ объявления до тех пор, пока я не верну его на средний уровень , Я нахожу это невероятно неприятным и нарушает конфиденциальность пользователей, но почему-то Spotify нашел способ сделать это.

Есть ли способ сделать это с помощью какао? Я создаю приложение, где может оказаться полезным предупредить пользователя, если уровень громкости низкий.

+1

Существует не один «текущий уровень громкости». На устройстве есть одно устройство, часто одно * на канал *, и есть два мета-устройства (по крайней мере для вывода): «устройство вывода по умолчанию» (для большинства звуковых выходов) и «устройство вывода предупреждений», (для предупреждающих звуков, звуков интерфейса и т. д.). –

ответ

8

Есть две опции. Первый шаг - определить, какое устройство вам нужно, и получить его идентификатор. Предполагая, что устройство вывода по умолчанию, код будет выглядеть примерно так:

AudioObjectPropertyAddress propertyAddress = { 
    kAudioHardwarePropertyDefaultOutputDevice, 
    kAudioObjectPropertyScopeGlobal, 
    kAudioObjectPropertyElementMaster 
}; 

AudioDeviceID deviceID; 
UInt32 dataSize = sizeof(deviceID); 
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize, &deviceID); 

if(kAudioHardwareNoError != result) 
    // Handle the error 

Далее вы можете использовать kAudioHardwareServiceDeviceProperty_VirtualMasterVolume свойство для получения виртуального тома главного устройства:

AudioObjectPropertyAddress propertyAddress = { 
    kAudioHardwareServiceDeviceProperty_VirtualMasterVolume, 
    kAudioDevicePropertyScopeOutput, 
    kAudioObjectPropertyElementMaster 
}; 

if(!AudioHardwareServiceHasProperty(deviceID, &propertyAddress)) 
    // An error occurred 

Float32 volume; 
UInt32 dataSize = sizeof(volume); 
OSStatus result = AudioHardwareServiceGetPropertyData(deviceID, &propertyAddress, 0, NULL, &dataSize, &volume); 

if(kAudioHardwareNoError != result) 
    // An error occurred 

В качестве альтернативы, вы можете использовать kAudioDevicePropertyVolumeScalar для получить объем для конкретного канала:

UInt32 channel = 1; // Channel 0 is master, if available 
AudioObjectPropertyAddress propertyAddress = { 
    kAudioDevicePropertyVolumeScalar, 
    kAudioDevicePropertyScopeOutput, 
    channel 
}; 

if(!AudioObjectHasProperty(deviceID, &propertyAddress)) 
    // An error occurred 

Float32 volume; 
UInt32 dataSize = sizeof(volume); 
OSStatus result = AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, NULL, &dataSize, &volume); 

if(kAudioHardwareNoError != result) 
    // An error occurred 

разница между ними объясняется в документации компании Apple:

kAudioHardwareServiceDeviceProperty_VirtualMasterVolume

Значение float32, представляющее значение регулировки громкости. Диапазон для этого свойства равен 0,0 (тишина) до 1,0 (полный уровень ). Эффект этого свойства зависит от аппаратного устройства , связанного с аудио-объектом HAL. Если у устройства есть регулятор громкости , это свойство управляет им. Если устройство имеет регуляторы громкости отдельных каналов, это свойство применяется к тем , идентифицированным предпочтительным многоканальным расположением устройства, или предпочтительной стереопарой , если устройство является стереофоническим. Этот элемент управления поддерживает относительный баланс между каналами, на которые он влияет.

Таким образом, может быть сложно определить, что такое громкость устройства, особенно для многоканальных устройств с нестандартными канальными картами.

+0

Где находится 'kAudioHardwareServiceDeviceProperty_VirtualMasterVolume', входящий в этот код? –

+0

Я не отправлял код для этого изначально, потому что Исаак, казалось, покрыл это в своем ответе.Однако я добавлю его в свой ответ, чтобы сделать его более полным. – sbooth

+0

Я получаю kAudioHardwareUnknownPropertyError для AudioObjectGetPropertyData, используя как kAudioHardwareServiceDeviceProperty_VirtualMasterVolume, так и kAudioDevicePropertyVolumeScalar. Xcode 7.3.1 OS X 10.10 – rocky

2

С CocoaDev эти методы класса выглядят, как они должны работать, хотя это не особенно какао, как:

#import <AudioToolbox/AudioServices.h> 

+(AudioDeviceID)defaultOutputDeviceID 
{ 
    AudioDeviceID outputDeviceID = kAudioObjectUnknown; 

    // get output device device 
    UInt32 propertySize = 0; 
    OSStatus status = noErr; 
    AudioObjectPropertyAddress propertyAOPA; 
    propertyAOPA.mScope = kAudioObjectPropertyScopeGlobal; 
    propertyAOPA.mElement = kAudioObjectPropertyElementMaster; 
    propertyAOPA.mSelector = kAudioHardwarePropertyDefaultOutputDevice; 

    if (!AudioHardwareServiceHasProperty(kAudioObjectSystemObject, &propertyAOPA)) 
    { 
     NSLog(@"Cannot find default output device!"); 
     return outputDeviceID; 
    } 

    propertySize = sizeof(AudioDeviceID); 

    status = AudioHardwareServiceGetPropertyData(kAudioObjectSystemObject, &propertyAOPA, 0, NULL, &propertySize, &outputDeviceID); 

    if(status) 
    { 
     NSLog(@"Cannot find default output device!"); 
    } 
    return outputDeviceID; 
} 

// getting system volume 

+(float)volume 
{ 
    Float32   outputVolume; 

    UInt32 propertySize = 0; 
    OSStatus status = noErr; 
    AudioObjectPropertyAddress propertyAOPA; 
    propertyAOPA.mElement = kAudioObjectPropertyElementMaster; 
    propertyAOPA.mSelector = kAudioHardwareServiceDeviceProperty_VirtualMasterVolume; 
    propertyAOPA.mScope = kAudioDevicePropertyScopeOutput; 

    AudioDeviceID outputDeviceID = [[self class] defaultOutputDeviceID]; 

    if (outputDeviceID == kAudioObjectUnknown) 
    { 
     NSLog(@"Unknown device"); 
     return 0.0; 
    } 

    if (!AudioHardwareServiceHasProperty(outputDeviceID, &propertyAOPA)) 
    { 
     NSLog(@"No volume returned for device 0x%0x", outputDeviceID); 
     return 0.0; 
    } 

    propertySize = sizeof(Float32); 

    status = AudioHardwareServiceGetPropertyData(outputDeviceID, &propertyAOPA, 0, NULL, &propertySize, &outputVolume); 

    if (status) 
    { 
     NSLog(@"No volume returned for device 0x%0x", outputDeviceID); 
     return 0.0; 
    } 

    if (outputVolume < 0.0 || outputVolume > 1.0) return 0.0; 

    return outputVolume; 
} 
+0

Что такое 'KNVolumeControl'? – sbooth

+0

@sbooth: копирование/вставка с моей стороны. Должно быть исправлено сейчас. (И +1 на ваш ответ, который, кажется, по тем же направлениям, но на самом деле объясняет это.) – Isaac

+0

Ссылка на CocoaDev мертва. Для этого требуется '-framework Cocoa -framework AudioToolbox' –

Смежные вопросы