212 lines
5.6 KiB
Objective-C
Executable File
212 lines
5.6 KiB
Objective-C
Executable File
//
|
|
// AppDelegate.m
|
|
// iTunes Volume Control
|
|
//
|
|
// Created by Andrea Alberti on 25.12.12.
|
|
// Copyright (c) 2012 Andrea Alberti. All rights reserved.
|
|
//
|
|
|
|
#import <Carbon/Carbon.h>
|
|
#import "AppDelegate.h"
|
|
|
|
#import "SystemVolume.h"
|
|
|
|
@implementation SystemApplication
|
|
|
|
@synthesize currentVolume = _currentVolume;
|
|
@synthesize icon = _icon;
|
|
|
|
-(AudioDeviceID) getDefaultOutputDevice
|
|
{
|
|
AudioObjectPropertyAddress getDefaultOutputDevicePropertyAddress = {
|
|
kAudioHardwarePropertyDefaultOutputDevice,
|
|
kAudioObjectPropertyScopeGlobal,
|
|
kAudioObjectPropertyElementMain
|
|
};
|
|
|
|
AudioDeviceID defaultOutputDeviceID;
|
|
UInt32 volumedataSize = sizeof(defaultOutputDeviceID);
|
|
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
|
&getDefaultOutputDevicePropertyAddress,
|
|
0, NULL,
|
|
&volumedataSize, &defaultOutputDeviceID);
|
|
|
|
if(kAudioHardwareNoError != result)
|
|
{
|
|
NSLog(@"Cannot find default output device!");
|
|
}
|
|
|
|
return defaultOutputDeviceID;
|
|
}
|
|
|
|
- (void)setCurrentVolume:(double)currentVolume
|
|
{
|
|
AudioDeviceID defaultOutputDeviceID = [self getDefaultOutputDevice];
|
|
|
|
AudioObjectPropertyAddress volumePropertyAddress = {
|
|
kAudioHardwareServiceDeviceProperty_VirtualMainVolume,
|
|
kAudioDevicePropertyScopeOutput,
|
|
kAudioObjectPropertyElementMain
|
|
};
|
|
|
|
AudioObjectPropertyAddress mutePropertyAddress = {
|
|
kAudioDevicePropertyMute,
|
|
kAudioDevicePropertyScopeOutput,
|
|
kAudioObjectPropertyElementMain
|
|
};
|
|
|
|
Float32 volume = (Float32)(currentVolume / 100.);
|
|
UInt32 dataSize;
|
|
|
|
if (volume == 0) {
|
|
// Mute the device
|
|
UInt32 mute = 1;
|
|
dataSize = sizeof(mute);
|
|
OSStatus result = AudioObjectSetPropertyData(defaultOutputDeviceID,
|
|
&mutePropertyAddress,
|
|
0, NULL,
|
|
dataSize, &mute);
|
|
if (result != noErr) {
|
|
NSLog(@"Failed to mute device 0x%0x", defaultOutputDeviceID);
|
|
}
|
|
} else {
|
|
// Set the volume to currentVolume (unmute the device if needed)
|
|
UInt32 mute = 0;
|
|
dataSize = sizeof(mute);
|
|
AudioObjectSetPropertyData(defaultOutputDeviceID,
|
|
&mutePropertyAddress,
|
|
0, NULL,
|
|
dataSize, &mute);
|
|
|
|
// Set the volume
|
|
dataSize = sizeof(volume);
|
|
OSStatus result = AudioObjectSetPropertyData(defaultOutputDeviceID,
|
|
&volumePropertyAddress,
|
|
0, NULL,
|
|
dataSize, &volume);
|
|
if (result != noErr) {
|
|
NSLog(@"Failed to set volume for device 0x%0x", defaultOutputDeviceID);
|
|
}
|
|
}
|
|
}
|
|
|
|
- (bool) isMuted
|
|
{
|
|
AudioDeviceID defaultOutputDeviceID = [self getDefaultOutputDevice];
|
|
|
|
AudioObjectPropertyAddress volumePropertyAddress = {
|
|
kAudioDevicePropertyMute,
|
|
kAudioDevicePropertyScopeOutput,
|
|
kAudioObjectPropertyElementMain
|
|
};
|
|
|
|
UInt32 muteVal;
|
|
UInt32 muteValSize = sizeof(muteVal);
|
|
OSStatus result = AudioObjectGetPropertyData(defaultOutputDeviceID,
|
|
&volumePropertyAddress,
|
|
0, NULL,
|
|
&muteValSize, &muteVal);
|
|
|
|
if (result != kAudioHardwareNoError) {
|
|
NSLog(@"No volume reported for device 0x%0x", defaultOutputDeviceID);
|
|
}
|
|
|
|
return muteVal;
|
|
}
|
|
|
|
- (double) currentVolume
|
|
{
|
|
AudioDeviceID defaultOutputDeviceID = [self getDefaultOutputDevice];
|
|
|
|
// First, check mute state
|
|
AudioObjectPropertyAddress mutePropertyAddress = {
|
|
kAudioDevicePropertyMute,
|
|
kAudioDevicePropertyScopeOutput,
|
|
kAudioObjectPropertyElementMain
|
|
};
|
|
|
|
UInt32 muteVal = 0;
|
|
UInt32 muteValSize = sizeof(muteVal);
|
|
OSStatus muteResult = AudioObjectGetPropertyData(defaultOutputDeviceID,
|
|
&mutePropertyAddress,
|
|
0, NULL,
|
|
&muteValSize, &muteVal);
|
|
|
|
if (muteResult == kAudioHardwareNoError && muteVal == 1) {
|
|
return 0.0; // Treat mute as 0%
|
|
}
|
|
|
|
// Otherwise, get the real volume
|
|
AudioObjectPropertyAddress volumePropertyAddress = {
|
|
kAudioHardwareServiceDeviceProperty_VirtualMainVolume,
|
|
kAudioDevicePropertyScopeOutput,
|
|
kAudioObjectPropertyElementMain
|
|
};
|
|
|
|
Float32 volume = 0;
|
|
UInt32 volumedataSize = sizeof(volume);
|
|
OSStatus result = AudioObjectGetPropertyData(defaultOutputDeviceID,
|
|
&volumePropertyAddress,
|
|
0, NULL,
|
|
&volumedataSize, &volume);
|
|
|
|
if (result != kAudioHardwareNoError) {
|
|
NSLog(@"No volume reported for device 0x%0x", defaultOutputDeviceID);
|
|
}
|
|
|
|
return ((double)volume) * 100.0;
|
|
}
|
|
|
|
- (NSString *)getDefaultOutputDeviceName
|
|
{
|
|
AudioDeviceID defaultOutputDeviceID = [self getDefaultOutputDevice];
|
|
|
|
if (defaultOutputDeviceID == kAudioObjectUnknown) {
|
|
return @"Unknown Device";
|
|
}
|
|
|
|
CFStringRef deviceName = NULL;
|
|
UInt32 dataSize = sizeof(deviceName);
|
|
|
|
AudioObjectPropertyAddress propertyAddress = {
|
|
kAudioObjectPropertyName,
|
|
kAudioObjectPropertyScopeGlobal,
|
|
kAudioObjectPropertyElementMain
|
|
};
|
|
|
|
OSStatus result = AudioObjectGetPropertyData(defaultOutputDeviceID,
|
|
&propertyAddress,
|
|
0,
|
|
NULL,
|
|
&dataSize,
|
|
&deviceName);
|
|
|
|
if (result != kAudioHardwareNoError || deviceName == NULL) {
|
|
NSLog(@"Could not get device name for device 0x%0x", defaultOutputDeviceID);
|
|
return @"Unknown Device";
|
|
}
|
|
|
|
NSString *name = [NSString stringWithString:(__bridge NSString *)deviceName];
|
|
CFRelease(deviceName);
|
|
return name;
|
|
}
|
|
|
|
|
|
-(void)dealloc
|
|
{
|
|
}
|
|
|
|
-(id)init{
|
|
if (self = [super init]) {
|
|
[self setOldVolume:[self currentVolume]];
|
|
if (@available(macOS 16.0, *)) {
|
|
[self setIcon:[NSImage imageNamed:@"FinderTahoe"]];
|
|
} else {
|
|
[self setIcon:[NSImage imageNamed:@"FinderSequoia"]];
|
|
}
|
|
}
|
|
return self;
|
|
}
|
|
|
|
@end
|