diff --git a/Mute Me Now/AppDelegate.m b/Mute Me Now/AppDelegate.m index e6bfa53..29032c4 100644 --- a/Mute Me Now/AppDelegate.m +++ b/Mute Me Now/AppDelegate.m @@ -8,6 +8,7 @@ #import #import #import "ViewController.h" +#import "Mute_Me-Swift.h" static const NSTouchBarItemIdentifier muteIdentifier = @"pp.mute"; static NSString *const MASCustomShortcutKey = @"customShortcut"; @@ -29,9 +30,7 @@ @implementation AppDelegate NSString *STATUS_ICON_OFF = @"micOff"; NSString *STATUS_ICON_ON = @"micOn"; -AudioDeviceID currentAudioDeviceID = kAudioObjectUnknown; -AudioObjectPropertyListenerBlock onDefaultInputDeviceChange = NULL; -AudioObjectPropertyListenerBlock onAudioDeviceMuteChange = NULL; +MuteState lastMuteState; - (void) awakeFromNib { BOOL hideStatusBar = NO; @@ -133,123 +132,40 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { NSCustomTouchBarItem *mute = [[NSCustomTouchBarItem alloc] initWithIdentifier:muteIdentifier]; NSImage *muteImage = [NSImage imageNamed:NSImageNameTouchBarAudioInputMuteTemplate]; - TouchButton *button = [TouchButton buttonWithImage: muteImage target:nil action:nil]; - [button setDelegate: self]; - mute.view = button; - - touchBarButton = button; - + touchBarButton = [TouchButton buttonWithImage: muteImage target:self action:@selector(onPressed:)]; + mute.view = touchBarButton; [NSTouchBarItem addSystemTrayItem:mute]; DFRElementSetControlStripPresenceForIdentifier(muteIdentifier, YES); - onDefaultInputDeviceChange = ^(UInt32 inNumberAddresses, const AudioObjectPropertyAddress * _Nonnull inAddresses) { - BOOL muted = false; - BOOL setMuted = false; - - if (currentAudioDeviceID != kAudioObjectUnknown) { - setMuted = true; - muted = [self getInputDeviceMute:currentAudioDeviceID]; - - [self unlistenInputDevice:currentAudioDeviceID]; - } - - [self setDefaultInputDeviceAsCurrentAndListen]; - - if (setMuted) { - [self setInputDevice:currentAudioDeviceID mute:muted]; - } - }; - - onAudioDeviceMuteChange = ^(UInt32 inNumberAddresses, const AudioObjectPropertyAddress * _Nonnull inAddresses) { + [Mute preformInitializationWithChangeCallback:^(enum MuteState state) { dispatch_async(dispatch_get_main_queue(), ^{ - [self updatePresentation]; + lastMuteState = state; + [self updatePresentationWithLastState]; }); - }; + }]; [self enableLoginAutostart]; - [self listenInputDevices]; // fires if we enter / exit dark mode [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(darkModeChanged:) name:@"AppleInterfaceThemeChangedNotification" object:nil]; } -- (void) unlistenCurrentDevice { - if (currentAudioDeviceID != kAudioObjectUnknown) { - [self unlistenInputDevice:currentAudioDeviceID]; - } -} - -- (void) setDefaultInputDeviceAsCurrentAndListen { - currentAudioDeviceID = [self getDefaultInputDevice]; - - if (currentAudioDeviceID != kAudioObjectUnknown) { - OSStatus error = [self listenInputDevice:currentAudioDeviceID]; - if (error != noErr) { - currentAudioDeviceID = kAudioObjectUnknown; - } else { - NSLog(@"Listen device: 0x%0x", currentAudioDeviceID); - } - } -} - -- (void) listenInputDevices { - AudioObjectPropertyAddress propertyAddress = [self defaultInputDevicePropertyAddress]; - - OSStatus error = AudioObjectAddPropertyListenerBlock(kAudioObjectSystemObject, &propertyAddress, NULL, onDefaultInputDeviceChange); - if (error != noErr) { - NSLog(@"Can't listen change of default device. Error: %d", error); - } - - [self setDefaultInputDeviceAsCurrentAndListen]; -} - -- (OSStatus) listenInputDevice:(AudioDeviceID)deviceID { - AudioObjectPropertyAddress muteAddress = [self mutePropertyAddress]; - - OSStatus error = AudioObjectAddPropertyListenerBlock(deviceID, &muteAddress, NULL, onAudioDeviceMuteChange); - if (error != noErr) { - NSLog(@"Can't listen mute change of device: 0x%0x. Error: %d", deviceID, error); - } - - dispatch_async(dispatch_get_main_queue(), ^{ - [self updatePresentation]; - }); - - return error; -} - -- (void) unlistenInputDevice:(AudioDeviceID)deviceID { - AudioObjectPropertyAddress muteAddress = [self mutePropertyAddress]; - - OSStatus error = AudioObjectRemovePropertyListenerBlock(deviceID, &muteAddress, NULL, onAudioDeviceMuteChange); - if (error != noErr) { - NSLog(@"Can't unlisten mute change of device: 0x%0x. Error: %d", deviceID, error); - } - - [self setInputDevice:deviceID mute:false]; -} - -- (void) updatePresentation { - if (currentAudioDeviceID == kAudioObjectUnknown) { - return; - } - - BOOL muted = [self getInputDeviceMute:currentAudioDeviceID]; - [self updateTouchBarButtonWithMuted:muted]; - [self updateStatusBarIconWithMuted:muted]; +- (void) updatePresentationWithLastState { + [self updateTouchBarButtonWithMuteState:lastMuteState]; + [self updateStatusBarIconWithMuteState:lastMuteState]; } -- (void) updateTouchBarButtonWithMuted:(BOOL)muted { - [touchBarButton setBezelColor: [self colorForMuted: muted]]; +- (void) updateTouchBarButtonWithMuteState:(MuteState) state { + [touchBarButton setBezelColor: [self colorForMuteState: state]]; [touchBarButton layout]; } -- (void) updateStatusBarIconWithMuted:(BOOL)muted { - [self setStatusBarImgRed: muted]; +- (void) updateStatusBarIconWithMuteState:(MuteState) state { + [self setStatusBarImgRed: state == MuteStateAll]; } -(void)darkModeChanged:(NSNotification *)notif { - [self updatePresentation]; + [self updatePresentationWithLastState]; } @@ -309,93 +225,6 @@ - (void) setStatusBarImgRed:(BOOL) shouldBeRed { } -- (BOOL) setAudioObject:(AudioObjectID)audioObjectID - property:(AudioObjectPropertyAddress)propertyAddress - dataSize:(UInt32)dataSize - data:(const void *)data -{ - if (!AudioObjectHasProperty(audioObjectID, &propertyAddress) ) { - NSLog(@"No property for audioObject 0x%0x", audioObjectID); - return false; - } - - Boolean settable; - OSStatus theError = AudioObjectIsPropertySettable(audioObjectID, &propertyAddress, &settable); - if (theError != noErr || !settable) { - NSLog(@"The property of audioObject 0x%0x cannot be set", audioObjectID); - return false; - } - - //now read the property and correct it, if outside [0...1] - theError = AudioObjectSetPropertyData(audioObjectID, &propertyAddress, 0, NULL, dataSize, data); - if (theError != noErr) { - NSLog(@"Unable to set property for audioObject 0x%0x", audioObjectID); - return false; - } - - return true; -} - -- (BOOL) getAudioObject:(AudioObjectID)audioObjectID - property:(AudioObjectPropertyAddress)propertyAddress - dataSize:(UInt32)dataSize - data:(void *)data -{ - if (!AudioObjectHasProperty(audioObjectID, &propertyAddress) ) { - NSLog(@"No property for audioObject 0x%0x", audioObjectID); - return false; - } - - OSStatus theError = AudioObjectGetPropertyData(audioObjectID, &propertyAddress, 0, NULL, &dataSize, data); - if (theError != noErr) { - NSLog(@"Unable to read property for audioObject 0x%0x", audioObjectID); - return false; - } - - return true; -} - -- (AudioObjectPropertyAddress) mutePropertyAddress { - AudioObjectPropertyAddress propertyAddress = { - kAudioDevicePropertyMute, - kAudioDevicePropertyScopeInput, - kAudioObjectPropertyElementMaster - }; - - return propertyAddress; -} - -- (AudioObjectPropertyAddress) defaultInputDevicePropertyAddress { - AudioObjectPropertyAddress propertyAddress = { - kAudioHardwarePropertyDefaultInputDevice, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; - - return propertyAddress; -} - -- (BOOL) getInputDeviceMute:(AudioDeviceID)deviceID { - AudioObjectPropertyAddress propertyAddress = [self mutePropertyAddress]; - UInt32 data; - - BOOL success = [self getAudioObject:deviceID property:propertyAddress dataSize:sizeof(data) data:&data]; - return success ? data == 1 : false; -} - -- (void) setInputDevice:(AudioDeviceID)deviceID mute:(BOOL)mute { - UInt32 value = mute ? 1 : 0; - AudioObjectPropertyAddress propertyAddress = [self mutePropertyAddress]; - - BOOL s = [self setAudioObject:deviceID property:propertyAddress dataSize:sizeof(value) data:&value]; - - if (s) { - printf("123"); - AudioObjectShow(deviceID); - NSLog(@"Set property for audioObject 0x%0x to %d", deviceID, value); - } -} - -(void) enableLoginAutostart { // on the first run this should be nil. So don't setup auto run @@ -410,24 +239,13 @@ -(void) enableLoginAutostart { } - (void)applicationWillTerminate:(NSNotification *)aNotification { - [self unlistenCurrentDevice]; + [Mute deinitialize]; } -- (AudioDeviceID) getDefaultInputDevice { - AudioDeviceID defaultDevice = kAudioObjectUnknown; - AudioObjectPropertyAddress address = [self defaultInputDevicePropertyAddress]; - - [self getAudioObject:kAudioObjectSystemObject property:address dataSize:sizeof(AudioDeviceID) data:&defaultDevice]; - - return defaultDevice; -} - --(NSColor *)colorForMuted:(BOOL)muted { - if(muted) { - return NSColor.redColor; - } else { - return NSColor.clearColor; - } +-(NSColor *)colorForMuteState:(MuteState)state { + if(state == MuteStateAll) return NSColor.redColor; + if(state == MuteStatePartially) return NSColor.yellowColor; + return NSColor.clearColor; } - (void)onPressed:(TouchButton*)sender { @@ -435,13 +253,7 @@ - (void)onPressed:(TouchButton*)sender { } - (void) toggleMute { - if (currentAudioDeviceID == kAudioObjectUnknown) { - NSLog(@"Can't toggle mute. No audio device."); - return; - } - - BOOL isMuted = [self getInputDeviceMute:currentAudioDeviceID]; - [self setInputDevice:currentAudioDeviceID mute:!isMuted]; + [Mute toggleMuteOfAllInputDevices]; } - (void) openPrefsWindow { diff --git a/Mute Me Now/Base.lproj/Main.storyboard b/Mute Me Now/Base.lproj/Main.storyboard index ecc41ca..160ece5 100644 --- a/Mute Me Now/Base.lproj/Main.storyboard +++ b/Mute Me Now/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -715,16 +715,16 @@ - + - + - + @@ -732,8 +732,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - + - - + + - - + @@ -851,36 +815,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -892,7 +971,7 @@ - + diff --git a/Mute Me Now/Info.plist b/Mute Me Now/Info.plist index 041d2e2..af8afe8 100644 --- a/Mute Me Now/Info.plist +++ b/Mute Me Now/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.0.0 + 2.1.0 CFBundleVersion 2 LSApplicationCategoryType diff --git a/Mute Me Now/Mute Me-Bridging-Header.h b/Mute Me Now/Mute Me-Bridging-Header.h new file mode 100644 index 0000000..e11d920 --- /dev/null +++ b/Mute Me Now/Mute Me-Bridging-Header.h @@ -0,0 +1,3 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// diff --git a/Mute Me Now/Mute.swift b/Mute Me Now/Mute.swift new file mode 100644 index 0000000..f4d839d --- /dev/null +++ b/Mute Me Now/Mute.swift @@ -0,0 +1,165 @@ +// +// Mute.swift +// Mute Me +// +// Created by Alexandr Promakh on 24/12/2018. +// Copyright © 2018 Pixel Point. All rights reserved. +// + +import Cocoa +import AMCoreAudio + +@objc public enum MuteState : Int { + case all // All devices muted + case partially // Some devices muted, some not + case none // All devices not muted +} + +class DeviceInfo : NSObject { + @objc public var name: String + @objc public var muted: Bool + + init(name: String, muted: Bool) { + self.name = name; + self.muted = muted; + } +} + +class Mute: NSObject { + static let defaultChannel = kAudioObjectPropertyElementMaster; + static let defaultDirection = Direction.recording; + static let notificationCenter = AMCoreAudio.NotificationCenter.defaultCenter; + static let instance = Mute(); + static var savedVolumeByDeviceId: [AudioDeviceID: Float] = [:]; + + static var lastMuteState: MuteState = MuteState.none; + static var changeCallback: (MuteState) -> Void = { state in }; + static var devicesMuteChangeCallback: ([DeviceInfo]) -> Void = { muted in } + + @objc static public func preformInitialization(changeCallback: @escaping (MuteState) -> Void) { + self.changeCallback = changeCallback; + + lastMuteState = getMuteOfAllInputDevices() + self.changeCallback(lastMuteState); + + notificationCenter.subscribe(instance, eventType: AudioHardwareEvent.self) + notificationCenter.subscribe(instance, eventType: AudioDeviceEvent.self) + } + + @objc static public func deinitialize() { + notificationCenter.unsubscribe(instance, eventType: AudioHardwareEvent.self) + notificationCenter.unsubscribe(instance, eventType: AudioDeviceEvent.self) + } + + @objc static public func subscribeToDevicesMutedChange(callback: @escaping ([DeviceInfo]) -> Void) { + self.devicesMuteChangeCallback = callback; + publishDevicesMuteChange(); + } + + @objc public static func setMuteToAllInputDevices(shouldMute: Bool) { + setMuteToDevices(devices: AudioDevice.allInputDevices(), shouldMute: shouldMute) + } + + private static func setMuteToDevices(devices: [AudioDevice], shouldMute: Bool) { + for device in devices { + setMuteToDevice(device, shouldMute: shouldMute); + } + } + + private static func setMuteToDevice(_ device: AudioDevice, shouldMute: Bool) { + let canMute = device.canMute(channel: defaultChannel, direction: Direction.recording) + let canVolume = device.canSetVolume(channel: defaultChannel, direction: Direction.recording) + let volume = device.volume(channel: defaultChannel, direction: defaultDirection); + + if (canMute) { + device.setMute(shouldMute, channel: defaultChannel, direction: Direction.recording) + } + + if (canVolume ) { + if (shouldMute && volume != 0) { + savedVolumeByDeviceId[device.id] = volume; + device.setVolume(0, channel: defaultChannel, direction: Direction.recording) + } else if (!shouldMute && volume == 0) { + let restoredVolume = savedVolumeByDeviceId[device.id] ?? 1; + device.setVolume(restoredVolume, channel: defaultChannel, direction: Direction.recording) + } + } + } + + @objc public static func getMuteOfAllInputDevices() -> MuteState { + let devices = AudioDevice.allInputDevices(); + let devicesCount = devices.count; + + var mutedDevicesCount = 0; + + for device in devices { + if (getMuteOfDevice(device)) { + mutedDevicesCount += 1; + } + } + + if (mutedDevicesCount == devicesCount) { + return MuteState.all; + } else if (mutedDevicesCount == 0) { + return MuteState.none; + } + return MuteState.partially; + } + + private static func getMuteOfDevice(_ device: AudioDevice) -> Bool { + let isMuted = device.isMuted(channel: defaultChannel, direction: defaultDirection) ?? false; + let volume = device.volume(channel: defaultChannel, direction: defaultDirection); + + return isMuted || volume == 0; + } + + @objc public static func toggleMuteOfAllInputDevices() { + setMuteToAllInputDevices(shouldMute: !shouldAllInputDevicesBeMuted()); + } + + public static func shouldAllInputDevicesBeMuted() -> Bool { + let currentState = getMuteOfAllInputDevices(); + return currentState == MuteState.none ? false : true; + } +} + +extension Mute : EventSubscriber { + func eventReceiver(_ event: Event) { + switch event { + case let event as AudioHardwareEvent: + switch event { + case .deviceListChanged(let addedDevices, _): + Mute.publishDevicesMuteChange() + + if (Mute.shouldAllInputDevicesBeMuted()) { + Mute.setMuteToDevices(devices: addedDevices, shouldMute: true) + } + default: + () + } + case let event as AudioDeviceEvent: + switch event { + case .muteDidChange(_, _, _), + .volumeDidChange(_, _, _): + Mute.publishDevicesMuteChange() + + let muteState = Mute.getMuteOfAllInputDevices(); + if (muteState != Mute.lastMuteState) { + Mute.lastMuteState = muteState; + Mute.changeCallback(muteState); + } + default: + () + } + default: + () + } + } + + private static func publishDevicesMuteChange() { + let devices = AudioDevice.allInputDevices(); + let infos = devices.map { DeviceInfo(name: $0.name, muted: Mute.getMuteOfDevice($0)) } + + self.devicesMuteChangeCallback(infos) + } +} diff --git a/Mute Me Now/TouchBar.h b/Mute Me Now/TouchBar.h index 327e4d0..6f14066 100644 --- a/Mute Me Now/TouchBar.h +++ b/Mute Me Now/TouchBar.h @@ -1,6 +1,6 @@ #import -extern void DFRElementSetControlStripPresenceForIdentifier(NSString *, BOOL); +extern void DFRElementSetControlStripPresenceForIdentifier(NSTouchBarItemIdentifier, BOOL); extern void DFRSystemModalShowsCloseBoxWhenFrontMost(BOOL); @interface NSTouchBarItem () @@ -11,6 +11,6 @@ extern void DFRSystemModalShowsCloseBoxWhenFrontMost(BOOL); @interface NSTouchBar () -+ (void)presentSystemModalFunctionBar:(NSTouchBar *)touchBar systemTrayItemIdentifier:(NSString *)identifier; ++ (void)presentSystemModalTouchBar:(NSTouchBar *)touchBar systemTrayItemIdentifier:(NSTouchBarItemIdentifier)identifier; @end diff --git a/Mute Me Now/ViewController.h b/Mute Me Now/ViewController.h index d5a4bc2..7fcca3a 100644 --- a/Mute Me Now/ViewController.h +++ b/Mute Me Now/ViewController.h @@ -1,7 +1,8 @@ #import #import +#import "Mute_Me-Swift.h" -@interface ViewController : NSViewController +@interface ViewController : NSViewController @property (weak) IBOutlet NSButton *githubButton; @property (weak) IBOutlet NSButton *websiteButton; @@ -10,9 +11,12 @@ @property (weak) IBOutlet NSButton *statusBarButtonToggle; @property (weak) IBOutlet NSButton *useAlternateStatusBarIcons; @property (weak) IBOutlet NSTextFieldCell *versionTextFieldCell; +@property (weak) IBOutlet NSTableView *devicesTable; @property (strong) IBOutlet MASShortcutView *masShortCutView; +@property NSArray *deviceInfos; + - (IBAction)showMenuBarChanged:(id)sender; - (IBAction)statusBarToggleChanged:(id)sender; - (IBAction)useAlternateStatusBarIconsChanged:(id)sender; diff --git a/Mute Me Now/ViewController.m b/Mute Me Now/ViewController.m index 1d4a29c..b5e0828 100644 --- a/Mute Me Now/ViewController.m +++ b/Mute Me Now/ViewController.m @@ -1,5 +1,6 @@ #import "ViewController.h" #import "AppDelegate.h" +#import "Mute_Me-Swift.h" static NSString *githubURL = @"https://github.com/pixel-point/mute-me"; static NSString *projectURL = @"https://muteme.pixelpoint.io/"; @@ -50,6 +51,13 @@ - (void)viewDidLoad { NSString *buildLabel = [buildVersion isEqualToString:@"1"] ? @"" :[NSString stringWithFormat:@"(%@)", buildVersion]; NSString *versionFieldValue = [NSString stringWithFormat:@"Version %@%@", version, buildLabel]; [self.versionTextFieldCell setStringValue:versionFieldValue]; + + [Mute subscribeToDevicesMutedChangeWithCallback:^(NSArray * _Nonnull _deviceInfos) { + dispatch_async(dispatch_get_main_queue(), ^{ + self.deviceInfos = _deviceInfos; + [self.devicesTable reloadData]; + }); + }]; } - (void) observeValueForKeyPath: (NSString*) keyPath ofObject: (id) object change: (NSDictionary*) change context: (void*) context @@ -176,9 +184,28 @@ - (IBAction)useAlternateStatusBarIconsChanged:(id)sender { } - - (IBAction)onMainWebsitePressed:(id)sender { [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:companyURL]]; } +// NSTableViewDataSource + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { + return self.deviceInfos.count; +}; + +- (nullable NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row { + DeviceInfo *info = self.deviceInfos[row]; + NSTableCellView *cell = [tableView makeViewWithIdentifier:@"textCell" owner:nil]; + + if (tableColumn == tableView.tableColumns[0]) { + cell.textField.stringValue = info.name; + } else if (tableColumn == tableView.tableColumns[1]) { + cell.textField.stringValue = info.muted ? @"Muted" : @"Not muted"; + } + + return cell; +} + + @end diff --git a/Mute Me.xcodeproj/project.pbxproj b/Mute Me.xcodeproj/project.pbxproj index 713810b..3cb8aeb 100644 --- a/Mute Me.xcodeproj/project.pbxproj +++ b/Mute Me.xcodeproj/project.pbxproj @@ -22,8 +22,10 @@ 5DA60BDA1EFAB9270045BDCF /* statusBarIcon2.png in Resources */ = {isa = PBXBuildFile; fileRef = 5DA60BD91EFAB9270045BDCF /* statusBarIcon2.png */; }; 5DA60C531EFBC5400045BDCF /* statusBarIcon3.png in Resources */ = {isa = PBXBuildFile; fileRef = 5DA60C521EFBC5400045BDCF /* statusBarIcon3.png */; }; 5DA60C551EFBC5D30045BDCF /* statusBarIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 5DA60C541EFBC5D30045BDCF /* statusBarIcon.png */; }; + C665CBA621D0E33B00CB4EC4 /* Mute.swift in Sources */ = {isa = PBXBuildFile; fileRef = C665CBA521D0E33B00CB4EC4 /* Mute.swift */; }; C6ABF3272163A01B00A62E2F /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6ABF3262163A01B00A62E2F /* CoreAudio.framework */; }; C6B6195A2167483F00F06C6B /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = C6B619592167483F00F06C6B /* .gitignore */; }; + C6E45B8121D2664100AD80F4 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = C6E45B8021D2664100AD80F4 /* README.md */; }; DBCC24CD4DBB4A88C86CD871 /* libPods-Mute Me.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 30004556042F084BBC0CA872 /* libPods-Mute Me.a */; }; /* End PBXBuildFile section */ @@ -84,9 +86,12 @@ 5DA60C521EFBC5400045BDCF /* statusBarIcon3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = statusBarIcon3.png; sourceTree = ""; }; 5DA60C541EFBC5D30045BDCF /* statusBarIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = statusBarIcon.png; sourceTree = ""; }; B222AB6057D3B902CBA70D34 /* Pods-Mute Me.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mute Me.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.debug.xcconfig"; sourceTree = ""; }; + C665CBA521D0E33B00CB4EC4 /* Mute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mute.swift; sourceTree = ""; }; C6ABF32421639AAD00A62E2F /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; C6ABF3262163A01B00A62E2F /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; + C6B46BA421CD142D000D577A /* Mute Me-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Mute Me-Bridging-Header.h"; sourceTree = ""; }; C6B619592167483F00F06C6B /* .gitignore */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; + C6E45B8021D2664100AD80F4 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -107,6 +112,7 @@ 11B86E441EDE9B4C0069D254 = { isa = PBXGroup; children = ( + C6E45B8021D2664100AD80F4 /* README.md */, C6B619592167483F00F06C6B /* .gitignore */, 5D4763251F0562F2005E8DB0 /* Graphics */, 5DA60C541EFBC5D30045BDCF /* statusBarIcon.png */, @@ -144,6 +150,8 @@ 1141FDF01EEFF6DD00CA5B30 /* TouchButton.h */, 1141FDF11EEFF6DD00CA5B30 /* TouchButton.m */, 1141FDF51EEFFA0000CA5B30 /* TouchDelegate.h */, + C6B46BA421CD142D000D577A /* Mute Me-Bridging-Header.h */, + C665CBA521D0E33B00CB4EC4 /* Mute.swift */, ); path = "Mute Me Now"; sourceTree = ""; @@ -207,7 +215,6 @@ 11B86E4A1EDE9B4D0069D254 /* Frameworks */, 11B86E4B1EDE9B4D0069D254 /* Resources */, 11B86E941EDEAD980069D254 /* CopyFiles */, - 40C930C145A2928D7225D5F2 /* [CP] Embed Pods Frameworks */, 0237E5264A87F3A06915D961 /* [CP] Copy Pods Resources */, ); buildRules = ( @@ -231,6 +238,7 @@ TargetAttributes = { 11B86E4C1EDE9B4D0069D254 = { CreatedOnToolsVersion = 8.3.1; + LastSwiftMigration = 1010; ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.Sandbox = { @@ -281,6 +289,7 @@ files = ( 5D4763241F0562E6005E8DB0 /* tray-active@2x.png in Resources */, 11B86E5A1EDE9B4D0069D254 /* Assets.xcassets in Resources */, + C6E45B8121D2664100AD80F4 /* README.md in Resources */, 5D4763231F0562E6005E8DB0 /* tray-unactive-black@2x.png in Resources */, 5D4763221F0562E6005E8DB0 /* tray-unactive-white@2x.png in Resources */, 5DA60BDA1EFAB9270045BDCF /* statusBarIcon2.png in Resources */, @@ -300,43 +309,34 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/MASShortcut/MASShortcut.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MASShortcut.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 40C930C145A2928D7225D5F2 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; E377EBCE94FE28E5EE796CBC /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Mute Me-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -348,6 +348,7 @@ files = ( 1141FDF21EEFF6DD00CA5B30 /* TouchButton.m in Sources */, 11B86E581EDE9B4D0069D254 /* ViewController.m in Sources */, + C665CBA621D0E33B00CB4EC4 /* Mute.swift in Sources */, 11B86E551EDE9B4D0069D254 /* main.m in Sources */, 11B86E521EDE9B4D0069D254 /* AppDelegate.m in Sources */, ); @@ -469,6 +470,7 @@ baseConfigurationReference = B222AB6057D3B902CBA70D34 /* Pods-Mute Me.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = "Mute Me Now/Mute Me Now.entitlements"; CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; @@ -483,6 +485,9 @@ PRODUCT_BUNDLE_IDENTIFIER = "pixel-point.mute-me-now"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Mute Me Now/Mute Me-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; }; name = Debug; }; @@ -491,6 +496,7 @@ baseConfigurationReference = 51C19D181CC260D65112962D /* Pods-Mute Me.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = "Mute Me Now/Mute Me Now.entitlements"; CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; @@ -505,6 +511,8 @@ PRODUCT_BUNDLE_IDENTIFIER = "pixel-point.mute-me-now"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Mute Me Now/Mute Me-Bridging-Header.h"; + SWIFT_VERSION = 4.2; }; name = Release; }; diff --git a/Podfile b/Podfile index c1ded9d..1f0536f 100644 --- a/Podfile +++ b/Podfile @@ -1,4 +1,4 @@ - target 'Mute Me' pod 'MASShortcut' +pod 'AMCoreAudio' diff --git a/Podfile.lock b/Podfile.lock index 4cd9831..759ef28 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,12 +1,20 @@ PODS: + - AMCoreAudio (3.2.1) - MASShortcut (2.3.6) DEPENDENCIES: + - AMCoreAudio - MASShortcut +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - AMCoreAudio + - MASShortcut + SPEC CHECKSUMS: + AMCoreAudio: 7fa6b718dc93acc29f849d60c3ad680ae1bf07b5 MASShortcut: 9c215e8a8a78f3d01ce56da48e2730ab66b538fa -PODFILE CHECKSUM: 4683a7c2272d973f5c2f219be2eb48cc49488353 +PODFILE CHECKSUM: a66a8437d41c8d97188c3af2ea62b72882bd49de -COCOAPODS: 1.2.0 +COCOAPODS: 1.5.3 diff --git a/Podfile~ b/Podfile~ deleted file mode 100644 index 66deab0..0000000 --- a/Podfile~ +++ /dev/null @@ -1,2 +0,0 @@ - -pod 'MASShortcut' diff --git a/Pods/AMCoreAudio/AMCoreAudio/AMCoreAudio.h b/Pods/AMCoreAudio/AMCoreAudio/AMCoreAudio.h new file mode 100644 index 0000000..69092cd --- /dev/null +++ b/Pods/AMCoreAudio/AMCoreAudio/AMCoreAudio.h @@ -0,0 +1,18 @@ +// +// AMCoreAudio.h +// AMCoreAudio +// +// Created by Ruben Nine on 11/11/2016. +// Copyright © 2016 9Labs. All rights reserved. +// + +@import Foundation; +@import CoreAudio.AudioHardware; + +//! Project version number for AMCoreAudio. +FOUNDATION_EXPORT double AMCoreAudioVersionNumber; + +//! Project version string for AMCoreAudio. +FOUNDATION_EXPORT const unsigned char AMCoreAudioVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import diff --git a/Pods/AMCoreAudio/AMCoreAudio/AudioDevice.swift b/Pods/AMCoreAudio/AMCoreAudio/AudioDevice.swift new file mode 100644 index 0000000..64425f3 --- /dev/null +++ b/Pods/AMCoreAudio/AMCoreAudio/AudioDevice.swift @@ -0,0 +1,1837 @@ +// +// AudioDevice.swift +// AMCoreAudio +// +// Created by Ruben on 7/7/15. +// Copyright © 2015 9Labs. All rights reserved. +// + +import Foundation +import AudioToolbox.AudioServices + + +/** + Represents an `AudioDevice` event. + */ +public enum AudioDeviceEvent: Event { + /** + Called whenever the audio device's sample rate changes. + */ + case nominalSampleRateDidChange(audioDevice: AudioDevice) + + /** + Called whenever the audio device's list of nominal sample rates changes. + + - Note: This will typically happen on *Aggregate* and *Multi-Output* devices when adding or removing other audio devices (either physical or virtual.) + */ + case availableNominalSampleRatesDidChange(audioDevice: AudioDevice) + + /** + Called whenever the audio device's clock source changes. + */ + case clockSourceDidChange(audioDevice: AudioDevice) + + /** + Called whenever the audio device's name changes. + */ + case nameDidChange(audioDevice: AudioDevice) + + /** + Called whenever the list of owned audio devices on this audio device changes. + + - Note: This will typically happen on *Aggregate* and *Multi-Output* devices when adding or removing other audio devices (either physical or virtual.) + */ + case listDidChange(audioDevice: AudioDevice) + + /** + Called whenever the audio device's volume for a given channel and direction changes. + */ + case volumeDidChange(audioDevice: AudioDevice, channel: UInt32, direction: Direction) + + /** + Called whenever the audio device's mute state for a given channel and direction changes. + */ + case muteDidChange(audioDevice: AudioDevice, channel:UInt32, direction: Direction) + + /** + Called whenever the audio device's *is alive* property changes. + */ + case isAliveDidChange(audioDevice: AudioDevice) + + /** + Called whenever the audio device's *is running* property changes. + */ + case isRunningDidChange(audioDevice: AudioDevice) + + /** + Called whenever the audio device's *is running somewhere* property changes. + */ + case isRunningSomewhereDidChange(audioDevice: AudioDevice) + + /** + Called whenever the audio device's *is jack connected* property changes. + */ + case isJackConnectedDidChange(audioDevice: AudioDevice) + + /** + Called whenever the audio device's *preferred channels for stereo* property changes. + */ + case preferredChannelsForStereoDidChange(audioDevice: AudioDevice) + + /** + Called whenever the audio device's *hog mode* property changes. + */ + case hogModeDidChange(audioDevice: AudioDevice) +} + + +/** + This class represents an audio device in the system and allows subscribing to audio device notifications. + + Devices may be physical or virtual. For a comprehensive list of supported types, please refer to `TransportType`. + */ +final public class AudioDevice: AudioObject { + + /** + The cached device name. This may be useful in some situations where the class instance + is pointing to a device that is no longer available, so we can still access its name. + + - Returns: The cached device name. + */ + private(set) var cachedDeviceName: String! + + private var isRegisteredForNotifications = false + + private lazy var notificationsQueue: DispatchQueue = { + + return DispatchQueue(label: "io.9labs.AMCoreAudio.notifications", attributes: .concurrent) + + }() + + private lazy var propertyListenerBlock: AudioObjectPropertyListenerBlock = { [weak self] (inNumberAddresses, inAddresses) -> Void in + + let address = inAddresses.pointee + let notificationCenter = NotificationCenter.defaultCenter + + switch address.mSelector { + case kAudioDevicePropertyNominalSampleRate: + + if let strongSelf = self { + notificationCenter.publish(AudioDeviceEvent.nominalSampleRateDidChange(audioDevice: strongSelf)) + } + + case kAudioDevicePropertyAvailableNominalSampleRates: + + if let strongSelf = self { + notificationCenter.publish(AudioDeviceEvent.availableNominalSampleRatesDidChange(audioDevice: strongSelf)) + } + + case kAudioDevicePropertyClockSource: + + if let strongSelf = self { + notificationCenter.publish(AudioDeviceEvent.clockSourceDidChange( + audioDevice: strongSelf + )) + } + + case kAudioObjectPropertyName: + + if let strongSelf = self { + notificationCenter.publish(AudioDeviceEvent.nameDidChange(audioDevice: strongSelf)) + } + + case kAudioObjectPropertyOwnedObjects: + + if let strongSelf = self { + notificationCenter.publish(AudioDeviceEvent.listDidChange(audioDevice: strongSelf)) + } + + case kAudioDevicePropertyVolumeScalar: + + if let strongSelf = self, let direction = direction(to: address.mScope) { + notificationCenter.publish(AudioDeviceEvent.volumeDidChange( + audioDevice: strongSelf, + channel: address.mElement, + direction: direction + )) + } + + case kAudioDevicePropertyMute: + + if let strongSelf = self, let direction = direction(to: address.mScope) { + notificationCenter.publish(AudioDeviceEvent.muteDidChange( + audioDevice: strongSelf, + channel: address.mElement, + direction: direction + )) + } + + case kAudioDevicePropertyDeviceIsAlive: + + if let strongSelf = self { + notificationCenter.publish(AudioDeviceEvent.isAliveDidChange(audioDevice: strongSelf)) + } + + case kAudioDevicePropertyDeviceIsRunning: + + if let strongSelf = self { + notificationCenter.publish(AudioDeviceEvent.isRunningDidChange(audioDevice: strongSelf)) + } + + case kAudioDevicePropertyDeviceIsRunningSomewhere: + + if let strongSelf = self { + notificationCenter.publish(AudioDeviceEvent.isRunningSomewhereDidChange(audioDevice: strongSelf)) + } + + case kAudioDevicePropertyJackIsConnected: + + if let strongSelf = self { + notificationCenter.publish(AudioDeviceEvent.isJackConnectedDidChange(audioDevice: strongSelf)) + } + + case kAudioDevicePropertyPreferredChannelsForStereo: + + if let strongSelf = self { + notificationCenter.publish(AudioDeviceEvent.preferredChannelsForStereoDidChange(audioDevice: strongSelf)) + } + + case kAudioDevicePropertyHogMode: + + if let strongSelf = self { + notificationCenter.publish(AudioDeviceEvent.hogModeDidChange(audioDevice: strongSelf)) + } + + // Unhandled cases beyond this point + case kAudioDevicePropertyBufferFrameSize: + + fallthrough + + case kAudioDevicePropertyPlayThru: + + fallthrough + + case kAudioDevicePropertyDataSource: + + fallthrough + + default: + + break + + } + } + + + // MARK: - Lifecycle Functions + + /** + Initializes an `AudioDevice` by providing a valid audio device identifier that is present in the system. + + - Parameter id: An audio device identifier. + */ + private init?(id: AudioObjectID) { + + super.init(objectID: id) + + guard owningObject != nil else { return nil } + + cachedDeviceName = getDeviceName() + registerForNotifications() + AudioObjectPool.instancePool.setObject(self, forKey: NSNumber(value: UInt(objectID))) + } + + deinit { + + unregisterForNotifications() + AudioObjectPool.instancePool.removeObject(forKey: NSNumber(value: UInt(objectID))) + } + + + // MARK: - Class Functions + + /** + Returns an `AudioDevice` by providing a valid audio device identifier. + + - Parameter id: An audio device identifier. + + - Note: If identifier is not valid, `nil` will be returned. + */ + public static func lookup(by id: AudioObjectID) -> AudioDevice? { + + var instance = AudioObjectPool.instancePool.object(forKey: NSNumber(value: UInt(id))) as? AudioDevice + + if instance == nil { + instance = AudioDevice(id: id) + } + + return instance + } + + /** + Returns an `AudioDevice` by providing a valid audio device unique identifier. + + - Parameter uid: An audio device unique identifier. + + - Note: If unique identifier is not valid, `nil` will be returned. + */ + public static func lookup(by uid: String) -> AudioDevice? { + + let address = AudioObjectPropertyAddress( + mSelector: kAudioHardwarePropertyDeviceForUID, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + var deviceID = kAudioObjectUnknown + var cfUID = (uid as CFString) + + var translation = AudioValueTranslation( + mInputData: &cfUID, + mInputDataSize: UInt32(MemoryLayout.size), + mOutputData: &deviceID, + mOutputDataSize: UInt32(MemoryLayout.size) + ) + + let status = getPropertyData(AudioObjectID(kAudioObjectSystemObject), + address: address, + andValue: &translation) + + if noErr != status || deviceID == kAudioObjectUnknown { + return nil + } + + return lookup(by: deviceID) + } + + /** + All the audio device identifiers currently available in the system. + + - Note: This list may also include *Aggregate* and *Multi-Output* devices. + + - Returns: An array of `AudioObjectID` values. + */ + public class func allDeviceIDs() -> [AudioObjectID] { + + let address = AudioObjectPropertyAddress( + mSelector: kAudioHardwarePropertyDevices, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + let systemObjectID = AudioObjectID(kAudioObjectSystemObject) + var allIDs = [AudioObjectID]() + let status = getPropertyDataArray(systemObjectID, address: address, value: &allIDs, andDefaultValue: 0) + + return noErr == status ? allIDs : [] + } + + /** + All the audio devices currently available in the system. + + - Note: This list may also include *Aggregate* and *Multi-Output* devices. + + - Returns: An array of `AudioDevice` objects. + */ + public class func allDevices() -> [AudioDevice] { + + let deviceIDs = allDeviceIDs() + + let devices = deviceIDs.compactMap { AudioDevice.lookup(by: $0) } + + return devices + } + + /** + All the devices in the system that have at least one input. + + - Note: This list may also include *Aggregate* devices. + + - Returns: An array of `AudioDevice` objects. + */ + public class func allInputDevices() -> [AudioDevice] { + + let devices = allDevices() + + return devices.filter { $0.channels(direction: .recording) > 0 } + } + + /** + All the devices in the system that have at least one output. + + - Note: The list may also include *Aggregate* and *Multi-Output* devices. + + - Returns: An array of `AudioDevice` objects. + */ + public class func allOutputDevices() -> [AudioDevice] { + + let devices = allDevices() + + return devices.filter { $0.channels(direction: .playback) > 0 } + } + + /** + The default input device. + + - Returns: *(optional)* An `AudioDevice`. + */ + public class func defaultInputDevice() -> AudioDevice? { + + return defaultDevice(of: kAudioHardwarePropertyDefaultInputDevice) + } + + /** + The default output device. + + - Returns: *(optional)* An `AudioDevice`. + */ + public class func defaultOutputDevice() -> AudioDevice? { + + return defaultDevice(of: kAudioHardwarePropertyDefaultOutputDevice) + } + + /** + The default system output device. + + - Returns: *(optional)* An `AudioDevice`. + */ + public class func defaultSystemOutputDevice() -> AudioDevice? { + + return defaultDevice(of: kAudioHardwarePropertyDefaultSystemOutputDevice) + } + + + // MARK: - Default Device Functions + + /** + Promotes this device to become the default input device. + + - Returns: `true` on success, `false` otherwise. + */ + @discardableResult public func setAsDefaultInputDevice() -> Bool { + + return setDefaultDevice(kAudioHardwarePropertyDefaultInputDevice) + } + + /** + Promotes this device to become the default output device. + + - Returns: `true` on success, `false` otherwise. + */ + @discardableResult public func setAsDefaultOutputDevice() -> Bool { + + return setDefaultDevice(kAudioHardwarePropertyDefaultOutputDevice) + } + + /** + Promotes this device to become the default system output device. + + - Returns: `true` on success, `false` otherwise. + */ + @discardableResult public func setAsDefaultSystemDevice() -> Bool { + + return setDefaultDevice(kAudioHardwarePropertyDefaultSystemOutputDevice) + } + + + // MARK: - ✪ General Device Information Functions + + /** + The audio device's identifier (ID). + + - Note: This identifier will change with system restarts. + If you need an unique identifier that persists between restarts, use `uid` instead. + + - SeeAlso: `uid` + + - Returns: An audio device identifier. + */ + public var id: AudioObjectID { + + get { + + return objectID + + } + } + + /** + The audio device's name as reported by the system. + + - Returns: An audio device's name. + */ + public override var name: String { + + return getDeviceName() + } + + /** + The audio device's unique identifier (UID). + + - Note: This identifier is guaranted to uniquely identify a device in the system + and will not change even after restarts. Two (or more) identical audio devices + are also guaranteed to have unique identifiers. + + - SeeAlso: `id` + + - Returns: *(optional)* A `String` with the audio device `UID`. + */ + public var uid: String? { + + if let address = validAddress(selector: kAudioDevicePropertyDeviceUID) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + The audio device's model unique identifier. + + - Returns: *(optional)* A `String` with the audio device's model unique identifier. + */ + public var modelUID: String? { + + if let address = validAddress(selector: kAudioDevicePropertyModelUID) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + The audio device's manufacturer. + + - Returns: *(optional)* A `String` with the audio device's manufacturer name. + */ + public var manufacturer: String? { + + if let address = validAddress(selector: kAudioObjectPropertyManufacturer) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + The bundle identifier for an application that provides a GUI for configuring the AudioDevice. + By default, the value of this property is the bundle ID for *Audio MIDI Setup*. + + - Returns: *(optional)* A `String` pointing to the bundle identifier + */ + public var configurationApplication: String? { + + if let address = validAddress(selector: kAudioDevicePropertyConfigurationApplication) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + A transport type that indicates how the audio device is connected to the CPU. + + - Returns: *(optional)* A `TransportType`. + */ + public var transportType: TransportType? { + + let address = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyTransportType, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + var transportType = UInt32(0) + let status = getPropertyData(address, andValue: &transportType) + + if noErr == status { + switch transportType { + case kAudioDeviceTransportTypeBuiltIn: + + return .builtIn + + case kAudioDeviceTransportTypeAggregate: + + return .aggregate + + case kAudioDeviceTransportTypeVirtual: + + return .virtual + + case kAudioDeviceTransportTypePCI: + + return .pci + + case kAudioDeviceTransportTypeUSB: + + return .usb + + case kAudioDeviceTransportTypeFireWire: + + return .fireWire + + case kAudioDeviceTransportTypeBluetooth: + + return .bluetooth + + case kAudioDeviceTransportTypeBluetoothLE: + + return .bluetoothLE + + case kAudioDeviceTransportTypeHDMI: + + return .hdmi + + case kAudioDeviceTransportTypeDisplayPort: + + return .displayPort + + case kAudioDeviceTransportTypeAirPlay: + + return .airPlay + + case kAudioDeviceTransportTypeAVB: + + return .avb + + case kAudioDeviceTransportTypeThunderbolt: + + return .thunderbolt + + case kAudioDeviceTransportTypeUnknown: + + fallthrough + + default: + + return .unknown + + } + } + + return nil + } + + /** + Whether the audio device is included in the normal list of devices. + + - Note: Hidden devices can only be discovered by knowing their `UID` and + using `kAudioHardwarePropertyDeviceForUID`. + + - Returns: `true` when device is hidden, `false` otherwise. + */ + public func isHidden() -> Bool { + + if let address = validAddress(selector: kAudioDevicePropertyIsHidden) { + return getProperty(address: address) ?? false + } else { + return false + } + } + + /** + Whether the audio device's jack is connected for a given direction. + + - Parameter direction: A direction. + + - Returns: `true` when jack is connected, `false` otherwise. + */ + public func isJackConnected(direction: Direction) -> Bool? { + + if let address = validAddress(selector: kAudioDevicePropertyJackIsConnected, + scope: scope(direction: direction)) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + Whether the device is alive. + + - Returns: `true` when the device is alive, `false` otherwise. + */ + public func isAlive() -> Bool { + + if let address = validAddress(selector: kAudioDevicePropertyDeviceIsAlive) { + return getProperty(address: address) ?? false + } else { + return false + } + } + + /** + Whether the device is running. + + - Returns: `true` when the device is running, `false` otherwise. + */ + public func isRunning() -> Bool { + + if let address = validAddress(selector: kAudioDevicePropertyDeviceIsRunning) { + return getProperty(address: address) ?? false + } else { + return false + } + } + + /** + Whether the device is running somewhere. + + - Returns: `true` when the device is running somewhere, `false` otherwise. + */ + public func isRunningSomewhere() -> Bool { + + if let address = validAddress(selector: kAudioDevicePropertyDeviceIsRunningSomewhere) { + return getProperty(address: address) ?? false + } else { + return false + } + } + + /** + A human readable name for the channel number and direction specified. + + - Parameter channel: A channel. + - Parameter direction: A direction. + + - Returns: *(optional)* A `String` with the name of the channel. + */ + public func name(channel: UInt32, direction: Direction) -> String? { + + if let address = validAddress(selector: kAudioObjectPropertyElementName, + scope: scope(direction: direction), + element: channel) { + if let name: String = getProperty(address: address) { + return name.isEmpty ? nil : name + } else { + return nil + } + } else { + return nil + } + } + + /** + All the audio object identifiers that are owned by this audio device. + + - Returns: *(optional)* An array of `AudioObjectID` values. + */ + public func ownedObjectIDs() -> [AudioObjectID]? { + + let address = AudioObjectPropertyAddress( + mSelector: kAudioObjectPropertyOwnedObjects, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + var qualifierData = [kAudioObjectClassID] + let qualifierDataSize = UInt32(MemoryLayout.size * qualifierData.count) + var ownedObjects = [AudioObjectID]() + + let status = getPropertyDataArray(address, + qualifierDataSize: qualifierDataSize, + qualifierData: &qualifierData, + value: &ownedObjects, + andDefaultValue: AudioObjectID()) + + return noErr == status ? ownedObjects : nil + } + + /** + All the audio object identifiers representing the audio controls of this audio device. + + - Returns: *(optional)* An array of `AudioObjectID` values. + */ + public func controlList() -> [AudioObjectID]? { + + let address = AudioObjectPropertyAddress( + mSelector: kAudioObjectPropertyControlList, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + var controlList = [AudioObjectID]() + let status = getPropertyDataArray(address, value: &controlList, andDefaultValue: AudioObjectID()) + + return noErr == status ? controlList : nil + } + + /** + All the audio devices related to this audio device. + + - Returns: *(optional)* An array of `AudioDevice` objects. + */ + public func relatedDevices() -> [AudioDevice]? { + + let address = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyRelatedDevices, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + var relatedDevices = [AudioDeviceID]() + let status = getPropertyDataArray(address, value: &relatedDevices, andDefaultValue: AudioDeviceID()) + + if noErr == status { + return relatedDevices.compactMap { AudioDevice.lookup(by: $0) } + } + + return nil + } + + + // MARK: - 💣 LFE (Low Frequency Effects) Functions + + /** + Whether the audio device should claim ownership of any attached iSub or not. + + - Return: *(optional)* `true` when device should claim ownership, `false` otherwise. + */ + public var shouldOwniSub: Bool? { + + get { + + if let address = validAddress(selector: kAudioDevicePropertyDriverShouldOwniSub) { + return getProperty(address: address) + } else { + return nil + } + } + + set { + + if let address = validAddress(selector: kAudioDevicePropertyDriverShouldOwniSub) { + if let value = newValue { + let _ = setProperty(address: address, value: value) + } + } + } + } + + /** + Whether the audio device's LFE (Low Frequency Effects) output is muted or not. + + - Return: *(optional)* `true` when LFE output is muted, `false` otherwise. + */ + public var lfeMute: Bool? { + + get { + + if let address = validAddress(selector: kAudioDevicePropertySubMute) { + return getProperty(address: address) + } else { + return nil + } + } + + set { + + if let address = validAddress(selector: kAudioDevicePropertySubMute) { + if let value = newValue { + let _ = setProperty(address: address, value: value) + } + } + } + } + + /** + The audio device's LFE (Low Frequency Effects) scalar output volume. + + - Return: *(optional)* A `Float32` with the volume. + */ + public var lfeVolume: Float32? { + + get { + + if let address = validAddress(selector: kAudioDevicePropertySubVolumeScalar) { + return getProperty(address: address) + } else { + return nil + } + } + + set { + + if let address = validAddress(selector: kAudioDevicePropertySubVolumeScalar) { + if let value = newValue { + let _ = setProperty(address: address, value: value) + } + } + } + } + + /** + The audio device's LFE (Low Frequency Effects) output volume in decibels. + + - Return: *(optional)* A `Float32` with the volume. + */ + public var lfeVolumeDecibels: Float32? { + + get { + + if let address = validAddress(selector: kAudioDevicePropertySubVolumeDecibels) { + return getProperty(address: address) + } else { + return nil + } + } + + set { + + if let address = validAddress(selector: kAudioDevicePropertySubVolumeDecibels) { + if let value = newValue { + let _ = setProperty(address: address, value: value) + } + } + } + } + + + // MARK: - ⇄ Input/Output Layout Functions + + /** + The number of layout channels for a given direction. + + - Parameter direction: A direction. + + - Returns: *(optional)* A `UInt32` with the number of layout channels. + */ + public func layoutChannels(direction: Direction) -> UInt32? { + + var address = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyPreferredChannelLayout, + mScope: scope(direction: direction), + mElement: kAudioObjectPropertyElementMaster + ) + + if AudioObjectHasProperty(id, &address) { + var result = AudioChannelLayout() + let status = getPropertyData(address, andValue: &result) + + return noErr == status ? result.mNumberChannelDescriptions : nil + } + + return nil + } + + /** + The number of channels for a given direction. + + - Parameter direction: A direction. + + - Returns: A `UInt32` with the number of channels. + */ + public func channels(direction: Direction) -> UInt32 { + + if let streams = streams(direction: direction) { + return streams.map { $0.physicalFormat?.mChannelsPerFrame ?? 0 }.reduce(0, +) + } + + return 0 + } + + /** + Whether the device has only inputs but no outputs. + + - Returns: `true` when the device is input only, `false` otherwise. + */ + public func isInputOnlyDevice() -> Bool { + + return channels(direction: .playback) == 0 && channels(direction: .recording) > 0 + } + + /** + Whether the device has only outputs but no inputs. + + - Returns: `true` when the device is output only, `false` otherwise. + */ + public func isOutputOnlyDevice() -> Bool { + + return channels(direction: .recording) == 0 && channels(direction: .playback) > 0 + } + + + // MARK: - ⇉ Individual Channel Functions + + /** + A `VolumeInfo` struct containing information about a particular channel and direction combination. + + - Parameter channel: A channel. + - Parameter direction: A direction. + + - Returns: *(optional)* A `VolumeInfo` struct. + */ + public func volumeInfo(channel: UInt32, direction: Direction) -> VolumeInfo? { + + // Obtain volume info + var address: AudioObjectPropertyAddress + var hasAnyProperty = false + + address = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyVolumeScalar, + mScope: scope(direction: direction), + mElement: channel + ) + + var volumeInfo = VolumeInfo() + + if AudioObjectHasProperty(id, &address) { + var canSetVolumeBoolean = DarwinBoolean(false) + var status = AudioObjectIsPropertySettable(id, &address, &canSetVolumeBoolean) + + if noErr == status { + volumeInfo.canSetVolume = canSetVolumeBoolean.boolValue + volumeInfo.hasVolume = true + + var volume = Float32(0) + status = getPropertyData(address, andValue: &volume) + + if noErr == status { + volumeInfo.volume = volume + hasAnyProperty = true + } + } + } + + // Obtain mute info + address.mSelector = kAudioDevicePropertyMute + + if AudioObjectHasProperty(id, &address) { + var canMuteBoolean = DarwinBoolean(false) + var status = AudioObjectIsPropertySettable(id, &address, &canMuteBoolean) + + if noErr == status { + volumeInfo.canMute = canMuteBoolean.boolValue + + var isMutedValue = UInt32(0) + status = getPropertyData(address, andValue: &isMutedValue) + + if noErr == status { + volumeInfo.isMuted = Bool(isMutedValue) + hasAnyProperty = true + } + } + } + + // Obtain play thru info + address.mSelector = kAudioDevicePropertyPlayThru + + if AudioObjectHasProperty(id, &address) { + var canPlayThruBoolean = DarwinBoolean(false) + var status = AudioObjectIsPropertySettable(id, &address, &canPlayThruBoolean) + + if noErr == status { + volumeInfo.canPlayThru = canPlayThruBoolean.boolValue + + var isPlayThruSetValue = UInt32(0) + status = getPropertyData(address, andValue: &isPlayThruSetValue) + + if noErr == status { + volumeInfo.isPlayThruSet = Bool(isPlayThruSetValue) + hasAnyProperty = true + } + } + } + + return hasAnyProperty ? volumeInfo : nil + } + + /** + The scalar volume for a given channel and direction. + + - Parameter channel: A channel. + - Parameter direction: A direction. + + - Returns: *(optional)* A `Float32` value with the scalar volume. + */ + public func volume(channel: UInt32, direction: Direction) -> Float32? { + + if let address = validAddress(selector: kAudioDevicePropertyVolumeScalar, + scope: scope(direction: direction), + element: channel) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + The volume in decibels *(dbFS)* for a given channel and direction. + + - Parameter channel: A channel. + - Parameter direction: A direction. + + - Returns: *(optional)* A `Float32` value with the volume in decibels. + */ + public func volumeInDecibels(channel: UInt32, direction: Direction) -> Float32? { + + if let address = validAddress(selector: kAudioDevicePropertyVolumeDecibels, + scope: scope(direction: direction), + element: channel) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + Sets the channel's volume for a given direction. + + - Parameter volume: The new volume as a scalar value ranging from 0 to 1. + - Parameter channel: A channel. + - Parameter direction: A direction. + + - Returns: `true` on success, `false` otherwise. + */ + @discardableResult public func setVolume(_ volume: Float32, channel: UInt32, direction: Direction) -> Bool { + + if let address = validAddress(selector: kAudioDevicePropertyVolumeScalar, + scope: scope(direction: direction), + element: channel) { + return setProperty(address: address, value: volume) + } else { + return false + } + } + + /** + Mutes a channel for a given direction. + + - Parameter shouldMute: Whether channel should be muted or not. + - Parameter channel: A channel. + - Parameter direction: A direction. + + - Returns: `true` on success, `false` otherwise. + */ + @discardableResult public func setMute(_ shouldMute: Bool, channel: UInt32, direction: Direction) -> Bool { + + if let address = validAddress(selector: kAudioDevicePropertyMute, + scope: scope(direction: direction), + element: channel) { + return setProperty(address: address, value: shouldMute) + } else { + return false + } + } + + /** + Whether a channel is muted for a given direction. + + - Parameter channel: A channel. + - Parameter direction: A direction. + + - Returns: *(optional)* `true` if channel is muted, false otherwise. + */ + public func isMuted(channel: UInt32, direction: Direction) -> Bool? { + + if let address = validAddress(selector: kAudioDevicePropertyMute, + scope: scope(direction: direction), + element: channel) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + Whether a channel can be muted for a given direction. + + - Parameter channel: A channel. + - Parameter direction: A direction. + + - Returns: `true` if channel can be muted, `false` otherwise. + */ + public func canMute(channel: UInt32, direction: Direction) -> Bool { + + return volumeInfo(channel: channel, direction: direction)?.canMute ?? false + } + + /** + Whether a channel's volume can be set for a given direction. + + - Parameter channel: A channel. + - Parameter direction: A direction. + + - Returns: `true` if the channel's volume can be set, `false` otherwise. + */ + public func canSetVolume(channel: UInt32, direction: Direction) -> Bool { + + return volumeInfo(channel: channel, direction: direction)?.canSetVolume ?? false + } + + /** + A list of channel numbers that best represent the preferred stereo channels + used by this device. In most occasions this will be channels 1 and 2. + + - Parameter direction: A direction. + + - Returns: A `StereoPair` tuple containing the channel numbers. + */ + public func preferredChannelsForStereo(direction: Direction) -> StereoPair? { + + let address = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyPreferredChannelsForStereo, + mScope: scope(direction: direction), + mElement: kAudioObjectPropertyElementMaster + ) + + var preferredChannels = [UInt32]() + let status = getPropertyDataArray(address, value: &preferredChannels, andDefaultValue: 0) + + if noErr == status && preferredChannels.count == 2 { + return (left: preferredChannels[0], right: preferredChannels[1]) + } else { + return nil + } + } + + /** + Attempts to set the new preferred channels for stereo for a given direction. + + - Parameter channels: A `StereoPair` representing the preferred channels. + - Parameter direction: A direction. + + - Returns: `true` on success, `false` otherwise. + */ + @discardableResult public func setPreferredChannelsForStereo(channels: StereoPair, direction: Direction) -> Bool { + + let address = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyPreferredChannelsForStereo, + mScope: scope(direction: direction), + mElement: kAudioObjectPropertyElementMaster + ) + + var preferredChannels = [channels.left, channels.right] + let status = setPropertyData(address, andValue: &preferredChannels) + + return noErr == status + } + + + // MARK: - 🔊 Master Volume/Balance Functions + + /** + Whether the master volume can be muted for a given direction. + + - Parameter direction: A direction. + + - Returns: `true` when the volume can be muted, `false` otherwise. + */ + public func canMuteVirtualMasterChannel(direction: Direction) -> Bool { + + if canMute(channel: kAudioObjectPropertyElementMaster, direction: direction) == true { + return true + } + + if let preferredChannelsForStereo = preferredChannelsForStereo(direction: direction) { + if canMute(channel: preferredChannelsForStereo.0, direction: direction) && canMute(channel: preferredChannelsForStereo.1, direction: direction) { + return true + } + } + + return false + } + + /** + Whether the master volume can be set for a given direction. + + - Parameter direction: A direction. + + - Returns: `true` when the volume can be set, `false` otherwise. + */ + public func canSetVirtualMasterVolume(direction: Direction) -> Bool { + + if validAddress(selector: kAudioHardwareServiceDeviceProperty_VirtualMasterVolume, + scope: scope(direction: direction)) != nil { + return true + } else { + return false + } + } + + /** + Sets the virtual master volume for a given direction. + + - Parameter volume: The new volume as a scalar value ranging from 0 to 1. + - Parameter direction: A direction. + + - Returns: `true` on success, `false` otherwise. + */ + @discardableResult public func setVirtualMasterVolume(_ volume: Float32, direction: Direction) -> Bool { + + if let address = validAddress(selector: kAudioHardwareServiceDeviceProperty_VirtualMasterVolume, + scope: scope(direction: direction)) { + return setProperty(address: address, value: volume) + } else { + return false + } + } + + /** + The virtual master scalar volume for a given direction. + + - Parameter direction: A direction. + + - Returns: *(optional)* A `Float32` value with the scalar volume. + */ + public func virtualMasterVolume(direction: Direction) -> Float32? { + + if let address = validAddress(selector: kAudioHardwareServiceDeviceProperty_VirtualMasterVolume, + scope: scope(direction: direction)) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + The virtual master volume in decibels for a given direction. + + - Parameter direction: A direction. + + - Returns: *(optional)* A `Float32` value with the volume in decibels. + */ + public func virtualMasterVolumeInDecibels(direction: Direction) -> Float32? { + + var referenceChannel: UInt32 + + if canSetVolume(channel: kAudioObjectPropertyElementMaster, direction: direction) { + referenceChannel = kAudioObjectPropertyElementMaster + } else { + if let channels = preferredChannelsForStereo(direction: direction) { + referenceChannel = channels.0 + } else { + return nil + } + } + + if let masterVolume = virtualMasterVolume(direction: direction) { + return scalarToDecibels(volume: masterVolume, channel: referenceChannel, direction: direction) + } else { + return nil + } + } + + /** + Whether the volume is muted for a given direction. + + - Parameter direction: A direction. + + - Returns: `true` when muted, `false` otherwise. + */ + public func isMasterChannelMuted(direction: Direction) -> Bool? { + + return isMuted(channel: kAudioObjectPropertyElementMaster, direction: direction) + } + + /** + The virtual master balance for a given direction. + + The range is from 0 (all power to the left) to 1 (all power to the right) with the value of 0.5 signifying + that the channels have equal power. + + - Parameter direction: A direction. + + - Returns: *(optional)* A `Float32` value with the stereo balance. + */ + public func virtualMasterBalance(direction: Direction) -> Float32? { + + if let address = validAddress(selector: kAudioHardwareServiceDeviceProperty_VirtualMasterBalance, + scope: scope(direction: direction)) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + Sets the new virtual master balance for a given direction. + + The range is from 0 (all power to the left) to 1 (all power to the right) with the value of 0.5 signifying + that the channels have equal power. + + - Parameter value: The new balance. + - Parameter direction: A direction. + + - Returns: `true` on success, `false` otherwise. + */ + @discardableResult public func setVirtualMasterBalance(_ value: Float32, direction: Direction) -> Bool { + + if let address = validAddress(selector: kAudioHardwareServiceDeviceProperty_VirtualMasterBalance, + scope: scope(direction: direction)) { + return setProperty(address: address, value: value) + } else { + return false + } + } + + + // MARK: - 〰 Sample Rate Functions + + /** + The actual audio device's sample rate. + + - Returns: *(optional)* A `Float64` value with the actual sample rate. + */ + public func actualSampleRate() -> Float64? { + + if let address = validAddress(selector: kAudioDevicePropertyActualSampleRate) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + The nominal audio device's sample rate. + + - Returns: *(optional)* A `Float64` value with the nominal sample rate. + */ + public func nominalSampleRate() -> Float64? { + + if let address = validAddress(selector: kAudioDevicePropertyNominalSampleRate) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + Sets the nominal sample rate. + + - Parameter sampleRate: The new nominal sample rate. + + - Returns: `true` on success, `false` otherwise. + */ + @discardableResult public func setNominalSampleRate(_ sampleRate: Float64) -> Bool { + + if let address = validAddress(selector: kAudioDevicePropertyNominalSampleRate) { + return setProperty(address: address, value: sampleRate) + } else { + return false + } + } + + /** + A list of all the nominal sample rates supported by this audio device. + + - Returns: *(optional)* A `Float64` array containing the nominal sample rates. + */ + public func nominalSampleRates() -> [Float64]? { + + guard let address = validAddress(selector: kAudioDevicePropertyAvailableNominalSampleRates, + scope: kAudioObjectPropertyScopeWildcard) else { return nil } + + var sampleRates = [Float64]() + var valueRanges = [AudioValueRange]() + let status = getPropertyDataArray(address, value: &valueRanges, andDefaultValue: AudioValueRange()) + + if noErr != status { + return nil + } + + // A list of all the possible sample rates up to 192kHz + // to be used in the case we receive a range (see below) + let possibleRates: [Float64] = [ + 6400, 8000, 11025, 12000, + 16000, 22050, 24000, 32000, + 44100, 48000, 64000, 88200, + 96000, 128000, 176400, 192000 + ] + + for valueRange in valueRanges { + if valueRange.mMinimum < valueRange.mMaximum { + // We got a range. + // + // This could be a headset audio device (i.e., CS50/CS60-USB Headset) + // or a virtual audio driver (i.e., "System Audio Recorder" by WonderShare AllMyMusic) + if let startIndex = possibleRates.index(of: valueRange.mMinimum), + let endIndex = possibleRates.index(of: valueRange.mMaximum) { + sampleRates += possibleRates[startIndex.. UInt32? { + + if let address = validAddress(selector: kAudioDevicePropertyClockSource, + scope: kAudioObjectPropertyScopeGlobal) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + The current clock source name for this audio device. + + - Returns: *(optional)* A `String` containing the clock source name. + */ + public func clockSourceName() -> String? { + + if let sourceID = clockSourceID() { + return clockSourceName(clockSourceID: sourceID) + } + + return nil + } + + /** + A list of all the clock source identifiers available for this audio device. + + - Returns: *(optional)* A `UInt32` array containing all the clock source identifiers. + */ + public func clockSourceIDs() -> [UInt32]? { + + guard let address = validAddress(selector: kAudioDevicePropertyClockSources, + scope: kAudioObjectPropertyScopeGlobal, + element: kAudioObjectPropertyElementMaster) else { return nil } + + var clockSourceIDs = [UInt32]() + let status = getPropertyDataArray(address, value: &clockSourceIDs, andDefaultValue: 0) + + if noErr != status { + return nil + } + + return clockSourceIDs + } + + /** + A list of all the clock source names available for this audio device. + + - Returns: *(optional)* A `String` array containing all the clock source names. + */ + public func clockSourceNames() -> [String]? { + + if let clockSourceIDs = clockSourceIDs() { + return clockSourceIDs.map { + // We expect clockSourceNameForClockSourceID to never fail in this case, + // but in the unlikely case it does, we provide a default value. + clockSourceName(clockSourceID: $0) ?? "Clock source \(clockSourceID)" + } + } + + return nil + } + + /** + Returns the clock source name for a given clock source ID. + + - Parameter clockSourceID: A clock source ID. + + - Returns: *(optional)* A `String` with the source clock name. + */ + public func clockSourceName(clockSourceID: UInt32) -> String? { + + var name: CFString = "" as CFString + var theClockSourceID = clockSourceID + + var translation = AudioValueTranslation( + mInputData: &theClockSourceID, + mInputDataSize: UInt32(MemoryLayout.size), + mOutputData: &name, + mOutputDataSize: UInt32(MemoryLayout.size) + ) + + let address = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyClockSourceNameForIDCFString, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + let status = getPropertyData(address, andValue: &translation) + + return noErr == status ? (name as String) : nil + } + + /** + Sets the clock source for this audio device. + + - Parameter clockSourceID: A clock source ID. + + - Returns: `true` on success, `false` otherwise. + */ + @discardableResult public func setClockSourceID(_ clockSourceID: UInt32) -> Bool { + + if let address = validAddress(selector: kAudioDevicePropertyClockSource, + scope: kAudioObjectPropertyScopeGlobal) { + return setProperty(address: address, value: clockSourceID) + } else { + return false + } + } + + + // MARK: - ↹ Latency Functions + + /** + The latency in frames for the specified direction. + + - Parameter direction: A direction. + + - Returns: *(optional)* A `UInt32` value with the latency in frames. + */ + public func latency(direction: Direction) -> UInt32? { + + if let address = validAddress(selector: kAudioDevicePropertyLatency, + scope: scope(direction: direction)) { + return getProperty(address: address) + } else { + return nil + } + } + + /** + The safety offset frames for the specified direction. + + - Parameter direction: A direction. + + - Returns: *(optional)* A `UInt32` value with the safety offset in frames. + */ + public func safetyOffset(direction: Direction) -> UInt32? { + + if let address = validAddress(selector: kAudioDevicePropertySafetyOffset, + scope: scope(direction: direction)) { + return getProperty(address: address) + } else { + return nil + } + } + + + // MARK: - 🐗 Hog Mode Functions + + /** + Indicates the `pid` that currently owns exclusive access to the audio device or + a value of `-1` indicating that the device is currently available to all processes. + + - Returns: *(optional)* A `pid_t` value. + */ + public func hogModePID() -> pid_t? { + + guard let address = validAddress(selector: kAudioDevicePropertyHogMode, + scope: kAudioObjectPropertyScopeWildcard) else { return nil } + + var pid = pid_t() + let status = getPropertyData(address, andValue: &pid) + + return noErr == status ? pid : nil + } + + /** + Toggles hog mode on/off + + - Returns: `true` on success, `false` otherwise. + */ + private func toggleHogMode() -> Bool { + + if let address = validAddress(selector: kAudioDevicePropertyHogMode, + scope: kAudioObjectPropertyScopeWildcard) { + return setProperty(address: address, value: 0) + } else { + return false + } + } + + /** + Attempts to set the `pid` that currently owns exclusive access to the + audio device. + + - Returns: `true` on success, `false` otherwise. + */ + @discardableResult public func setHogMode() -> Bool { + + if hogModePID() != pid_t(ProcessInfo.processInfo.processIdentifier) { + return toggleHogMode() + } else { + return false + } + } + + /** + Attempts to make the audio device available to all processes by setting + the hog mode to `-1`. + + - Returns: `true` on success, `false` otherwise. + */ + public func unsetHogMode() -> Bool { + + if hogModePID() == pid_t(ProcessInfo.processInfo.processIdentifier) { + return toggleHogMode() + } else { + return false + } + } + + + // MARK: - ♺ Volume Conversion Functions + + /** + Converts a scalar volume to a decibel *(dbFS)* volume for the given channel and direction. + + - Parameter volume: A scalar volume. + - Parameter channel: A channel number. + - Parameter direction: A direction. + + - Returns: *(optional)* A `Float32` value with the scalar volume converted in decibels. + */ + public func scalarToDecibels(volume: Float32, channel: UInt32, direction: Direction) -> Float32? { + + guard let address = validAddress(selector: kAudioDevicePropertyVolumeScalarToDecibels, + scope: scope(direction: direction), + element: channel) else { return nil } + + var inOutVolume = volume + let status = getPropertyData(address, andValue: &inOutVolume) + + return noErr == status ? inOutVolume : nil + } + + /** + Converts a relative decibel *(dbFS)* volume to a scalar volume for the given channel and direction. + + - Parameter volume: A volume in relative decibels (dbFS). + - Parameter channel: A channel number. + - Parameter direction: A direction. + + - Returns: *(optional)* A `Float32` value with the decibels volume converted to scalar. + */ + public func decibelsToScalar(volume: Float32, channel: UInt32, direction: Direction) -> Float32? { + + guard let address = validAddress(selector: kAudioDevicePropertyVolumeDecibelsToScalar, + scope: scope(direction: direction), + element: channel) else { return nil } + + var inOutVolume = volume + let status = getPropertyData(address, andValue: &inOutVolume) + + return noErr == status ? inOutVolume : nil + } + + + // MARK: - ♨︎ Stream Functions + + /** + Returns a list of streams for a given direction. + + - Parameter direction: A direction. + + - Returns: *(optional)* An array of `AudioStream` objects. + */ + public func streams(direction: Direction) -> [AudioStream]? { + + guard let address = validAddress(selector: kAudioDevicePropertyStreams, + scope: scope(direction: direction)) else { return nil } + + var streamIDs = [AudioStreamID]() + let status = getPropertyDataArray(address, value: &streamIDs, andDefaultValue: 0) + + if noErr != status { + return nil + } + + return streamIDs.compactMap { AudioStream.lookup(by: $0) } + } + + + // MARK: - Private Functions + + private func setDefaultDevice(_ type: AudioObjectPropertySelector) -> Bool { + + let address = self.address(selector: type) + var deviceID = UInt32(id) + let status = setPropertyData(AudioObjectID(kAudioObjectSystemObject), address: address, andValue: &deviceID) + + return noErr == status + } + + private func getDeviceName() -> String { + + return super.name ?? (cachedDeviceName ?? "") + } + + private class func defaultDevice(of type: AudioObjectPropertySelector) -> AudioDevice? { + + let address = self.address(selector: type) + var deviceID = AudioDeviceID() + let status = getPropertyData(AudioObjectID(kAudioObjectSystemObject), address: address, andValue: &deviceID) + + return noErr == status ? AudioDevice.lookup(by: deviceID) : nil + } + + + // MARK: - Notification Book-keeping + + private func registerForNotifications() { + + if isRegisteredForNotifications { + unregisterForNotifications() + } + + var address = AudioObjectPropertyAddress( + mSelector: kAudioObjectPropertySelectorWildcard, + mScope: kAudioObjectPropertyScopeWildcard, + mElement: kAudioObjectPropertyElementWildcard + ) + + let err = AudioObjectAddPropertyListenerBlock(id, &address, notificationsQueue, propertyListenerBlock) + + if noErr != err { + log("Error on AudioObjectAddPropertyListenerBlock: \(err)") + } + + isRegisteredForNotifications = noErr == err + } + + private func unregisterForNotifications() { + + if isAlive() && isRegisteredForNotifications { + var address = AudioObjectPropertyAddress( + mSelector: kAudioObjectPropertySelectorWildcard, + mScope: kAudioObjectPropertyScopeWildcard, + mElement: kAudioObjectPropertyElementWildcard + ) + + let err = AudioObjectRemovePropertyListenerBlock(id, &address, notificationsQueue, propertyListenerBlock) + + if noErr != err { + log("Error on AudioObjectRemovePropertyListenerBlock: \(err)") + } + + isRegisteredForNotifications = noErr != err + } else { + isRegisteredForNotifications = false + } + } +} + + +extension AudioDevice: CustomStringConvertible { + + // MARK: - CustomStringConvertible Protocol + + /** + Returns a string describing this audio device. + */ + public var description: String { + + return "\(name) (\(id))" + } +} diff --git a/Pods/AMCoreAudio/AMCoreAudio/AudioHardware.swift b/Pods/AMCoreAudio/AMCoreAudio/AudioHardware.swift new file mode 100644 index 0000000..f490d38 --- /dev/null +++ b/Pods/AMCoreAudio/AMCoreAudio/AudioHardware.swift @@ -0,0 +1,230 @@ +// +// AudioHardware.swift +// AMCoreAudio +// +// Created by Ruben on 7/9/15. +// Copyright © 2015 9Labs. All rights reserved. +// + +import Foundation + + +/** + Represents an `AudioHardware` event. + */ +public enum AudioHardwareEvent: Event { + /** + Called whenever the list of hardware devices and device subdevices changes. + (i.e., devices that are part of *Aggregate* or *Multi-Output* devices.) + */ + case deviceListChanged(addedDevices: [AudioDevice], removedDevices: [AudioDevice]) + + /** + Called whenever the default input device changes. + */ + case defaultInputDeviceChanged(audioDevice: AudioDevice) + + /** + Called whenever the default output device changes. + */ + case defaultOutputDeviceChanged(audioDevice: AudioDevice) + + /** + Called whenever the default system output device changes. + */ + case defaultSystemOutputDeviceChanged(audioDevice: AudioDevice) +} + + +/** + This class allows subscribing to hardware-related audio notifications. + + For a comprehensive list of supported notifications, see `AudioHardwareEvent`. + */ +final public class AudioHardware { + + /** + Returns a singleton `AudioHardware` instance. + */ + public static let sharedInstance = AudioHardware() + + /** + An auto-maintained array of all the audio devices currently available in the system. + + - Note: This list may also include *Aggregate* and *Multi-Output* devices. + + - Returns: An array of `AudioDevice` objects. + */ + private var allKnownDevices = [AudioDevice]() + + private var isRegisteredForNotifications = false + + private lazy var notificationsQueue: DispatchQueue = { + + return DispatchQueue(label: "io.9labs.AMCoreAudio.hardwareNotifications", attributes: .concurrent) + }() + + private lazy var propertyListenerBlock: AudioObjectPropertyListenerBlock = { [weak self] (inNumberAddresses, inAddresses) -> Void in + + let address = inAddresses.pointee + let notificationCenter = NotificationCenter.defaultCenter + + switch address.mSelector { + case kAudioObjectPropertyOwnedObjects: + + // Get the latest device list + let latestDeviceList = AudioDevice.allDevices() + + let addedDevices = latestDeviceList.filter { (audioDevice) -> Bool in + let isContained = self?.allKnownDevices.contains { return $0 == audioDevice } ?? false + + return !isContained + } + + let removedDevices = self?.allKnownDevices.filter { (audioDevice) -> Bool in + let isContained = latestDeviceList.contains { return $0 == audioDevice } + + return !isContained + } ?? [] + + // Add new devices + for device in addedDevices { + self?.add(device: device) + } + + // Remove old devices + for device in removedDevices { + self?.remove(device: device) + } + + notificationCenter.publish(AudioHardwareEvent.deviceListChanged( + addedDevices: addedDevices, + removedDevices: removedDevices + )) + + case kAudioHardwarePropertyDefaultInputDevice: + + if let audioDevice = AudioDevice.defaultInputDevice() { + notificationCenter.publish(AudioHardwareEvent.defaultInputDeviceChanged(audioDevice: audioDevice)) + } + + case kAudioHardwarePropertyDefaultOutputDevice: + + if let audioDevice = AudioDevice.defaultOutputDevice() { + notificationCenter.publish(AudioHardwareEvent.defaultOutputDeviceChanged(audioDevice: audioDevice)) + } + + case kAudioHardwarePropertyDefaultSystemOutputDevice: + + if let audioDevice = AudioDevice.defaultSystemOutputDevice() { + notificationCenter.publish(AudioHardwareEvent.defaultSystemOutputDeviceChanged(audioDevice: audioDevice)) + } + + default: + + break + + } + } + + + // MARK: - Public Functions + + deinit { + + disableDeviceMonitoring() + } + + /** + Enables device monitoring so events like the ones below are generated: + + - added or removed device + - new default input device + - new default output device + - new default system output device + + - SeeAlso: disableDeviceMonitoring() + */ + internal func enableDeviceMonitoring() { + + registerForNotifications() + + let allDevices = AudioDevice.allDevices() + + for device in allDevices { + add(device: device) + } + } + + /** + Disables device monitoring. + + - SeeAlso: enableDeviceMonitoring() + */ + internal func disableDeviceMonitoring() { + + for device in allKnownDevices { + remove(device: device) + } + + unregisterForNotifications() + } + + + // MARK: - Private Functions + + private func add(device: AudioDevice) { + + allKnownDevices.append(device) + } + + private func remove(device: AudioDevice) { + + if let idx = allKnownDevices.index(of: device) { + allKnownDevices.remove(at: idx) + } + } + + + // MARK: - Notification Book-keeping + + private func registerForNotifications() { + + if isRegisteredForNotifications { + unregisterForNotifications() + } + + var address = AudioObjectPropertyAddress( + mSelector: kAudioObjectPropertySelectorWildcard, + mScope: kAudioObjectPropertyScopeWildcard, + mElement: kAudioObjectPropertyElementWildcard + ) + + let err = AudioObjectAddPropertyListenerBlock(AudioObjectID(kAudioObjectSystemObject), &address, notificationsQueue, propertyListenerBlock) + + if noErr != err { + log("Error on AudioObjectAddPropertyListenerBlock: \(err)") + } + + isRegisteredForNotifications = noErr == err + } + + private func unregisterForNotifications() { + + if isRegisteredForNotifications { + var address = AudioObjectPropertyAddress( + mSelector: kAudioObjectPropertySelectorWildcard, + mScope: kAudioObjectPropertyScopeWildcard, + mElement: kAudioObjectPropertyElementWildcard + ) + + let err = AudioObjectRemovePropertyListenerBlock(AudioObjectID(kAudioObjectSystemObject), &address, notificationsQueue, propertyListenerBlock) + + if noErr != err { + log("Error on AudioObjectRemovePropertyListenerBlock: \(err)") + } + + isRegisteredForNotifications = noErr != err + } + } +} diff --git a/Pods/AMCoreAudio/AMCoreAudio/AudioObject.swift b/Pods/AMCoreAudio/AMCoreAudio/AudioObject.swift new file mode 100644 index 0000000..1b63758 --- /dev/null +++ b/Pods/AMCoreAudio/AMCoreAudio/AudioObject.swift @@ -0,0 +1,431 @@ +// +// AudioObject.swift +// AMCoreAudio +// +// Created by Ruben Nine on 13/04/16. +// Copyright © 2016 9Labs. All rights reserved. +// + +import Foundation +import CoreAudio.AudioHardwareBase + + +internal class AudioObjectPool: NSObject { + + static var instancePool: NSMapTable = NSMapTable.weakToWeakObjects() +} + + +/** + This class represents a Core Audio object currently present in the system. In Core Audio, + audio objects are referenced by its `AudioObjectID` and belong to a specific `AudioClassID`. + For more information, please refer to Core Audio's documentation or source code. + */ +public class AudioObject { + + internal var objectID: AudioObjectID + + internal init(objectID: AudioObjectID) { + + self.objectID = objectID + } + + deinit { + + // NO-OP + } + + /** + The `AudioClassID` that identifies the class of this audio object. + + - Returns: *(optional)* An `AudioClassID`. + */ + public lazy var classID: AudioClassID? = { + + var address = AudioObjectPropertyAddress( + mSelector: kAudioObjectPropertyClass, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + if !AudioObjectHasProperty(self.objectID, &address) { + return nil + } + + var klassID = AudioClassID() + let status = self.getPropertyData(address, andValue: &klassID) + + if noErr != status { + return nil + } + + return klassID + }() + + /** + The audio object that owns this audio object. + + - Returns: *(optional)* An `AudioObject`. + */ + public lazy var owningObject: AudioObject? = { + + var address = AudioObjectPropertyAddress( + mSelector: kAudioObjectPropertyOwner, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + if !AudioObjectHasProperty(self.objectID, &address) { + return nil + } + + var objectID = AudioObjectID() + let status = self.getPropertyData(address, andValue: &objectID) + + if noErr != status { + return nil + } + + return AudioObject(objectID: objectID) + }() + + /** + The audio device that owns this audio object. + + - Returns: *(optional)* An `AudioDevice`. + */ + public lazy var owningDevice: AudioDevice? = { + + guard let object = self.owningObject, object.classID == kAudioDeviceClassID else { return nil } + + return AudioDevice.lookup(by: object.objectID) + }() + + /** + The audio object's name as reported by the system. + + - Returns: *(optional)* An audio object's name. + */ + internal var name: String? { + + var name: CFString = "" as CFString + + let address = AudioObjectPropertyAddress( + mSelector: kAudioObjectPropertyName, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + let status = getPropertyData(address, andValue: &name) + + return noErr == status ? (name as String) : nil + } +} + +extension AudioObject { + + + // MARK: - Class Functions + + internal class func address(selector: AudioObjectPropertySelector, scope: AudioObjectPropertyScope = kAudioObjectPropertyScopeGlobal, element: AudioObjectPropertyElement = kAudioObjectPropertyElementMaster) -> AudioObjectPropertyAddress { + + return AudioObjectPropertyAddress(mSelector: selector, + mScope: scope, + mElement: element) + } + + internal class func getPropertyDataSize(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, qualifierDataSize: UInt32?, qualifierData: inout [Q], andSize size: inout UInt32) -> (OSStatus) { + + var theAddress = address + + return AudioObjectGetPropertyDataSize(objectID, &theAddress, qualifierDataSize ?? UInt32(0), &qualifierData, &size) + } + + internal class func getPropertyDataSize(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, qualifierDataSize: UInt32?, qualifierData: inout Q, andSize size: inout UInt32) -> (OSStatus) { + + var theAddress = address + + return AudioObjectGetPropertyDataSize(objectID, &theAddress, qualifierDataSize ?? UInt32(0), &qualifierData, &size) + } + + internal class func getPropertyDataSize(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, andSize size: inout UInt32) -> (OSStatus) { + + var nilValue: ExpressibleByNilLiteral? + + return getPropertyDataSize(objectID, address: address, qualifierDataSize: nil, qualifierData: &nilValue, andSize: &size) + } + + internal class func getPropertyData(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, andValue value: inout T) -> OSStatus { + + var theAddress = address + var size = UInt32(MemoryLayout.size) + let status = AudioObjectGetPropertyData(objectID, &theAddress, UInt32(0), nil, &size, &value) + + return status + } + + internal class func getPropertyDataArray(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, qualifierDataSize: UInt32?, qualifierData: inout Q, value: inout [T], andDefaultValue defaultValue: T) -> OSStatus { + + var size = UInt32(0) + let sizeStatus = getPropertyDataSize(objectID, address: address, qualifierDataSize: qualifierDataSize, qualifierData: &qualifierData, andSize: &size) + + if noErr == sizeStatus { + value = [T](repeating: defaultValue, count: Int(size) / MemoryLayout.size) + } else { + return sizeStatus + } + + var theAddress = address + let status = AudioObjectGetPropertyData(objectID, &theAddress, qualifierDataSize ?? UInt32(0), &qualifierData, &size, &value) + + return status + } + + internal class func getPropertyDataArray(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, qualifierDataSize: UInt32?, qualifierData: inout [Q], value: inout [T], andDefaultValue defaultValue: T) -> OSStatus { + + var size = UInt32(0) + let sizeStatus = getPropertyDataSize(objectID, address: address, qualifierDataSize: qualifierDataSize, qualifierData: &qualifierData, andSize: &size) + + if noErr == sizeStatus { + value = [T](repeating: defaultValue, count: Int(size) / MemoryLayout.size) + } else { + return sizeStatus + } + + var theAddress = address + let status = AudioObjectGetPropertyData(objectID, &theAddress, qualifierDataSize ?? UInt32(0), &qualifierData, &size, &value) + + return status + } + + internal class func getPropertyDataArray(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, value: inout [T], andDefaultValue defaultValue: T) -> OSStatus { + + var nilValue: ExpressibleByNilLiteral? + + return getPropertyDataArray(objectID, address: address, qualifierDataSize: nil, qualifierData: &nilValue, value: &value, andDefaultValue: defaultValue) + } + + + // MARK: - Instance Functions + + internal func getPropertyDataSize(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, qualifierDataSize: UInt32?, qualifierData: inout [Q], andSize size: inout UInt32) -> (OSStatus) { + + return type(of: self).getPropertyDataSize(objectID, address: address, qualifierDataSize: qualifierDataSize, qualifierData: &qualifierData, andSize: &size) + } + + internal func getPropertyDataSize(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, qualifierDataSize: UInt32?, qualifierData: inout Q, andSize size: inout UInt32) -> (OSStatus) { + + return type(of: self).getPropertyDataSize(objectID, address: address, qualifierDataSize: qualifierDataSize, qualifierData: &qualifierData, andSize: &size) + } + + internal func getPropertyDataSize(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, andSize size: inout UInt32) -> OSStatus { + + return type(of: self).getPropertyDataSize(objectID, address: address, andSize: &size) + } + + internal func getPropertyDataSize(_ address: AudioObjectPropertyAddress, qualifierDataSize: UInt32?, qualifierData: inout [Q], andSize size: inout UInt32) -> (OSStatus) { + + return type(of: self).getPropertyDataSize(objectID, address: address, qualifierDataSize: qualifierDataSize, qualifierData: &qualifierData, andSize: &size) + } + + internal func getPropertyDataSize(_ address: AudioObjectPropertyAddress, qualifierDataSize: UInt32?, qualifierData: inout Q, andSize size: inout UInt32) -> (OSStatus) { + + return type(of: self).getPropertyDataSize(objectID, address: address, qualifierDataSize: qualifierDataSize, qualifierData: &qualifierData, andSize: &size) + } + + internal func getPropertyDataSize(_ address: AudioObjectPropertyAddress, andSize size: inout UInt32) -> OSStatus { + + return type(of: self).getPropertyDataSize(objectID, address: address, andSize: &size) + } + + internal func getPropertyData(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, andValue value: inout T) -> OSStatus { + + return type(of: self).getPropertyData(objectID, address: address, andValue: &value) + } + + internal func getPropertyDataArray(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, qualifierDataSize: UInt32?, qualifierData: inout Q, value: inout [T], andDefaultValue defaultValue: T) -> OSStatus { + + return type(of: self).getPropertyDataArray(objectID, address: address, qualifierDataSize: qualifierDataSize, qualifierData: &qualifierData, value: &value, andDefaultValue: defaultValue) + } + + internal func getPropertyData(_ address: AudioObjectPropertyAddress, andValue value: inout T) -> OSStatus { + + return type(of: self).getPropertyData(objectID, address: address, andValue: &value) + } + + internal func getPropertyDataArray(_ address: AudioObjectPropertyAddress, qualifierDataSize: UInt32?, qualifierData: inout Q, value: inout [T], andDefaultValue defaultValue: T) -> OSStatus { + + return type(of: self).getPropertyDataArray(objectID, address: address, qualifierDataSize: qualifierDataSize, qualifierData: &qualifierData, value: &value, andDefaultValue: defaultValue) + } + + internal func getPropertyDataArray(_ address: AudioObjectPropertyAddress, qualifierDataSize: UInt32?, qualifierData: inout [Q], value: inout [T], andDefaultValue defaultValue: T) -> OSStatus { + + return type(of: self).getPropertyDataArray(objectID, address: address, qualifierDataSize: qualifierDataSize, qualifierData: &qualifierData, value: &value, andDefaultValue: defaultValue) + } + + internal func getPropertyDataArray(_ address: AudioObjectPropertyAddress, value: inout [T], andDefaultValue defaultValue: T) -> OSStatus { + + return type(of: self).getPropertyDataArray(objectID, address: address, value: &value, andDefaultValue: defaultValue) + } + + internal func setPropertyData(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, andValue value: inout T) -> OSStatus { + + var theAddress = address + let size = UInt32(MemoryLayout.size) + let status = AudioObjectSetPropertyData(objectID, &theAddress, UInt32(0), nil, size, &value) + + return status + } + + internal func setPropertyData(_ objectID: AudioObjectID, address: AudioObjectPropertyAddress, andValue value: inout [T]) -> OSStatus { + + var theAddress = address + let size = UInt32(value.count * MemoryLayout.size) + let status = AudioObjectSetPropertyData(objectID, &theAddress, UInt32(0), nil, size, &value) + + return status + } + + internal func setPropertyData(_ address: AudioObjectPropertyAddress, andValue value: inout T) -> OSStatus { + + return setPropertyData(objectID, address: address, andValue: &value) + } + + internal func setPropertyData(_ address: AudioObjectPropertyAddress, andValue value: inout [T]) -> OSStatus { + + return setPropertyData(objectID, address: address, andValue: &value) + } + + internal func address(selector: AudioObjectPropertySelector, scope: AudioObjectPropertyScope = kAudioObjectPropertyScopeGlobal, element: AudioObjectPropertyElement = kAudioObjectPropertyElementMaster) -> AudioObjectPropertyAddress { + + return AudioObject.address(selector: selector, scope: scope, element: element) + } + + internal func validAddress(selector: AudioObjectPropertySelector, scope: AudioObjectPropertyScope = kAudioObjectPropertyScopeGlobal, element: AudioObjectPropertyElement = kAudioObjectPropertyElementMaster) -> AudioObjectPropertyAddress? { + + var address = self.address(selector: selector, scope: scope, element: element) + + if AudioObjectHasProperty(self.objectID, &address) { + return address + } else { + return nil + } + } + + // getProperty with default value + internal func getProperty(address: AudioObjectPropertyAddress, defaultValue: T) -> T? { + + var value = defaultValue + let status = getPropertyData(address, andValue: &value) + + switch status { + case noErr: + + return value + + default: + + log("Unable to get property with address (\(address)). Status: \(status)") + return nil + } + } + + internal func getProperty(address: AudioObjectPropertyAddress, defaultValue: CFString) -> String? { + + var value = defaultValue + let status = getPropertyData(address, andValue: &value) + + switch status { + case noErr: + + return value as String + + default: + + log("Unable to get property with address (\(address)). Status: \(status)") + return nil + + } + } + + // getProperty UInt32 + internal func getProperty(address: AudioObjectPropertyAddress) -> UInt32? { + + return getProperty(address: address, defaultValue: UInt32(0)) + } + + // getProperty Float32 + internal func getProperty(address: AudioObjectPropertyAddress) -> Float32? { + + return getProperty(address: address, defaultValue: Float32(0.0)) + } + + // getProperty Float64 + internal func getProperty(address: AudioObjectPropertyAddress) -> Float64? { + + return getProperty(address: address, defaultValue: Float64(0.0)) + } + + // getProperty Bool + internal func getProperty(address: AudioObjectPropertyAddress) -> Bool? { + + if let value = getProperty(address: address, defaultValue: UInt32(0)) { + return value != 0 + } else { + return nil + } + } + + // getProperty String + internal func getProperty(address: AudioObjectPropertyAddress) -> String? { + + return getProperty(address: address, defaultValue: "" as CFString) + } + + // setProperty T + internal func setProperty(address: AudioObjectPropertyAddress, value: T) -> Bool { + + let status: OSStatus + + if let unwrappedValue = value as? Bool { + var newValue: UInt32 = unwrappedValue == true ? 1 : 0 + status = setPropertyData(address, andValue: &newValue) + } else if let unwrappedValue = value as? String { + var newValue: CFString = unwrappedValue as CFString + status = setPropertyData(address, andValue: &newValue) + } else { + var newValue = value + status = setPropertyData(address, andValue: &newValue) + } + + switch status { + case noErr: + + return true + + default: + + log("Unable to set property with address (\(address)). Status: \(status)") + return false + + } + } +} + + +extension AudioObject: Hashable { + + /** + The hash value. + */ + public var hashValue: Int { + + return Int(objectID) + } +} + +/// :nodoc: +public func ==(lhs: AudioObject, rhs: AudioObject) -> Bool { + + return lhs.hashValue == rhs.hashValue +} diff --git a/Pods/AMCoreAudio/AMCoreAudio/AudioStream.swift b/Pods/AMCoreAudio/AMCoreAudio/AudioStream.swift new file mode 100644 index 0000000..06932f7 --- /dev/null +++ b/Pods/AMCoreAudio/AMCoreAudio/AudioStream.swift @@ -0,0 +1,614 @@ +// +// AudioStream.swift +// AMCoreAudio +// +// Created by Ruben Nine on 13/04/16. +// Copyright © 2016 9Labs. All rights reserved. +// + +import Foundation + + +/** + Represents an `AudioStream` event. + */ +public enum AudioStreamEvent: Event { + + /** + Called whenever the audio stream `isActive` flag changes state. + */ + case isActiveDidChange(audioStream: AudioStream) + + /** + Called whenever the audio stream physical format changes. + */ + case physicalFormatDidChange(audioStream: AudioStream) +} + +/** + `AudioStream` + + This class represents an audio stream belonging to an audio object. + */ +final public class AudioStream: AudioObject { + + // MARK: - Public Properties + + /** + This audio stream's identifier. + + - Returns: An `AudioObjectID`. + */ + public var id: AudioObjectID { + + get { + + return objectID + } + } + + /** + Returns whether this audio stream is enabled and doing I/O. + + - Returns: `true` when enabled, `false` otherwise. + */ + public lazy var active: Bool = { + + var address = AudioObjectPropertyAddress( + mSelector: kAudioStreamPropertyIsActive, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + if !AudioObjectHasProperty(self.id, &address) { + return false + } + + var active: UInt32 = 0 + let status = self.getPropertyData(address, andValue: &active) + + if noErr != status { + return false + } + + return active == 1 + }() + + /** + Specifies the first element in the owning device that corresponds to the element one of this stream. + + - Returns: *(optional)* A `UInt32`. + */ + public lazy var startingChannel: UInt32? = { + + var address = AudioObjectPropertyAddress( + mSelector: kAudioStreamPropertyStartingChannel, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + if !AudioObjectHasProperty(self.id, &address) { + return nil + } + + var startingChannel: UInt32 = 0 + let status = self.getPropertyData(address, andValue: &startingChannel) + + if noErr != status { + return nil + } + + return startingChannel + }() + + /** + Describes the general kind of functionality attached to this stream. + + - Return: A `TerminalType`. + */ + public lazy var terminalType: TerminalType = { + + var address = AudioObjectPropertyAddress( + mSelector: kAudioStreamPropertyTerminalType, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + if !AudioObjectHasProperty(self.id, &address) { + return .unknown + } + + var terminalType: UInt32 = 0 + let status = self.getPropertyData(address, andValue: &terminalType) + + if noErr != status { + return .unknown + } + + switch terminalType { + case kAudioStreamTerminalTypeLine: + + return .line + + case kAudioStreamTerminalTypeDigitalAudioInterface: + + return .digitalAudioInterface + + case kAudioStreamTerminalTypeSpeaker: + + return .speaker + + case kAudioStreamTerminalTypeHeadphones: + + return .headphones + + case kAudioStreamTerminalTypeLFESpeaker: + + return .lfeSpeaker + + case kAudioStreamTerminalTypeReceiverSpeaker: + + return .receiverSpeaker + + case kAudioStreamTerminalTypeMicrophone: + + return .microphone + + case kAudioStreamTerminalTypeHeadsetMicrophone: + + return .headsetMicrophone + + case kAudioStreamTerminalTypeReceiverMicrophone: + + return .receiverMicrophone + + case kAudioStreamTerminalTypeTTY: + + return .tty + + case kAudioStreamTerminalTypeHDMI: + + return .hdmi + + case kAudioStreamTerminalTypeDisplayPort: + + return .displayPort + + case kAudioStreamTerminalTypeUnknown: + + fallthrough + + default: + + return .unknown + + } + }() + + /** + The audio stream's direction. + + For output streams, and to continue using the same `Direction` concept used by `AudioDevice`, + this will be `Direction.Playback`, likewise, for input streams, `Direction.Recording` will be returned. + + - Returns: *(optional)* A `Direction`. + */ + public lazy var direction: Direction? = { + + var address = AudioObjectPropertyAddress( + mSelector: kAudioStreamPropertyDirection, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMaster + ) + + if !AudioObjectHasProperty(self.id, &address) { + return nil + } + + var direction: UInt32 = 0 + let status = self.getPropertyData(address, andValue: &direction) + + if noErr != status { + return nil + } + + switch direction { + case 0: + + return .playback + + case 1: + + return .recording + + default: + + return nil + + } + }() + + /** + An `AudioStreamBasicDescription` that describes the current data format for this audio stream. + + - SeeAlso: `virtualFormat` + + - Returns: *(optional)* An `AudioStreamBasicDescription`. + */ + public var physicalFormat: AudioStreamBasicDescription? { + + get { + + var asbd = AudioStreamBasicDescription() + + if let status = getStreamPropertyData(kAudioStreamPropertyPhysicalFormat, andValue: &asbd) { + if noErr == status { + return asbd + } + } + + return nil + } + + set { + + var asbd = newValue + + if let status = setStreamPropertyData(kAudioStreamPropertyPhysicalFormat, andValue: &asbd) { + if noErr != status { + log("Error setting physicalFormat to \(String(describing: newValue))") + } + } + } + } + + /** + An `AudioStreamBasicDescription` that describes the current virtual data format for this audio stream. + + - SeeAlso: `physicalFormat` + + - Returns: *(optional)* An `AudioStreamBasicDescription`. + */ + public var virtualFormat: AudioStreamBasicDescription? { + + get { + + var asbd = AudioStreamBasicDescription() + + if let status = getStreamPropertyData(kAudioStreamPropertyVirtualFormat, andValue: &asbd) { + if noErr == status { + return asbd + } + } + + return nil + } + + set { + + var asbd = newValue + + if let status = setStreamPropertyData(kAudioStreamPropertyVirtualFormat, andValue: &asbd) { + if noErr != status { + log("Error setting virtualFormat to \(String(describing: newValue))") + } + } + } + } + + /** + All the available physical formats for this audio stream. + + - SeeAlso: `availableVirtualFormats` + + - Returns: *(optional)* An array of `AudioStreamRangedDescription` structs. + */ + public lazy var availablePhysicalFormats: [AudioStreamRangedDescription]? = { + + guard let direction = self.direction else { return nil } + + var address = AudioObjectPropertyAddress( + mSelector: kAudioStreamPropertyAvailablePhysicalFormats, + mScope: scope(direction: direction), + mElement: kAudioObjectPropertyElementMaster + ) + + if !AudioObjectHasProperty(self.id, &address) { + return nil + } + + var asrd = [AudioStreamRangedDescription]() + let status = self.getPropertyDataArray(address, value: &asrd, andDefaultValue: AudioStreamRangedDescription()) + + if noErr != status { + return nil + } + + return asrd + }() + + /** + All the available virtual formats for this audio stream. + + - SeeAlso: `availablePhysicalFormats` + + - Returns: *(optional)* An array of `AudioStreamRangedDescription` structs. + */ + public lazy var availableVirtualFormats: [AudioStreamRangedDescription]? = { + + guard let direction = self.direction else { return nil } + + var address = AudioObjectPropertyAddress( + mSelector: kAudioStreamPropertyAvailableVirtualFormats, + mScope: scope(direction: direction), + mElement: kAudioObjectPropertyElementMaster + ) + + if !AudioObjectHasProperty(self.id, &address) { + return nil + } + + var asrd = [AudioStreamRangedDescription]() + let status = self.getPropertyDataArray(address, value: &asrd, andDefaultValue: AudioStreamRangedDescription()) + + if noErr != status { + return nil + } + + return asrd + }() + + + // MARK: - Private Properties + + private var isRegisteredForNotifications = false + + private lazy var notificationsQueue: DispatchQueue = { + + return DispatchQueue(label: "io.9labs.AMCoreAudio.notifications", attributes: .concurrent) + }() + + private lazy var propertyListenerBlock: AudioObjectPropertyListenerBlock = { (inNumberAddresses, inAddresses) -> Void in + + let address = inAddresses.pointee + let direction = AMCoreAudio.direction(to: address.mScope) + let notificationCenter = NotificationCenter.defaultCenter + + switch address.mSelector { + case kAudioStreamPropertyIsActive: + + notificationCenter.publish(AudioStreamEvent.isActiveDidChange(audioStream: self)) + + case kAudioStreamPropertyPhysicalFormat: + + notificationCenter.publish(AudioStreamEvent.physicalFormatDidChange(audioStream: self)) + + default: + + break + + } + } + + // MARK: - Public Functions + + /** + Returns an `AudioStream` by providing a valid audio stream identifier. + + - Note: If identifier is not valid, `nil` will be returned. + */ + public static func lookup(by id: AudioObjectID) -> AudioStream? { + + var instance = AudioObjectPool.instancePool.object(forKey: NSNumber(value: UInt(id))) as? AudioStream + + if instance == nil { + instance = AudioStream(id: id) + } + + return instance + } + + /** + Initializes an `AudioStream` by providing a valid `AudioObjectID` referencing an existing audio stream. + */ + private init?(id: AudioObjectID) { + + super.init(objectID: id) + + guard owningObject != nil else { return nil } + + registerForNotifications() + AudioObjectPool.instancePool.setObject(self, forKey: NSNumber(value: UInt(objectID))) + } + + deinit { + + unregisterForNotifications() + AudioObjectPool.instancePool.removeObject(forKey: NSNumber(value: UInt(objectID))) + } + + /** + All the available physical formats for this audio stream matching the current physical format's sample rate. + + - Note: By default, both mixable and non-mixable streams are returned, however, non-mixable + streams can be filtered out by setting `includeNonMixable` to `false`. + + - Parameter includeNonMixable: Whether to include non-mixable streams in the returned array. Defaults to `true`. + + - SeeAlso: `availableVirtualFormatsMatchingCurrentNominalSampleRate(_:)` + + - Returns: *(optional)* An array of `AudioStreamBasicDescription` structs. + */ + public final func availablePhysicalFormatsMatchingCurrentNominalSampleRate(_ includeNonMixable: Bool = true) -> [AudioStreamBasicDescription]? { + + guard let physicalFormats = availablePhysicalFormats, let physicalFormat = physicalFormat else { return nil } + + var filteredFormats = physicalFormats.filter { (format) -> Bool in + format.mSampleRateRange.mMinimum >= physicalFormat.mSampleRate && + format.mSampleRateRange.mMaximum <= physicalFormat.mSampleRate + }.map { $0.mFormat } + + if !includeNonMixable { + filteredFormats = filteredFormats.filter { $0.mFormatFlags & kAudioFormatFlagIsNonMixable == 0 } + } + + return filteredFormats + } + + /** + The audio stream's name as reported by the system. + + - Returns: *(optional)* An audio stream's name. + */ + override public var name: String? { + + return super.name + } + + /** + All the available virtual formats for this audio stream matching the current virtual format's sample rate. + + - Note: By default, both mixable and non-mixable streams are returned, however, non-mixable + streams can be filtered out by setting `includeNonMixable` to `false`. + + - Parameter includeNonMixable: Whether to include non-mixable streams in the returned array. Defaults to `true`. + + - SeeAlso: `availablePhysicalFormatsMatchingCurrentNominalSampleRate(_:)` + + - Returns: *(optional)* An array of `AudioStreamBasicDescription` structs. + */ + public final func availableVirtualFormatsMatchingCurrentNominalSampleRate(_ includeNonMixable: Bool = true) -> [AudioStreamBasicDescription]? { + + guard let virtualFormats = availableVirtualFormats, let virtualFormat = virtualFormat else { return nil } + + var filteredFormats = virtualFormats.filter { (format) -> Bool in + format.mSampleRateRange.mMinimum >= virtualFormat.mSampleRate && + format.mSampleRateRange.mMaximum <= virtualFormat.mSampleRate + }.map { $0.mFormat } + + if !includeNonMixable { + filteredFormats = filteredFormats.filter { $0.mFormatFlags & kAudioFormatFlagIsNonMixable == 0 } + } + + return filteredFormats + } + + + // MARK: - Private Functions + + /** + This is an specialized version of `getPropertyData` that only requires passing an `AudioObjectPropertySelector` + instead of an `AudioObjectPropertyAddress`. The scope is computed from the stream's `Direction`, and the element + is assumed to be `kAudioObjectPropertyElementMaster`. + + Additionally, the property address is validated before calling `getPropertyData`. + + - Parameter selector: The `AudioObjectPropertySelector` that points to the property we want to get. + - Parameter value: The value that will be returned. + + - Returns: An `OSStatus` with `noErr` on success, or an error code other than `noErr` when it fails. + */ + private func getStreamPropertyData(_ selector: AudioObjectPropertySelector, andValue value: inout T) -> OSStatus? { + + guard let direction = direction else { return nil } + + var address = AudioObjectPropertyAddress( + mSelector: selector, + mScope: scope(direction: direction), + mElement: kAudioObjectPropertyElementMaster + ) + + if !AudioObjectHasProperty(id, &address) { + return nil + } + + return getPropertyData(address, andValue: &value) + } + + /** + This is an specialized version of `setPropertyData` that only requires passing an `AudioObjectPropertySelector` + instead of an `AudioObjectPropertyAddress`. The scope is computed from the stream's `Direction`, and the element + is assumed to be `kAudioObjectPropertyElementMaster`. + + Additionally, the property address is validated before calling `setPropertyData`. + + - Parameter selector: The `AudioObjectPropertySelector` that points to the property we want to set. + - Parameter value: The new value we want to set. + + - Returns: An `OSStatus` with `noErr` on success, or an error code other than `noErr` when it fails. + */ + private func setStreamPropertyData(_ selector: AudioObjectPropertySelector, andValue value: inout T) -> OSStatus? { + + guard let direction = direction else { return nil } + + var address = AudioObjectPropertyAddress( + mSelector: selector, + mScope: scope(direction: direction), + mElement: kAudioObjectPropertyElementMaster + ) + + if !AudioObjectHasProperty(id, &address) { + return nil + } + + return setPropertyData(address, andValue: &value) + } + + + // MARK: - Notification Book-keeping + + private func registerForNotifications() { + + if isRegisteredForNotifications { + unregisterForNotifications() + } + + var address = AudioObjectPropertyAddress( + mSelector: kAudioObjectPropertySelectorWildcard, + mScope: kAudioObjectPropertyScopeWildcard, + mElement: kAudioObjectPropertyElementWildcard + ) + + let err = AudioObjectAddPropertyListenerBlock(id, &address, notificationsQueue, propertyListenerBlock) + + if noErr != err { + log("Error on AudioObjectAddPropertyListenerBlock: \(err)") + } + + isRegisteredForNotifications = noErr == err + } + + private func unregisterForNotifications() { + + if isRegisteredForNotifications { + var address = AudioObjectPropertyAddress( + mSelector: kAudioObjectPropertySelectorWildcard, + mScope: kAudioObjectPropertyScopeWildcard, + mElement: kAudioObjectPropertyElementWildcard + ) + + let err = AudioObjectRemovePropertyListenerBlock(id, &address, notificationsQueue, propertyListenerBlock) + + if noErr != err { + log("Error on AudioObjectRemovePropertyListenerBlock: \(err)") + } + + isRegisteredForNotifications = noErr != err + } else { + isRegisteredForNotifications = false + } + } +} + +extension AudioStream: CustomStringConvertible { + + // MARK: - CustomStringConvertible Protocol + + /** + Returns a string describing this audio stream. + */ + public var description: String { + + return "\(name ?? "Stream \(id)") (\(id))" + } +} diff --git a/Pods/AMCoreAudio/AMCoreAudio/Bool+Extensions.swift b/Pods/AMCoreAudio/AMCoreAudio/Bool+Extensions.swift new file mode 100644 index 0000000..354aca5 --- /dev/null +++ b/Pods/AMCoreAudio/AMCoreAudio/Bool+Extensions.swift @@ -0,0 +1,17 @@ +// +// Bool+Boolean.swift +// AMCoreAudio +// +// Created by Ruben on 7/9/15. +// Copyright © 2015 9Labs. All rights reserved. +// + +import Foundation + +extension Bool { + + init(_ integer: T) { + + self.init(integer != 0) + } +} diff --git a/Pods/AMCoreAudio/AMCoreAudio/BundleInfo.swift b/Pods/AMCoreAudio/AMCoreAudio/BundleInfo.swift new file mode 100644 index 0000000..6e94cf4 --- /dev/null +++ b/Pods/AMCoreAudio/AMCoreAudio/BundleInfo.swift @@ -0,0 +1,45 @@ +// +// BundleInfo.swift +// AMCoreAudio +// +// Created by Ruben Nine on 29/04/16. +// Copyright © 2016 9Labs. All rights reserved. +// + +import Foundation + +/** + This class provides information about this bundle such as: + + - build date + - name + - version + - builder number + */ +final public class BundleInfo { + private init() {} + + private static let thisBundle = Bundle(for: BundleInfo.self) + + /// Returns this bundle's build date + public static let buildDate: String? = thisBundle.infoDictionary?["BuildDate"] as? String + + /// Returns this bundle's name + public static let name: String? = thisBundle.infoDictionary?["CFBundleName"] as? String + + /// Returns this bundle's version + public static let version: String? = thisBundle.infoDictionary?["CFBundleShortVersionString"] as? String + + /// Returns this bundle's build number + public static let buildNumber: String? = thisBundle.infoDictionary?["CFBundleVersion"] as? String + + /// Returns this bundle's build information + public static func buildInfo() -> String? { + + guard let buildDate = buildDate, let name = name, let version = version, let buildNumber = buildNumber else { + return nil + } + + return "\(name) \(version) (build \(buildNumber)) built on \(buildDate)." + } +} diff --git a/Pods/AMCoreAudio/AMCoreAudio/NotificationCenter.swift b/Pods/AMCoreAudio/AMCoreAudio/NotificationCenter.swift new file mode 100644 index 0000000..5d2a450 --- /dev/null +++ b/Pods/AMCoreAudio/AMCoreAudio/NotificationCenter.swift @@ -0,0 +1,143 @@ +// +// NotificationCenter.swift +// AMCoreAudio +// +// Created by Ruben Nine on 17/04/16. +// Copyright © 2016 9Labs. All rights reserved. +// + +import Foundation + + +/** + The protocol that any events must implement. + + An event conforming to this protocol may be a class, a struct or an enum. In AMCoreAudio, + we will be relying on enums, since they are very lightweight yet expressive enough (we can + pass arguments to them.) + */ +public protocol Event {} + +/** + The protocol any event subscriber must implement. + + Typically, this will be a class that also happens to conform to the `Hashable` protocol. + */ +public protocol EventSubscriber { + + /** + This is the event handler. + */ + func eventReceiver(_ event: Event) + + /** + The hash value. + - SeeAlso: The `Hashable` protocol. + */ + var hashValue: Int { get } +} + +func ==(lhs: EventSubscriber, rhs: EventSubscriber) -> Bool { + + return lhs.hashValue == rhs.hashValue +} + + +private struct EventSubscriberDescriptor { + + var subscriber: EventSubscriber + var queue: DispatchQueue? +} + + +// MARK: - NotificationCenter + +/** + This is `AMCoreAudio`'s de facto pub-sub system. + */ +final public class NotificationCenter { + + private var subscriberDescriptorsByEvent = [String: [EventSubscriberDescriptor]]() + + private init() {} + + /** + Returns a singleton `NotificationCenter` instance. + */ + public static let defaultCenter = NotificationCenter() + + /** + Allows a subscriber conforming to the `EventSubscriber` protocol to receive events of + the type specified by `eventType`. + + - Parameter subscriber: Any object conforming to the `EventSubscriber` protocol. + - Parameter eventType: A class, struct or enum type conforming to the `Event` protocol. + - Parameter dispatchQueue: (optional) A dispatch queue to use for delivering the events. + */ + public func subscribe(_ subscriber: EventSubscriber, eventType: Event.Type, dispatchQueue: DispatchQueue? = nil) { + + let type = String(describing: eventType) + + if subscriberDescriptorsByEvent[type] == nil { + subscriberDescriptorsByEvent[type] = [] + + if eventType is AudioHardwareEvent.Type { + AudioHardware.sharedInstance.enableDeviceMonitoring() + } + } + + let descriptor = EventSubscriberDescriptor(subscriber: subscriber, queue: dispatchQueue) + + subscriberDescriptorsByEvent[type]!.append(descriptor) + } + + /** + Removes a subscriber from the subscription to events of a specified `eventType`. + + - Parameter subscriber: Any object conforming to the `EventSubscriber` protocol. + - Parameter eventType: A class, struct or enum type conforming to the `Event` protocol. + */ + public func unsubscribe(_ subscriber: EventSubscriber, eventType: Event.Type) { + + let type = String(describing: eventType) + + if var subscribers = subscriberDescriptorsByEvent[type] { + if let idx = subscribers.index(where: { (aSubscriber) -> Bool in aSubscriber.subscriber == subscriber}) { + subscribers.remove(at: idx) + } + + if subscribers.count == 0 { + subscriberDescriptorsByEvent.removeValue(forKey: type) + + if eventType is AudioHardwareEvent.Type { + AudioHardware.sharedInstance.disableDeviceMonitoring() + } + } + } + } + + /** + Publishes an event. The event is delivered to all its subscribers. + + - Parameter event: The event conforming to the `Event` protocol to publish. + */ + func publish(_ event: Event) { + + let type = String(describing: Swift.type(of: event)) + + if let subscriberDescriptors = subscriberDescriptorsByEvent[type] { + for descriptor in subscriberDescriptors { + // If queue is present, we will dispatch the event in that queue, + // otherwise, we will just dispatch the event in whatever happens to be the current + // queue. + if let queue = descriptor.queue { + queue.async(execute: { + descriptor.subscriber.eventReceiver(event) + }) + } else { + descriptor.subscriber.eventReceiver(event) + } + } + } + } +} diff --git a/Pods/AMCoreAudio/AMCoreAudio/Types.swift b/Pods/AMCoreAudio/AMCoreAudio/Types.swift new file mode 100644 index 0000000..9eea822 --- /dev/null +++ b/Pods/AMCoreAudio/AMCoreAudio/Types.swift @@ -0,0 +1,174 @@ +// +// Types.swift +// AMCoreAudio +// +// Created by Ruben on 7/7/15. +// Copyright © 2015 9Labs. All rights reserved. +// + +import Foundation + +/** + Represents a pair of stereo channel numbers. + */ +public typealias StereoPair = (left: UInt32, right: UInt32) + +/** + Indicates the direction used by an `AudioDevice` or `AudioStream`. + */ +public enum Direction: String { + /** + Playback direction + */ + case playback + /** + Recording direction + */ + case recording +} + +/** + Indicates the transport type used by an `AudioDevice`. + */ +public enum TransportType: String { + /** + Unknown Transport Type + */ + case unknown + /** + Built-In Transport Type + */ + case builtIn + /** + Aggregate Transport Type + */ + case aggregate + /** + Virtual Transport Type + */ + case virtual + /** + PCI Transport Type + */ + case pci + /** + USB Transport Type + */ + case usb + /** + FireWire Transport Type + */ + case fireWire + /** + Bluetooth Transport Type + */ + case bluetooth + /** + Bluetooth LE Transport Type + */ + case bluetoothLE + /** + HDMI Transport Type + */ + case hdmi + /** + DisplayPort Transport Type + */ + case displayPort + /** + AirPlay Transport Type + */ + case airPlay + /** + Audio Video Bridging (AVB) Transport Type + */ + case avb + /** + Thunderbolt Transport Type + */ + case thunderbolt +} + +/** + Indicates the terminal type used by an `AudioStream`. + */ +public enum TerminalType: String { + /** + Unknown + */ + case unknown + /** + The ID for a terminal type of a line level stream. + Note that this applies to both input streams and output streams. + */ + case line + /** + A stream from/to a digital audio interface as defined by ISO 60958 (aka SPDIF or AES/EBU). + Note that this applies to both input streams and output streams. + */ + case digitalAudioInterface + /** + Speaker + */ + case speaker + /** + Headphones + */ + case headphones + /** + Speaker for low frequency effects + */ + case lfeSpeaker + /** + A speaker on a telephone handset receiver + */ + case receiverSpeaker + /** + A microphone + */ + case microphone + /** + A microphone attached to an headset + */ + case headsetMicrophone + /** + A microphone on a telephone handset receiver + */ + case receiverMicrophone + /** + A device providing a TTY signl + */ + case tty + /** + A stream from/to an HDMI port + */ + case hdmi + /** + A stream from/to an DisplayPort port + */ + case displayPort +} + +/** + This struct holds volume, mute, and playthru information about a given channel and direction of an `AudioDevice`. + */ +public struct VolumeInfo { + + var volume: Float32? + var hasVolume: Bool + var canSetVolume: Bool + var canMute: Bool + var isMuted: Bool + var canPlayThru: Bool + var isPlayThruSet: Bool + + init() { + + hasVolume = false + canSetVolume = false + canMute = false + isMuted = false + canPlayThru = false + isPlayThruSet = false + } +} diff --git a/Pods/AMCoreAudio/AMCoreAudio/Utils.swift b/Pods/AMCoreAudio/AMCoreAudio/Utils.swift new file mode 100644 index 0000000..78b2755 --- /dev/null +++ b/Pods/AMCoreAudio/AMCoreAudio/Utils.swift @@ -0,0 +1,49 @@ +// +// Utils.swift +// AMCoreAudio +// +// Created by Ruben Nine on 13/04/16. +// Copyright © 2016 9Labs. All rights reserved. +// + +import Foundation + + +private let logDateFormatter: DateFormatter = { + + $0.locale = NSLocale.current + $0.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS" + + return $0 +}(DateFormatter()) + + +internal func log(_ message: String, file: String = #file, line: Int = #line, function: String = #function) { + + let fileName = file.components(separatedBy: "/").last ?? file + + print("\(logDateFormatter.string(from: Date())) [AMCoreAudio] [\(fileName):\(line)] \(function) > \(message)") +} + +internal func scope(direction: Direction) -> AudioObjectPropertyScope { + + return .playback == direction ? kAudioObjectPropertyScopeOutput : kAudioObjectPropertyScopeInput +} + +internal func direction(to scope: AudioObjectPropertyScope) -> Direction? { + + switch scope { + case kAudioObjectPropertyScopeOutput: + + return .playback + + case kAudioObjectPropertyScopeInput: + + return .recording + + default: + + return nil + + } +} diff --git a/Pods/AMCoreAudio/LICENSE.md b/Pods/AMCoreAudio/LICENSE.md new file mode 100644 index 0000000..eaa39ad --- /dev/null +++ b/Pods/AMCoreAudio/LICENSE.md @@ -0,0 +1,7 @@ +Copyright (c) 2014-2018 Ruben Nine + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Pods/AMCoreAudio/README.md b/Pods/AMCoreAudio/README.md new file mode 100644 index 0000000..b930e34 --- /dev/null +++ b/Pods/AMCoreAudio/README.md @@ -0,0 +1,43 @@ +## AMCoreAudio + +[![Version](http://cocoapod-badges.herokuapp.com/v/AMCoreAudio/badge.png)](http://cocoadocs.org/docsets/AMCoreAudio) +[![Platform](http://cocoapod-badges.herokuapp.com/p/AMCoreAudio/badge.png)](http://cocoadocs.org/docsets/AMCoreAudio) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![GitHub tag](https://img.shields.io/github/tag/rnine/AMCoreAudio.svg)](https://github.com/rnine/AMCoreAudio) +[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/rnine/AMCoreAudio/blob/develop/LICENSE.md) + +`AMCoreAudio` is a Swift framework that aims to make [Core Audio](https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/CoreAudioOverview/) use less tedious in macOS. + +Here's a few things it can do: + +- Simplifying audio device enumeration +- Providing accessors for the most relevant audio device properties (i.e., device name, device manufacturer, device UID, volume, mute, sample rate, clock source, etc.) +- Managing (physical and virtual) audio streams associated to an audio device +- Subscribing to audio hardware, audio device, and audio stream events +- etc. + +### Requirements + +* Xcode 8 and Swift 3 +* OS X 10.9 or later + +**Note:** If you are targeting OS X version 10.7 or 10.8 please use the [objc branch](https://github.com/rnine/AMCoreAudio/tree/objc). + +![Alt text](https://github.com/rnine/AMCoreAudio/raw/develop/images/screenshot.png?raw=true "AMCoreAudio Demo (Output tab)") + +### Documentation + +* [AMCoreAudio Documentation](http://rnine.github.io/AMCoreAudio) (powered by [jazzy ♪♫](https://github.com/realm/jazzy) and [GitHub Pages](https://pages.github.com)) + +### Further Development & Patches + +Do you want to contribute to the project? Please fork, patch, and then submit a pull request! + +### Sample Projects + +* `AMCoreAudio Demo` (included in this repository) +* [AudioMate](https://github.com/The9Labs/AudioMate) (a full-featured app recently open-sourced) + +### License + +`AMCoreAudio` was written by Ruben Nine ([@sonicbee9](https://twitter.com/sonicbee9)) in 2013-2014 (open-sourced in March 2014) and is licensed under the [MIT](http://opensource.org/licenses/MIT) license. See [LICENSE.md](LICENSE.md). diff --git a/Pods/Headers/Private/AMCoreAudio/AMCoreAudio.h b/Pods/Headers/Private/AMCoreAudio/AMCoreAudio.h new file mode 120000 index 0000000..73a15cd --- /dev/null +++ b/Pods/Headers/Private/AMCoreAudio/AMCoreAudio.h @@ -0,0 +1 @@ +../../../AMCoreAudio/AMCoreAudio/AMCoreAudio.h \ No newline at end of file diff --git a/Pods/Headers/Public/AMCoreAudio/AMCoreAudio-umbrella.h b/Pods/Headers/Public/AMCoreAudio/AMCoreAudio-umbrella.h new file mode 100644 index 0000000..60e98af --- /dev/null +++ b/Pods/Headers/Public/AMCoreAudio/AMCoreAudio-umbrella.h @@ -0,0 +1,17 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "AMCoreAudio.h" + +FOUNDATION_EXPORT double AMCoreAudioVersionNumber; +FOUNDATION_EXPORT const unsigned char AMCoreAudioVersionString[]; + diff --git a/Pods/Headers/Public/AMCoreAudio/AMCoreAudio.h b/Pods/Headers/Public/AMCoreAudio/AMCoreAudio.h new file mode 120000 index 0000000..73a15cd --- /dev/null +++ b/Pods/Headers/Public/AMCoreAudio/AMCoreAudio.h @@ -0,0 +1 @@ +../../../AMCoreAudio/AMCoreAudio/AMCoreAudio.h \ No newline at end of file diff --git a/Pods/Headers/Public/AMCoreAudio/AMCoreAudio.modulemap b/Pods/Headers/Public/AMCoreAudio/AMCoreAudio.modulemap new file mode 100644 index 0000000..bb6ebda --- /dev/null +++ b/Pods/Headers/Public/AMCoreAudio/AMCoreAudio.modulemap @@ -0,0 +1,6 @@ +module AMCoreAudio { + umbrella header "AMCoreAudio-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index 4cd9831..759ef28 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -1,12 +1,20 @@ PODS: + - AMCoreAudio (3.2.1) - MASShortcut (2.3.6) DEPENDENCIES: + - AMCoreAudio - MASShortcut +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - AMCoreAudio + - MASShortcut + SPEC CHECKSUMS: + AMCoreAudio: 7fa6b718dc93acc29f849d60c3ad680ae1bf07b5 MASShortcut: 9c215e8a8a78f3d01ce56da48e2730ab66b538fa -PODFILE CHECKSUM: 4683a7c2272d973f5c2f219be2eb48cc49488353 +PODFILE CHECKSUM: a66a8437d41c8d97188c3af2ea62b72882bd49de -COCOAPODS: 1.2.0 +COCOAPODS: 1.5.3 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 224fdd9..bd908e2 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -7,357 +7,469 @@ objects = { /* Begin PBXBuildFile section */ - 0E3FE226CE18F169D10196723C37D1D6 /* fr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 038D200C5F73B8EFF0A93DF4E6E1BD90 /* fr.lproj */; }; - 0E9F71B13EB5B5185C1368803180F2BA /* MASShortcut-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F2035E0B6B08D4683931B31919D5194 /* MASShortcut-dummy.m */; }; - 1BFB0520F10AC37A104DF56489C393AD /* cs.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8C406EEFC562A5DDF90E7181CB08331B /* cs.lproj */; }; - 2BEA82707F6B1289F28D8C8097CF4121 /* MASShortcut.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EA5D3E1505005EA05EF0615090F48F8 /* MASShortcut.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2DBA7EDB796E0AF9A189672E9CBA1407 /* zh-Hans.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 262F9C963F67BB43B77AEBFCCACE7C2E /* zh-Hans.lproj */; }; - 33691F55769BFDF534CD2343841B2B48 /* MASShortcutBinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 36695E6AC45B850D887F4F00D8CE1EE9 /* MASShortcutBinder.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 34A3BE024A34E64B83C0CEBB641D987D /* MASShortcutValidator.h in Headers */ = {isa = PBXBuildFile; fileRef = BE890D74FF5505CA2C7D20BDC9D0402A /* MASShortcutValidator.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3C5B1682B90C602799A06D0A5FDC68F9 /* MASLocalization.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EAD18341A993AF2033A3FB2D21AA783 /* MASLocalization.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 3F085DAD796785980C134C9F89C27044 /* MASShortcut.m in Sources */ = {isa = PBXBuildFile; fileRef = BA53FE178C20D7B44CF09D6CE340DB43 /* MASShortcut.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 4416502FCC3847A2A4239B44A9624A47 /* MASShortcutMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 71170E4E2771D185598BE05475B68E69 /* MASShortcutMonitor.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 45333808B39FACCB4128E10F4B44432B /* Shortcut.h in Headers */ = {isa = PBXBuildFile; fileRef = 7431A6D435BC007D466649E2A7BAC1A9 /* Shortcut.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 56B0E92AC0CDAB0AD106E4A16CAA4B1C /* MASShortcutBinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 9775F916524923D2392B56450009DFB7 /* MASShortcutBinder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5C5FEAFEBC103CA46099D2D65EBC47A1 /* MASDictionaryTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ED853B9DF49E5C90CCA069BB3F2B43B /* MASDictionaryTransformer.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 6229CC2D8700E52B2C67C085FF9563D5 /* ko.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 66963E9C1F04B976EC0D1830456B912C /* ko.lproj */; }; - 67250F0458194534752D26E44041F059 /* ru.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 605EBDBCA1616C656042B471811F6C71 /* ru.lproj */; }; - 6DFD61F5CE0AFF2AD3918A9719D46F63 /* MASShortcutMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = FC87DC0EA27BB8249F80FAE5FC10020C /* MASShortcutMonitor.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6F22DF5181A0505E68AB893585556551 /* MASKeyMasks.h in Headers */ = {isa = PBXBuildFile; fileRef = 819F2EB6B7FFAB4121876D2654ACD028 /* MASKeyMasks.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 720804F34108B4D8CA6ED208E23391E0 /* MASDictionaryTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2414CC14D6996F009EBA016B98439675 /* MASDictionaryTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7A95B39667A492A060986B0795B85122 /* MASShortcutView.h in Headers */ = {isa = PBXBuildFile; fileRef = 20E469613DEEF5698CC2E0658385B3A7 /* MASShortcutView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 86288836A35118CD387C7B8383A1F9F1 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12CB16911106539CF98B4AF79FAA2938 /* Cocoa.framework */; }; - 87E1E943697B97013BB895607DAC60F4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12CB16911106539CF98B4AF79FAA2938 /* Cocoa.framework */; }; - 88087104DB90EC679F1E367163351FFD /* ja.lproj in Resources */ = {isa = PBXBuildFile; fileRef = FD95351169AD17DCD8AE7D859C1D6BC1 /* ja.lproj */; }; - 902EEE23E9D3AA8467EF3A50431EF2BE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2E8B3BCAE3930DB03E31F39C1A09E705 /* Carbon.framework */; }; - 959B73A9B0B7E25899F6A37ECB3302C5 /* Pods-Mute Me-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E4CB1032B70EC4DE02D87B368D77636 /* Pods-Mute Me-dummy.m */; }; - 96C33D954D43210E97B3DF6444AB94E5 /* MASShortcutValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = CA5C2484673E6954903EEDF333085965 /* MASShortcutValidator.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - A358B1CC04588D145AA9D67E26A66AEA /* zh-Hant.lproj in Resources */ = {isa = PBXBuildFile; fileRef = A9C4628298B582F17383E31ED11A5F08 /* zh-Hant.lproj */; }; - A5D5DCDE376956279D5B36EA42A24D7D /* MASHotKey.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6E28893186CA3688715CA60BFC32E0 /* MASHotKey.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BCF8876FA78B037CCD4B6BC9246DC6FD /* MASHotKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 55A11AB5D416530A484DAD1F97D9E010 /* MASHotKey.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - BE1F5449678438070473EA08C4951547 /* MASShortcutView+Bindings.m in Sources */ = {isa = PBXBuildFile; fileRef = FD619B73B50911A58B096529F52A50A7 /* MASShortcutView+Bindings.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - C322A7288AAD972168AE2C0B75CD059B /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A5E586EAF4C098BB13472B84B96B96F /* AppKit.framework */; }; - CA74C6C7D02F9C3FFAA2E3600617F0EF /* MASKeyCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A7023C612FF3F139AE89D62A61C7A13 /* MASKeyCodes.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CC55627A7F9AC4EFF8FFE3AE9A73CBEC /* MASLocalization.h in Headers */ = {isa = PBXBuildFile; fileRef = 6247799F171A0B65576998B4116F1F4E /* MASLocalization.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D12DF721C2FBA157157279D77B865C1E /* nl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = B4F45EF1CC04352F093E8BF2B47F48B1 /* nl.lproj */; }; - D6B7130455C1FC500FCFBB4C7B52F8DF /* en.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 2404E18B631A74AD670CE1609A7080BF /* en.lproj */; }; - D7790A18B5A9A073E65E6C35CC4E93C4 /* de.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 19DD9FCBCB8B9347A5BE1D983DEE6192 /* de.lproj */; }; - E450732C1FBD59C7E1C614CC5B0AA249 /* MASShortcutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B3E9B40B057B9FEE6019C779F14C5A8 /* MASShortcutView.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - F0E73BA1E7A419B07EDEDB7670600937 /* MASShortcutView+Bindings.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AD57029FEF1D175476848C76ACD611D /* MASShortcutView+Bindings.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F0FBB86094DE6FFD72E0FA11946335D7 /* it.lproj in Resources */ = {isa = PBXBuildFile; fileRef = BC5C51BB4780191957F415BC673514BE /* it.lproj */; }; - F111E58A8F199C64FAA24329DE9DC5C8 /* pl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = EFDE7A909E6986B29687C1E0DEFF2C69 /* pl.lproj */; }; - FEFD6109965996832710EC2D2FE74A26 /* es.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 857F9CF0E370084DD45F7EE72F210D08 /* es.lproj */; }; + 032114835220926E1FAA6B332C20F474 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4C463285A5925FB898105EC16FCB462 /* Carbon.framework */; }; + 0E7B078C378488D0FE927FAA1A5C96D0 /* MASShortcut-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F6374DC3D73D05DC6DDF696B0874073 /* MASShortcut-dummy.m */; }; + 11779DBA685BB660420494534B69AE9C /* BundleInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D90066DB370CE7374341AA1AFC7437 /* BundleInfo.swift */; }; + 147CCDE5AD17EEAEB7307135649A1CDA /* ko.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8CE1222E5403FDBA0FF874D786E3C334 /* ko.lproj */; }; + 175B873D32A93054ED16A9EA28DF554E /* zh-Hant.lproj in Resources */ = {isa = PBXBuildFile; fileRef = EC7E83519E23A52CAFACE3CFA8ABBC2D /* zh-Hant.lproj */; }; + 1BFE6C690E87497478B413DA698581FE /* MASDictionaryTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DD3DCA07EE6BBEB510E28B78164795C /* MASDictionaryTransformer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1C49168C4CA9F8F28855E705CEAAF3BE /* Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = 808932CA81FC8F274816065B66B90F65 /* Types.swift */; }; + 1C84CDAD529437F703DB82AFEAA5E4B6 /* cs.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8A2C3441A87129B30CE1D55EB0FCF88D /* cs.lproj */; }; + 1CCDA82A9A7612E541FF8AC05CE0618C /* AMCoreAudio-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = E0CDCAC090952E3A35832B935916ECDD /* AMCoreAudio-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1D752D5EB52D85DA8E81118D6F0F563D /* AMCoreAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = BFC1A40C3AEEF2B0A906A2D9AF3CBDCF /* AMCoreAudio.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2490A627FB16436157C4D688D93B583F /* es.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 2A33F9E4DBC6B092FFBED9AD66583B93 /* es.lproj */; }; + 2C3B819108C015056E37E70B8F5F5F97 /* MASShortcut.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D7CF235F8CB3695AEA8FC1C2CDC23A8 /* MASShortcut.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2D21A45126693BB628C5E9218D29BBF7 /* zh-Hans.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 11F84CECBBD83213FAB9437CC53005DA /* zh-Hans.lproj */; }; + 2D676047C6F308F0D8284D6607018D39 /* MASShortcutView.h in Headers */ = {isa = PBXBuildFile; fileRef = 8800159F77D90A6B11F9E6DB2B1D10C9 /* MASShortcutView.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3DDE5D8E6BA5807A73AA2DAF0A6380AD /* AudioObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34C89D595D7C6327CB99F166987ABB3D /* AudioObject.swift */; }; + 4AE0C21E0BAA974F2C60A080ED8C2C60 /* AMCoreAudio-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8FB88DFDF9A34BCF6BBD18958D3FB /* AMCoreAudio-dummy.m */; }; + 4CBD52728FBB8422C646B006C863DFBC /* Bool+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 795F93B81931EFDFBEB38B35E3B439A2 /* Bool+Extensions.swift */; }; + 4CF6A428699BBCD512BCB75DDD04253C /* pl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 71F1ACA1E273718B63DB243453762045 /* pl.lproj */; }; + 5072F8909F7D9030E51C99863E0DCA5F /* Pods-Mute Me-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3138415EE4C39E4D8D18803DC62AF15D /* Pods-Mute Me-dummy.m */; }; + 576F91878CBEE7B98FFE2DBF14513287 /* NotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9728E6AECF701D9714A158FBE4E4FBCB /* NotificationCenter.swift */; }; + 5949E58680693F245B6618769F48E027 /* MASDictionaryTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = ED566130640BE986EDE9AECEDFA19ED3 /* MASDictionaryTransformer.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 5991CFA46E6B481A7D16A8FCE2C8AAB3 /* MASShortcutView+Bindings.m in Sources */ = {isa = PBXBuildFile; fileRef = 5598DDAC241575E32DD53C69F65BCED0 /* MASShortcutView+Bindings.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 5DB9D8AB23B4B44A2D310195FE6DD9C8 /* MASLocalization.m in Sources */ = {isa = PBXBuildFile; fileRef = 61EA23293B8D52869CE0C2B73D305DD6 /* MASLocalization.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 60FEA26188D044E89F8677FF2145602B /* MASShortcutValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CF1BCD39C024EBD38C4E46D3D5C45CD /* MASShortcutValidator.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 68743B36BC7BA3D8353809CFB18E3AAF /* MASShortcutBinder.m in Sources */ = {isa = PBXBuildFile; fileRef = CBD746AFD858C4E4600305FC69BC4A43 /* MASShortcutBinder.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + 70505A7976C90DA277BCF05983D4C3D0 /* AudioHardware.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29DB9EACC28E55F42B7F7497E56930E /* AudioHardware.swift */; }; + 796502BE643C8A0FAF717D67A10A022F /* MASShortcutView+Bindings.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F63DB772886EF01076D831D08536154 /* MASShortcutView+Bindings.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 923B336EBB1CB2B1133BC0C99EA63782 /* nl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = E053F4D7E5A0171F99A441F2A495E70F /* nl.lproj */; }; + 98814E7E8FEEEF74ED4649F9784E04F0 /* ja.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8F1DC0F50F5A8F203662D33E3A752F98 /* ja.lproj */; }; + 9EB36945B3F024B1AB74EBE26568F349 /* MASHotKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ACBA716BF0D15B78C9F91A90F7DCDD3 /* MASHotKey.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A08D6BAA2DB79A661C32701D100ECC42 /* MASShortcutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 672E38A4C198C098BA76D00DCF2C525D /* MASShortcutView.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + A18A16B46F8E24827037BC1351CB1902 /* MASShortcutBinder.h in Headers */ = {isa = PBXBuildFile; fileRef = DBB80BE4D14C42B10C7E6DD69A3D08DE /* MASShortcutBinder.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A23370E6F15B4D760D58F352944C3980 /* de.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 6A085AC897F480938FD8205E790E5362 /* de.lproj */; }; + A51BA2AC7C6DCC3FBB4DCCC0E0A9C85D /* ru.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 7C797DD5F54C68F7AD07C6902E910D04 /* ru.lproj */; }; + A54431EC24BD97D6F53C3D5C663D5535 /* MASLocalization.h in Headers */ = {isa = PBXBuildFile; fileRef = C7330DB3FC46777FEFD2C7EEB68073A8 /* MASLocalization.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A9BE08C9AD3438D768172849F8906280 /* en.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8E37AFC5D939ABD376E54DF6FDBEBF6D /* en.lproj */; }; + ACFD347C8623905355E68B1BFF70D5C3 /* MASShortcut.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CE6173A1C8468D123FC535E451CBD03 /* MASShortcut.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + B012CA369CF29D6A7C9ADC7FAB089BFA /* AudioDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C24D7458B53FC8C0E0AC5F35F93DCD8 /* AudioDevice.swift */; }; + B28578A4640B4DEF4630973C9241A60D /* Shortcut.h in Headers */ = {isa = PBXBuildFile; fileRef = C343B557884B84D2882E164F9DB07510 /* Shortcut.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BFE2D11FD048C0C802913C3EACA335BF /* fr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = AE6AE58205DC91D08D3628029D578BD1 /* fr.lproj */; }; + C146D10CABABA35034A0A071B3762FB4 /* MASShortcutMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 57B8F916B49E58D68B23EBD1B84CEACD /* MASShortcutMonitor.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C2B7C61C31EBBAC3DD5AD0BCF6F08FEE /* AudioStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5FD7A1CAC5F980162BB80AF3BA94FD1 /* AudioStream.swift */; }; + D12A1378E0CE7DFEB6DF6C415233C124 /* MASShortcutValidator.h in Headers */ = {isa = PBXBuildFile; fileRef = 205B5B4550A3C02781B4A85C62DB6BB0 /* MASShortcutValidator.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D32E5B0A81CBB4E15BDD7ED6702454A7 /* MASKeyMasks.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E68CC19D1A4D6596255D409C2B6C267 /* MASKeyMasks.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DB9C9F72BFAEF42212533B457687EF91 /* it.lproj in Resources */ = {isa = PBXBuildFile; fileRef = FF318380E895C518B7B8052F375AD842 /* it.lproj */; }; + E0474C69B6C6A2948B9C1CC1700FE887 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F87DCFDA2B9446DEFB997E726115125 /* Utils.swift */; }; + E6D988DDCE07F9F298F552404DA897DF /* Pods-Mute Me-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 91C31DF27E277122DD1523A744A7A165 /* Pods-Mute Me-umbrella.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F3A152D35D07959868FBF3D2E29EAEE1 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 089CBA884EB516614A8C77B86196F0A2 /* AppKit.framework */; }; + F4BC1C6AE1DA18857CCE4CE5017EB06B /* MASShortcutMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = D51F19AB07CE6C018FABF6A86AB240CC /* MASShortcutMonitor.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + F58931A610D4EE4CE5BA282CE50CDBAE /* MASHotKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C97E6CABF48BDC6DC927F5984D59C6A /* MASHotKey.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; + F62C2E44D07A79CCDAD8A813684B2B7E /* MASKeyCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = AA28AFF1B24A13B063349AC1800C6BBE /* MASKeyCodes.h */; settings = {ATTRIBUTES = (Project, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 864BADC041E6C26B87C3BEBC266C0532 /* PBXContainerItemProxy */ = { + 0C3A21DFDB41A3CB6E4AD1C5DDC20F55 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 2E029AB0CA275443A2AF3531E33683AB; - remoteInfo = MASShortcut; + remoteGlobalIDString = 51129A24EE72AC4637629D9606318911; + remoteInfo = "MASShortcut-MASShortcut"; }; - AB589568138B5952333D183DCA39836A /* PBXContainerItemProxy */ = { + 38506A9005375B291F3480229AD70EC7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 21E49887F9334B84548BFF0BA2C69086; - remoteInfo = "MASShortcut-MASShortcut"; + remoteGlobalIDString = F2DF73D98ECF3AA885B70529062E51F2; + remoteInfo = AMCoreAudio; + }; + 9F916A9B1DDCD9C6C3315E1399EE7D5D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 31DA45D85CE3DAB6BBD38E00F0A444BA; + remoteInfo = MASShortcut; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 038D200C5F73B8EFF0A93DF4E6E1BD90 /* fr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = fr.lproj; sourceTree = ""; }; - 0A5E586EAF4C098BB13472B84B96B96F /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = DEVELOPER_DIR; }; - 12CB16911106539CF98B4AF79FAA2938 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; - 19DD9FCBCB8B9347A5BE1D983DEE6192 /* de.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = de.lproj; sourceTree = ""; }; - 20E469613DEEF5698CC2E0658385B3A7 /* MASShortcutView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutView.h; path = Framework/MASShortcutView.h; sourceTree = ""; }; - 2404E18B631A74AD670CE1609A7080BF /* en.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = en.lproj; sourceTree = ""; }; - 2414CC14D6996F009EBA016B98439675 /* MASDictionaryTransformer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASDictionaryTransformer.h; path = Framework/MASDictionaryTransformer.h; sourceTree = ""; }; - 262F9C963F67BB43B77AEBFCCACE7C2E /* zh-Hans.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = "zh-Hans.lproj"; sourceTree = ""; }; - 2E8B3BCAE3930DB03E31F39C1A09E705 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = DEVELOPER_DIR; }; - 2EAD18341A993AF2033A3FB2D21AA783 /* MASLocalization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASLocalization.m; path = Framework/MASLocalization.m; sourceTree = ""; }; - 30E9081214B252FA88E26761619D5384 /* Pods-Mute Me-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Mute Me-acknowledgements.plist"; sourceTree = ""; }; - 34E349B65FF57F7507C7E886525FCD29 /* Pods-Mute Me-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Mute Me-frameworks.sh"; sourceTree = ""; }; - 36695E6AC45B850D887F4F00D8CE1EE9 /* MASShortcutBinder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutBinder.m; path = Framework/MASShortcutBinder.m; sourceTree = ""; }; - 3ADD1D498AC44A5D7BD80C8B9F21D30B /* Pods-Mute Me-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Mute Me-acknowledgements.markdown"; sourceTree = ""; }; - 4ABF22BA082314E781B0AA36E9E238C4 /* MASShortcut.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MASShortcut.xcconfig; sourceTree = ""; }; - 4EA5D3E1505005EA05EF0615090F48F8 /* MASShortcut.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcut.h; path = Framework/MASShortcut.h; sourceTree = ""; }; - 55A11AB5D416530A484DAD1F97D9E010 /* MASHotKey.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASHotKey.m; path = Framework/MASHotKey.m; sourceTree = ""; }; - 5BAF377C4E8EF2A53E3ACA62B79CD7E7 /* ResourceBundle-MASShortcut-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-MASShortcut-Info.plist"; sourceTree = ""; }; - 605EBDBCA1616C656042B471811F6C71 /* ru.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ru.lproj; sourceTree = ""; }; - 6247799F171A0B65576998B4116F1F4E /* MASLocalization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASLocalization.h; path = Framework/MASLocalization.h; sourceTree = ""; }; - 66963E9C1F04B976EC0D1830456B912C /* ko.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ko.lproj; sourceTree = ""; }; - 71170E4E2771D185598BE05475B68E69 /* MASShortcutMonitor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutMonitor.m; path = Framework/MASShortcutMonitor.m; sourceTree = ""; }; - 7431A6D435BC007D466649E2A7BAC1A9 /* Shortcut.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Shortcut.h; path = Framework/Shortcut.h; sourceTree = ""; }; - 7F7B48185DC0E504A7EAF6C3CAC1FBFB /* Pods-Mute Me.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Mute Me.release.xcconfig"; sourceTree = ""; }; - 819F2EB6B7FFAB4121876D2654ACD028 /* MASKeyMasks.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASKeyMasks.h; path = Framework/MASKeyMasks.h; sourceTree = ""; }; - 857F9CF0E370084DD45F7EE72F210D08 /* es.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = es.lproj; sourceTree = ""; }; - 8A7023C612FF3F139AE89D62A61C7A13 /* MASKeyCodes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASKeyCodes.h; path = Framework/MASKeyCodes.h; sourceTree = ""; }; - 8AD57029FEF1D175476848C76ACD611D /* MASShortcutView+Bindings.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "MASShortcutView+Bindings.h"; path = "Framework/MASShortcutView+Bindings.h"; sourceTree = ""; }; - 8C406EEFC562A5DDF90E7181CB08331B /* cs.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = cs.lproj; sourceTree = ""; }; - 8E4CB1032B70EC4DE02D87B368D77636 /* Pods-Mute Me-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Mute Me-dummy.m"; sourceTree = ""; }; - 8ED853B9DF49E5C90CCA069BB3F2B43B /* MASDictionaryTransformer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASDictionaryTransformer.m; path = Framework/MASDictionaryTransformer.m; sourceTree = ""; }; + 020C0DA4FA888537D881BA658A516317 /* MASShortcut-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MASShortcut-prefix.pch"; sourceTree = ""; }; + 089CBA884EB516614A8C77B86196F0A2 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = DEVELOPER_DIR; }; + 09ACDB21F879D80D2F628185562E7A4A /* AMCoreAudio.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = AMCoreAudio.xcconfig; sourceTree = ""; }; + 0D96CB7C478CD981286C75F892355A12 /* MASShortcut.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MASShortcut.xcconfig; sourceTree = ""; }; + 0FB17B12CA8811D0A23D3E900BA24288 /* Pods-Mute Me.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Mute Me.release.xcconfig"; sourceTree = ""; }; + 0FC8FB88DFDF9A34BCF6BBD18958D3FB /* AMCoreAudio-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "AMCoreAudio-dummy.m"; sourceTree = ""; }; + 11F84CECBBD83213FAB9437CC53005DA /* zh-Hans.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = "zh-Hans.lproj"; sourceTree = ""; }; + 14F3CA06AA7BC4907F6A1A4177CEC11D /* libPods-Mute Me.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-Mute Me.a"; path = "libPods-Mute Me.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DD3DCA07EE6BBEB510E28B78164795C /* MASDictionaryTransformer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASDictionaryTransformer.h; path = Framework/MASDictionaryTransformer.h; sourceTree = ""; }; + 1F63DB772886EF01076D831D08536154 /* MASShortcutView+Bindings.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "MASShortcutView+Bindings.h"; path = "Framework/MASShortcutView+Bindings.h"; sourceTree = ""; }; + 205B5B4550A3C02781B4A85C62DB6BB0 /* MASShortcutValidator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutValidator.h; path = Framework/MASShortcutValidator.h; sourceTree = ""; }; + 2A33F9E4DBC6B092FFBED9AD66583B93 /* es.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = es.lproj; sourceTree = ""; }; + 2CE6173A1C8468D123FC535E451CBD03 /* MASShortcut.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcut.m; path = Framework/MASShortcut.m; sourceTree = ""; }; + 2E126F54F7E79480B1976648D32C8D66 /* libAMCoreAudio.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libAMCoreAudio.a; path = libAMCoreAudio.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 3138415EE4C39E4D8D18803DC62AF15D /* Pods-Mute Me-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Mute Me-dummy.m"; sourceTree = ""; }; + 34C89D595D7C6327CB99F166987ABB3D /* AudioObject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AudioObject.swift; path = AMCoreAudio/AudioObject.swift; sourceTree = ""; }; + 4484AF6BAC1CAFF87FE9AE927E507BDC /* Pods-Mute Me-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Mute Me-acknowledgements.markdown"; sourceTree = ""; }; + 4908D3B99EFE914B3ECEC78FE635CD9C /* AMCoreAudio.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; name = AMCoreAudio.modulemap; path = ../../Headers/Public/AMCoreAudio/AMCoreAudio.modulemap; sourceTree = ""; }; + 4C97E6CABF48BDC6DC927F5984D59C6A /* MASHotKey.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASHotKey.m; path = Framework/MASHotKey.m; sourceTree = ""; }; + 4F6374DC3D73D05DC6DDF696B0874073 /* MASShortcut-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MASShortcut-dummy.m"; sourceTree = ""; }; + 4F87DCFDA2B9446DEFB997E726115125 /* Utils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Utils.swift; path = AMCoreAudio/Utils.swift; sourceTree = ""; }; + 5598DDAC241575E32DD53C69F65BCED0 /* MASShortcutView+Bindings.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "MASShortcutView+Bindings.m"; path = "Framework/MASShortcutView+Bindings.m"; sourceTree = ""; }; + 57B8F916B49E58D68B23EBD1B84CEACD /* MASShortcutMonitor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutMonitor.h; path = Framework/MASShortcutMonitor.h; sourceTree = ""; }; + 61EA23293B8D52869CE0C2B73D305DD6 /* MASLocalization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASLocalization.m; path = Framework/MASLocalization.m; sourceTree = ""; }; + 672E38A4C198C098BA76D00DCF2C525D /* MASShortcutView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutView.m; path = Framework/MASShortcutView.m; sourceTree = ""; }; + 68C6B64AF2EA5E434C96A9A30426465B /* AMCoreAudio-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "AMCoreAudio-prefix.pch"; sourceTree = ""; }; + 6A085AC897F480938FD8205E790E5362 /* de.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = de.lproj; sourceTree = ""; }; + 6E68CC19D1A4D6596255D409C2B6C267 /* MASKeyMasks.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASKeyMasks.h; path = Framework/MASKeyMasks.h; sourceTree = ""; }; + 71F1ACA1E273718B63DB243453762045 /* pl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = pl.lproj; sourceTree = ""; }; + 795F93B81931EFDFBEB38B35E3B439A2 /* Bool+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Bool+Extensions.swift"; path = "AMCoreAudio/Bool+Extensions.swift"; sourceTree = ""; }; + 7ACBA716BF0D15B78C9F91A90F7DCDD3 /* MASHotKey.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASHotKey.h; path = Framework/MASHotKey.h; sourceTree = ""; }; + 7C797DD5F54C68F7AD07C6902E910D04 /* ru.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ru.lproj; sourceTree = ""; }; + 7EF0A9BFDE8644C1FC9E8B49B30D176E /* Pods-Mute Me.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Mute Me.debug.xcconfig"; sourceTree = ""; }; + 808932CA81FC8F274816065B66B90F65 /* Types.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Types.swift; path = AMCoreAudio/Types.swift; sourceTree = ""; }; + 8800159F77D90A6B11F9E6DB2B1D10C9 /* MASShortcutView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutView.h; path = Framework/MASShortcutView.h; sourceTree = ""; }; + 8A2C3441A87129B30CE1D55EB0FCF88D /* cs.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = cs.lproj; sourceTree = ""; }; + 8CE1222E5403FDBA0FF874D786E3C334 /* ko.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ko.lproj; sourceTree = ""; }; + 8CF1BCD39C024EBD38C4E46D3D5C45CD /* MASShortcutValidator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutValidator.m; path = Framework/MASShortcutValidator.m; sourceTree = ""; }; + 8D7CF235F8CB3695AEA8FC1C2CDC23A8 /* MASShortcut.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcut.h; path = Framework/MASShortcut.h; sourceTree = ""; }; + 8E37AFC5D939ABD376E54DF6FDBEBF6D /* en.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = en.lproj; sourceTree = ""; }; + 8F1DC0F50F5A8F203662D33E3A752F98 /* ja.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ja.lproj; sourceTree = ""; }; + 91C31DF27E277122DD1523A744A7A165 /* Pods-Mute Me-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Mute Me-umbrella.h"; sourceTree = ""; }; 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 9775F916524923D2392B56450009DFB7 /* MASShortcutBinder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutBinder.h; path = Framework/MASShortcutBinder.h; sourceTree = ""; }; - 9B3E9B40B057B9FEE6019C779F14C5A8 /* MASShortcutView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutView.m; path = Framework/MASShortcutView.m; sourceTree = ""; }; - 9F2035E0B6B08D4683931B31919D5194 /* MASShortcut-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MASShortcut-dummy.m"; sourceTree = ""; }; - A212E1D2BC7A106F0B6463091F90FEB8 /* libPods-Mute Me.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-Mute Me.a"; path = "libPods-Mute Me.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - A8FCD63C6E322922A731DB941C851A4F /* MASShortcut.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = MASShortcut.bundle; path = MASShortcut.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; - A9C4628298B582F17383E31ED11A5F08 /* zh-Hant.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = "zh-Hant.lproj"; sourceTree = ""; }; - B4F45EF1CC04352F093E8BF2B47F48B1 /* nl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = nl.lproj; sourceTree = ""; }; - BA53FE178C20D7B44CF09D6CE340DB43 /* MASShortcut.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcut.m; path = Framework/MASShortcut.m; sourceTree = ""; }; - BC5C51BB4780191957F415BC673514BE /* it.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = it.lproj; sourceTree = ""; }; - BC6E28893186CA3688715CA60BFC32E0 /* MASHotKey.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASHotKey.h; path = Framework/MASHotKey.h; sourceTree = ""; }; - BE890D74FF5505CA2C7D20BDC9D0402A /* MASShortcutValidator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutValidator.h; path = Framework/MASShortcutValidator.h; sourceTree = ""; }; - C59C0A36CF0FF5402DE8930148D3C39D /* Pods-Mute Me-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Mute Me-resources.sh"; sourceTree = ""; }; - C9A948480CC4094D7FD4DB1934F308DF /* MASShortcut-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MASShortcut-prefix.pch"; sourceTree = ""; }; - CA5C2484673E6954903EEDF333085965 /* MASShortcutValidator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutValidator.m; path = Framework/MASShortcutValidator.m; sourceTree = ""; }; - D9BE4BA371D4340E716B396548885BFB /* Pods-Mute Me.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Mute Me.debug.xcconfig"; sourceTree = ""; }; - EF3789198921958045681A19D290466B /* libMASShortcut.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libMASShortcut.a; path = libMASShortcut.a; sourceTree = BUILT_PRODUCTS_DIR; }; - EFDE7A909E6986B29687C1E0DEFF2C69 /* pl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = pl.lproj; sourceTree = ""; }; - FC87DC0EA27BB8249F80FAE5FC10020C /* MASShortcutMonitor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutMonitor.h; path = Framework/MASShortcutMonitor.h; sourceTree = ""; }; - FD619B73B50911A58B096529F52A50A7 /* MASShortcutView+Bindings.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "MASShortcutView+Bindings.m"; path = "Framework/MASShortcutView+Bindings.m"; sourceTree = ""; }; - FD95351169AD17DCD8AE7D859C1D6BC1 /* ja.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = ja.lproj; sourceTree = ""; }; + 9728E6AECF701D9714A158FBE4E4FBCB /* NotificationCenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NotificationCenter.swift; path = AMCoreAudio/NotificationCenter.swift; sourceTree = ""; }; + 9C24D7458B53FC8C0E0AC5F35F93DCD8 /* AudioDevice.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AudioDevice.swift; path = AMCoreAudio/AudioDevice.swift; sourceTree = ""; }; + A4F05A0D12CA9ADB324902B31CD47933 /* Pods-Mute Me-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Mute Me-acknowledgements.plist"; sourceTree = ""; }; + AA28AFF1B24A13B063349AC1800C6BBE /* MASKeyCodes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASKeyCodes.h; path = Framework/MASKeyCodes.h; sourceTree = ""; }; + AE6AE58205DC91D08D3628029D578BD1 /* fr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = fr.lproj; sourceTree = ""; }; + B822D22D1BB8539F8DBBF2BA53655683 /* MASShortcut.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = MASShortcut.bundle; path = "MASShortcut-MASShortcut.bundle"; sourceTree = BUILT_PRODUCTS_DIR; }; + BFC1A40C3AEEF2B0A906A2D9AF3CBDCF /* AMCoreAudio.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AMCoreAudio.h; path = AMCoreAudio/AMCoreAudio.h; sourceTree = ""; }; + C2FE061CA93A2BDB59B73987EB219397 /* ResourceBundle-MASShortcut-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-MASShortcut-Info.plist"; sourceTree = ""; }; + C343B557884B84D2882E164F9DB07510 /* Shortcut.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Shortcut.h; path = Framework/Shortcut.h; sourceTree = ""; }; + C4D90066DB370CE7374341AA1AFC7437 /* BundleInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BundleInfo.swift; path = AMCoreAudio/BundleInfo.swift; sourceTree = ""; }; + C7330DB3FC46777FEFD2C7EEB68073A8 /* MASLocalization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASLocalization.h; path = Framework/MASLocalization.h; sourceTree = ""; }; + CB6080E06103C655397D0E8D218C77D0 /* Pods-Mute Me-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Mute Me-resources.sh"; sourceTree = ""; }; + CBD746AFD858C4E4600305FC69BC4A43 /* MASShortcutBinder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutBinder.m; path = Framework/MASShortcutBinder.m; sourceTree = ""; }; + CD72F76D34D1B6EC12D2BFC70FE1F42C /* libMASShortcut.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libMASShortcut.a; path = libMASShortcut.a; sourceTree = BUILT_PRODUCTS_DIR; }; + D29DB9EACC28E55F42B7F7497E56930E /* AudioHardware.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AudioHardware.swift; path = AMCoreAudio/AudioHardware.swift; sourceTree = ""; }; + D51F19AB07CE6C018FABF6A86AB240CC /* MASShortcutMonitor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutMonitor.m; path = Framework/MASShortcutMonitor.m; sourceTree = ""; }; + D6BF686FED3D7AC758EACBA7D84FE58E /* Pods-Mute Me-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Mute Me-frameworks.sh"; sourceTree = ""; }; + DBB80BE4D14C42B10C7E6DD69A3D08DE /* MASShortcutBinder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutBinder.h; path = Framework/MASShortcutBinder.h; sourceTree = ""; }; + E053F4D7E5A0171F99A441F2A495E70F /* nl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = nl.lproj; sourceTree = ""; }; + E0CDCAC090952E3A35832B935916ECDD /* AMCoreAudio-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "AMCoreAudio-umbrella.h"; path = "../../Headers/Public/AMCoreAudio/AMCoreAudio-umbrella.h"; sourceTree = ""; }; + E4C463285A5925FB898105EC16FCB462 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = DEVELOPER_DIR; }; + E8E18812312F7AA632C59DF80A2A39E8 /* Pods-Mute Me.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Mute Me.modulemap"; sourceTree = ""; }; + EC7E83519E23A52CAFACE3CFA8ABBC2D /* zh-Hant.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = "zh-Hant.lproj"; sourceTree = ""; }; + ED566130640BE986EDE9AECEDFA19ED3 /* MASDictionaryTransformer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASDictionaryTransformer.m; path = Framework/MASDictionaryTransformer.m; sourceTree = ""; }; + F5FD7A1CAC5F980162BB80AF3BA94FD1 /* AudioStream.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AudioStream.swift; path = AMCoreAudio/AudioStream.swift; sourceTree = ""; }; + FF318380E895C518B7B8052F375AD842 /* it.lproj */ = {isa = PBXFileReference; includeInIndex = 1; path = it.lproj; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 941213D2430D297562720C51FB950F5F /* Frameworks */ = { + 4ADF60BA1B90B87D52EF550ED5194EC9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - C322A7288AAD972168AE2C0B75CD059B /* AppKit.framework in Frameworks */, - 902EEE23E9D3AA8467EF3A50431EF2BE /* Carbon.framework in Frameworks */, - 87E1E943697B97013BB895607DAC60F4 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 9C297045AF0032DBFB26D4A5B9CD541B /* Frameworks */ = { + 79DA256310AC3FF7FC0CF4ECB3E444F7 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - E52C92D7ABC8344192B32D6F33418646 /* Frameworks */ = { + ABEC36A3BE615CABC95DE7D955652A38 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F3A152D35D07959868FBF3D2E29EAEE1 /* AppKit.framework in Frameworks */, + 032114835220926E1FAA6B332C20F474 /* Carbon.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E573664A3C95AFD973D5B3D392F77059 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 86288836A35118CD387C7B8383A1F9F1 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 32DF2D860294139396E2A0B2201DC7AF /* Pods-Mute Me */ = { + 1082483116FC7239B010F925255F24AC /* Resources */ = { isa = PBXGroup; children = ( - 3ADD1D498AC44A5D7BD80C8B9F21D30B /* Pods-Mute Me-acknowledgements.markdown */, - 30E9081214B252FA88E26761619D5384 /* Pods-Mute Me-acknowledgements.plist */, - 8E4CB1032B70EC4DE02D87B368D77636 /* Pods-Mute Me-dummy.m */, - 34E349B65FF57F7507C7E886525FCD29 /* Pods-Mute Me-frameworks.sh */, - C59C0A36CF0FF5402DE8930148D3C39D /* Pods-Mute Me-resources.sh */, - D9BE4BA371D4340E716B396548885BFB /* Pods-Mute Me.debug.xcconfig */, - 7F7B48185DC0E504A7EAF6C3CAC1FBFB /* Pods-Mute Me.release.xcconfig */, + 8A2C3441A87129B30CE1D55EB0FCF88D /* cs.lproj */, + 6A085AC897F480938FD8205E790E5362 /* de.lproj */, + 8E37AFC5D939ABD376E54DF6FDBEBF6D /* en.lproj */, + 2A33F9E4DBC6B092FFBED9AD66583B93 /* es.lproj */, + AE6AE58205DC91D08D3628029D578BD1 /* fr.lproj */, + FF318380E895C518B7B8052F375AD842 /* it.lproj */, + 8F1DC0F50F5A8F203662D33E3A752F98 /* ja.lproj */, + 8CE1222E5403FDBA0FF874D786E3C334 /* ko.lproj */, + E053F4D7E5A0171F99A441F2A495E70F /* nl.lproj */, + 71F1ACA1E273718B63DB243453762045 /* pl.lproj */, + 7C797DD5F54C68F7AD07C6902E910D04 /* ru.lproj */, + 11F84CECBBD83213FAB9437CC53005DA /* zh-Hans.lproj */, + EC7E83519E23A52CAFACE3CFA8ABBC2D /* zh-Hant.lproj */, ); - name = "Pods-Mute Me"; - path = "Target Support Files/Pods-Mute Me"; + name = Resources; sourceTree = ""; }; - 3505FEFEE0F5A3FB4CD41AB3E1F4B539 /* Targets Support Files */ = { + 36DBC7BC9E611E31F9CE9A414EFDFA39 /* OS X */ = { isa = PBXGroup; children = ( - 32DF2D860294139396E2A0B2201DC7AF /* Pods-Mute Me */, + 089CBA884EB516614A8C77B86196F0A2 /* AppKit.framework */, + E4C463285A5925FB898105EC16FCB462 /* Carbon.framework */, ); - name = "Targets Support Files"; + name = "OS X"; sourceTree = ""; }; - 71E828FE9FE82679B14421EDD9C435F0 /* OS X */ = { + 57946C177876550CC342F7BB749D5AC5 /* Products */ = { isa = PBXGroup; children = ( - 0A5E586EAF4C098BB13472B84B96B96F /* AppKit.framework */, - 2E8B3BCAE3930DB03E31F39C1A09E705 /* Carbon.framework */, - 12CB16911106539CF98B4AF79FAA2938 /* Cocoa.framework */, + 2E126F54F7E79480B1976648D32C8D66 /* libAMCoreAudio.a */, + CD72F76D34D1B6EC12D2BFC70FE1F42C /* libMASShortcut.a */, + 14F3CA06AA7BC4907F6A1A4177CEC11D /* libPods-Mute Me.a */, + B822D22D1BB8539F8DBBF2BA53655683 /* MASShortcut.bundle */, ); - name = "OS X"; + name = Products; + sourceTree = ""; + }; + 7249C0F68A4D2A372EFE9254A03D144F /* MASShortcut */ = { + isa = PBXGroup; + children = ( + 1DD3DCA07EE6BBEB510E28B78164795C /* MASDictionaryTransformer.h */, + ED566130640BE986EDE9AECEDFA19ED3 /* MASDictionaryTransformer.m */, + 7ACBA716BF0D15B78C9F91A90F7DCDD3 /* MASHotKey.h */, + 4C97E6CABF48BDC6DC927F5984D59C6A /* MASHotKey.m */, + AA28AFF1B24A13B063349AC1800C6BBE /* MASKeyCodes.h */, + 6E68CC19D1A4D6596255D409C2B6C267 /* MASKeyMasks.h */, + C7330DB3FC46777FEFD2C7EEB68073A8 /* MASLocalization.h */, + 61EA23293B8D52869CE0C2B73D305DD6 /* MASLocalization.m */, + 8D7CF235F8CB3695AEA8FC1C2CDC23A8 /* MASShortcut.h */, + 2CE6173A1C8468D123FC535E451CBD03 /* MASShortcut.m */, + DBB80BE4D14C42B10C7E6DD69A3D08DE /* MASShortcutBinder.h */, + CBD746AFD858C4E4600305FC69BC4A43 /* MASShortcutBinder.m */, + 57B8F916B49E58D68B23EBD1B84CEACD /* MASShortcutMonitor.h */, + D51F19AB07CE6C018FABF6A86AB240CC /* MASShortcutMonitor.m */, + 205B5B4550A3C02781B4A85C62DB6BB0 /* MASShortcutValidator.h */, + 8CF1BCD39C024EBD38C4E46D3D5C45CD /* MASShortcutValidator.m */, + 8800159F77D90A6B11F9E6DB2B1D10C9 /* MASShortcutView.h */, + 672E38A4C198C098BA76D00DCF2C525D /* MASShortcutView.m */, + 1F63DB772886EF01076D831D08536154 /* MASShortcutView+Bindings.h */, + 5598DDAC241575E32DD53C69F65BCED0 /* MASShortcutView+Bindings.m */, + C343B557884B84D2882E164F9DB07510 /* Shortcut.h */, + 1082483116FC7239B010F925255F24AC /* Resources */, + C7E850A750123E5BEF2B86D3A472966D /* Support Files */, + ); + name = MASShortcut; + path = MASShortcut; sourceTree = ""; }; 7DB346D0F39D3F0E887471402A8071AB = { isa = PBXGroup; children = ( 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, - 96D996393384F21972E2DD81788EE22C /* Frameworks */, - DD0B7A53801E1BE1901C3DF3EFE653E5 /* Pods */, - 845F177C4E367A46B437CA2784062F52 /* Products */, - 3505FEFEE0F5A3FB4CD41AB3E1F4B539 /* Targets Support Files */, + D648CE86F139C7CCFD55D5B8A03BE74B /* Frameworks */, + 8C4327BE4D104B8362CEA14E368661BF /* Pods */, + 57946C177876550CC342F7BB749D5AC5 /* Products */, + 8368889B80401765FDE77555A43011AA /* Targets Support Files */, ); sourceTree = ""; }; - 845F177C4E367A46B437CA2784062F52 /* Products */ = { + 8368889B80401765FDE77555A43011AA /* Targets Support Files */ = { isa = PBXGroup; children = ( - EF3789198921958045681A19D290466B /* libMASShortcut.a */, - A212E1D2BC7A106F0B6463091F90FEB8 /* libPods-Mute Me.a */, - A8FCD63C6E322922A731DB941C851A4F /* MASShortcut.bundle */, + AB4F7A31AA0559D8C47D02D937B773C2 /* Pods-Mute Me */, ); - name = Products; + name = "Targets Support Files"; sourceTree = ""; }; - 86C7852825D60E928A0CFA79CBCEFD72 /* Support Files */ = { + 8C4327BE4D104B8362CEA14E368661BF /* Pods */ = { isa = PBXGroup; children = ( - 4ABF22BA082314E781B0AA36E9E238C4 /* MASShortcut.xcconfig */, - 9F2035E0B6B08D4683931B31919D5194 /* MASShortcut-dummy.m */, - C9A948480CC4094D7FD4DB1934F308DF /* MASShortcut-prefix.pch */, - 5BAF377C4E8EF2A53E3ACA62B79CD7E7 /* ResourceBundle-MASShortcut-Info.plist */, + DC2A003D24B72D222EF88AAD9ADD0A9C /* AMCoreAudio */, + 7249C0F68A4D2A372EFE9254A03D144F /* MASShortcut */, ); - name = "Support Files"; - path = "../Target Support Files/MASShortcut"; + name = Pods; sourceTree = ""; }; - 9001976D922754630998DED442D7BE6D /* Resources */ = { + AB4F7A31AA0559D8C47D02D937B773C2 /* Pods-Mute Me */ = { isa = PBXGroup; children = ( - 8C406EEFC562A5DDF90E7181CB08331B /* cs.lproj */, - 19DD9FCBCB8B9347A5BE1D983DEE6192 /* de.lproj */, - 2404E18B631A74AD670CE1609A7080BF /* en.lproj */, - 857F9CF0E370084DD45F7EE72F210D08 /* es.lproj */, - 038D200C5F73B8EFF0A93DF4E6E1BD90 /* fr.lproj */, - BC5C51BB4780191957F415BC673514BE /* it.lproj */, - FD95351169AD17DCD8AE7D859C1D6BC1 /* ja.lproj */, - 66963E9C1F04B976EC0D1830456B912C /* ko.lproj */, - B4F45EF1CC04352F093E8BF2B47F48B1 /* nl.lproj */, - EFDE7A909E6986B29687C1E0DEFF2C69 /* pl.lproj */, - 605EBDBCA1616C656042B471811F6C71 /* ru.lproj */, - 262F9C963F67BB43B77AEBFCCACE7C2E /* zh-Hans.lproj */, - A9C4628298B582F17383E31ED11A5F08 /* zh-Hant.lproj */, + E8E18812312F7AA632C59DF80A2A39E8 /* Pods-Mute Me.modulemap */, + 4484AF6BAC1CAFF87FE9AE927E507BDC /* Pods-Mute Me-acknowledgements.markdown */, + A4F05A0D12CA9ADB324902B31CD47933 /* Pods-Mute Me-acknowledgements.plist */, + 3138415EE4C39E4D8D18803DC62AF15D /* Pods-Mute Me-dummy.m */, + D6BF686FED3D7AC758EACBA7D84FE58E /* Pods-Mute Me-frameworks.sh */, + CB6080E06103C655397D0E8D218C77D0 /* Pods-Mute Me-resources.sh */, + 91C31DF27E277122DD1523A744A7A165 /* Pods-Mute Me-umbrella.h */, + 7EF0A9BFDE8644C1FC9E8B49B30D176E /* Pods-Mute Me.debug.xcconfig */, + 0FB17B12CA8811D0A23D3E900BA24288 /* Pods-Mute Me.release.xcconfig */, ); - name = Resources; + name = "Pods-Mute Me"; + path = "Target Support Files/Pods-Mute Me"; sourceTree = ""; }; - 96D996393384F21972E2DD81788EE22C /* Frameworks */ = { + C7E850A750123E5BEF2B86D3A472966D /* Support Files */ = { isa = PBXGroup; children = ( - 71E828FE9FE82679B14421EDD9C435F0 /* OS X */, + 0D96CB7C478CD981286C75F892355A12 /* MASShortcut.xcconfig */, + 4F6374DC3D73D05DC6DDF696B0874073 /* MASShortcut-dummy.m */, + 020C0DA4FA888537D881BA658A516317 /* MASShortcut-prefix.pch */, + C2FE061CA93A2BDB59B73987EB219397 /* ResourceBundle-MASShortcut-Info.plist */, ); - name = Frameworks; + name = "Support Files"; + path = "../Target Support Files/MASShortcut"; sourceTree = ""; }; - 9A4A1752687DE09C8DBF2479B5B1D8F3 /* MASShortcut */ = { + D648CE86F139C7CCFD55D5B8A03BE74B /* Frameworks */ = { isa = PBXGroup; children = ( - 2414CC14D6996F009EBA016B98439675 /* MASDictionaryTransformer.h */, - 8ED853B9DF49E5C90CCA069BB3F2B43B /* MASDictionaryTransformer.m */, - BC6E28893186CA3688715CA60BFC32E0 /* MASHotKey.h */, - 55A11AB5D416530A484DAD1F97D9E010 /* MASHotKey.m */, - 8A7023C612FF3F139AE89D62A61C7A13 /* MASKeyCodes.h */, - 819F2EB6B7FFAB4121876D2654ACD028 /* MASKeyMasks.h */, - 6247799F171A0B65576998B4116F1F4E /* MASLocalization.h */, - 2EAD18341A993AF2033A3FB2D21AA783 /* MASLocalization.m */, - 4EA5D3E1505005EA05EF0615090F48F8 /* MASShortcut.h */, - BA53FE178C20D7B44CF09D6CE340DB43 /* MASShortcut.m */, - 9775F916524923D2392B56450009DFB7 /* MASShortcutBinder.h */, - 36695E6AC45B850D887F4F00D8CE1EE9 /* MASShortcutBinder.m */, - FC87DC0EA27BB8249F80FAE5FC10020C /* MASShortcutMonitor.h */, - 71170E4E2771D185598BE05475B68E69 /* MASShortcutMonitor.m */, - BE890D74FF5505CA2C7D20BDC9D0402A /* MASShortcutValidator.h */, - CA5C2484673E6954903EEDF333085965 /* MASShortcutValidator.m */, - 20E469613DEEF5698CC2E0658385B3A7 /* MASShortcutView.h */, - 9B3E9B40B057B9FEE6019C779F14C5A8 /* MASShortcutView.m */, - 8AD57029FEF1D175476848C76ACD611D /* MASShortcutView+Bindings.h */, - FD619B73B50911A58B096529F52A50A7 /* MASShortcutView+Bindings.m */, - 7431A6D435BC007D466649E2A7BAC1A9 /* Shortcut.h */, - 9001976D922754630998DED442D7BE6D /* Resources */, - 86C7852825D60E928A0CFA79CBCEFD72 /* Support Files */, + 36DBC7BC9E611E31F9CE9A414EFDFA39 /* OS X */, ); - name = MASShortcut; - path = MASShortcut; + name = Frameworks; sourceTree = ""; }; - DD0B7A53801E1BE1901C3DF3EFE653E5 /* Pods */ = { + DC2A003D24B72D222EF88AAD9ADD0A9C /* AMCoreAudio */ = { isa = PBXGroup; children = ( - 9A4A1752687DE09C8DBF2479B5B1D8F3 /* MASShortcut */, + BFC1A40C3AEEF2B0A906A2D9AF3CBDCF /* AMCoreAudio.h */, + 9C24D7458B53FC8C0E0AC5F35F93DCD8 /* AudioDevice.swift */, + D29DB9EACC28E55F42B7F7497E56930E /* AudioHardware.swift */, + 34C89D595D7C6327CB99F166987ABB3D /* AudioObject.swift */, + F5FD7A1CAC5F980162BB80AF3BA94FD1 /* AudioStream.swift */, + 795F93B81931EFDFBEB38B35E3B439A2 /* Bool+Extensions.swift */, + C4D90066DB370CE7374341AA1AFC7437 /* BundleInfo.swift */, + 9728E6AECF701D9714A158FBE4E4FBCB /* NotificationCenter.swift */, + 808932CA81FC8F274816065B66B90F65 /* Types.swift */, + 4F87DCFDA2B9446DEFB997E726115125 /* Utils.swift */, + F33FD00B1B7E8C7F5BD788D5CB8E0995 /* Support Files */, + ); + name = AMCoreAudio; + path = AMCoreAudio; + sourceTree = ""; + }; + F33FD00B1B7E8C7F5BD788D5CB8E0995 /* Support Files */ = { + isa = PBXGroup; + children = ( + 4908D3B99EFE914B3ECEC78FE635CD9C /* AMCoreAudio.modulemap */, + 09ACDB21F879D80D2F628185562E7A4A /* AMCoreAudio.xcconfig */, + 0FC8FB88DFDF9A34BCF6BBD18958D3FB /* AMCoreAudio-dummy.m */, + 68C6B64AF2EA5E434C96A9A30426465B /* AMCoreAudio-prefix.pch */, + E0CDCAC090952E3A35832B935916ECDD /* AMCoreAudio-umbrella.h */, ); - name = Pods; + name = "Support Files"; + path = "../Target Support Files/AMCoreAudio"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 9473DBBEA25053B2575C0714CC0FCF87 /* Headers */ = { + 0A8C2CE0B151F8DC356286934DA03617 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 720804F34108B4D8CA6ED208E23391E0 /* MASDictionaryTransformer.h in Headers */, - A5D5DCDE376956279D5B36EA42A24D7D /* MASHotKey.h in Headers */, - CA74C6C7D02F9C3FFAA2E3600617F0EF /* MASKeyCodes.h in Headers */, - 6F22DF5181A0505E68AB893585556551 /* MASKeyMasks.h in Headers */, - CC55627A7F9AC4EFF8FFE3AE9A73CBEC /* MASLocalization.h in Headers */, - 2BEA82707F6B1289F28D8C8097CF4121 /* MASShortcut.h in Headers */, - 56B0E92AC0CDAB0AD106E4A16CAA4B1C /* MASShortcutBinder.h in Headers */, - 6DFD61F5CE0AFF2AD3918A9719D46F63 /* MASShortcutMonitor.h in Headers */, - 34A3BE024A34E64B83C0CEBB641D987D /* MASShortcutValidator.h in Headers */, - F0E73BA1E7A419B07EDEDB7670600937 /* MASShortcutView+Bindings.h in Headers */, - 7A95B39667A492A060986B0795B85122 /* MASShortcutView.h in Headers */, - 45333808B39FACCB4128E10F4B44432B /* Shortcut.h in Headers */, + 1BFE6C690E87497478B413DA698581FE /* MASDictionaryTransformer.h in Headers */, + 9EB36945B3F024B1AB74EBE26568F349 /* MASHotKey.h in Headers */, + F62C2E44D07A79CCDAD8A813684B2B7E /* MASKeyCodes.h in Headers */, + D32E5B0A81CBB4E15BDD7ED6702454A7 /* MASKeyMasks.h in Headers */, + A54431EC24BD97D6F53C3D5C663D5535 /* MASLocalization.h in Headers */, + 2C3B819108C015056E37E70B8F5F5F97 /* MASShortcut.h in Headers */, + A18A16B46F8E24827037BC1351CB1902 /* MASShortcutBinder.h in Headers */, + C146D10CABABA35034A0A071B3762FB4 /* MASShortcutMonitor.h in Headers */, + D12A1378E0CE7DFEB6DF6C415233C124 /* MASShortcutValidator.h in Headers */, + 796502BE643C8A0FAF717D67A10A022F /* MASShortcutView+Bindings.h in Headers */, + 2D676047C6F308F0D8284D6607018D39 /* MASShortcutView.h in Headers */, + B28578A4640B4DEF4630973C9241A60D /* Shortcut.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 201732951AB0C19FCE19E246F43A4DE1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 1CCDA82A9A7612E541FF8AC05CE0618C /* AMCoreAudio-umbrella.h in Headers */, + 1D752D5EB52D85DA8E81118D6F0F563D /* AMCoreAudio.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 36B272E0E496595AF85940A795F1D756 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + E6D988DDCE07F9F298F552404DA897DF /* Pods-Mute Me-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 21E49887F9334B84548BFF0BA2C69086 /* MASShortcut-MASShortcut */ = { + 1E1EC0119E43772249F4DA6C196F1AC1 /* Pods-Mute Me */ = { isa = PBXNativeTarget; - buildConfigurationList = B0CB5289DD0F20D2CAF82C92BB3129B3 /* Build configuration list for PBXNativeTarget "MASShortcut-MASShortcut" */; + buildConfigurationList = 461133804696F2C9B398FD36B4E87314 /* Build configuration list for PBXNativeTarget "Pods-Mute Me" */; buildPhases = ( - EAF659BC5D7419DEE732EC806EF56C72 /* Sources */, - 9C297045AF0032DBFB26D4A5B9CD541B /* Frameworks */, - B8F7EFE753FA2FA9DA9FA9242878193C /* Resources */, + 36B272E0E496595AF85940A795F1D756 /* Headers */, + D3C064E1A7B19573560C7067BF52FEAD /* Sources */, + 4ADF60BA1B90B87D52EF550ED5194EC9 /* Frameworks */, ); buildRules = ( ); dependencies = ( + CE4273EDC616BFD1B5D413ACFDC58343 /* PBXTargetDependency */, + B96D52435348CF71C0133A549FC16F6B /* PBXTargetDependency */, ); - name = "MASShortcut-MASShortcut"; - productName = "MASShortcut-MASShortcut"; - productReference = A8FCD63C6E322922A731DB941C851A4F /* MASShortcut.bundle */; - productType = "com.apple.product-type.bundle"; + name = "Pods-Mute Me"; + productName = "Pods-Mute Me"; + productReference = 14F3CA06AA7BC4907F6A1A4177CEC11D /* libPods-Mute Me.a */; + productType = "com.apple.product-type.library.static"; }; - 2E029AB0CA275443A2AF3531E33683AB /* MASShortcut */ = { + 31DA45D85CE3DAB6BBD38E00F0A444BA /* MASShortcut */ = { isa = PBXNativeTarget; - buildConfigurationList = C84B7482B124C24B3A3B284872F1F133 /* Build configuration list for PBXNativeTarget "MASShortcut" */; + buildConfigurationList = F155FB4BBE57344E45D3CA53C13D3641 /* Build configuration list for PBXNativeTarget "MASShortcut" */; buildPhases = ( - 21E448A741CC6884D96A953FA9B7F8E0 /* Sources */, - 941213D2430D297562720C51FB950F5F /* Frameworks */, - 9473DBBEA25053B2575C0714CC0FCF87 /* Headers */, + 0A8C2CE0B151F8DC356286934DA03617 /* Headers */, + 3B5D5C57E22CD7600ADDE5721A475DD6 /* Sources */, + ABEC36A3BE615CABC95DE7D955652A38 /* Frameworks */, ); buildRules = ( ); dependencies = ( - C5433A9590099A9CA8A6C30603588C9B /* PBXTargetDependency */, + 74663D37B1256C26D923FCA051D14AF5 /* PBXTargetDependency */, ); name = MASShortcut; productName = MASShortcut; - productReference = EF3789198921958045681A19D290466B /* libMASShortcut.a */; + productReference = CD72F76D34D1B6EC12D2BFC70FE1F42C /* libMASShortcut.a */; productType = "com.apple.product-type.library.static"; }; - AD411026F3BFEA85B8D683794E6457DD /* Pods-Mute Me */ = { + 51129A24EE72AC4637629D9606318911 /* MASShortcut-MASShortcut */ = { isa = PBXNativeTarget; - buildConfigurationList = C59B4804432D9ECA9159C80B7B37BC2A /* Build configuration list for PBXNativeTarget "Pods-Mute Me" */; + buildConfigurationList = C1E6AC30F4C5B84ACB2136F98CB7E174 /* Build configuration list for PBXNativeTarget "MASShortcut-MASShortcut" */; buildPhases = ( - 12F1C704E5AE3C323C402A4B4BA9268E /* Sources */, - E52C92D7ABC8344192B32D6F33418646 /* Frameworks */, + 6CA09106A67B3F4D75AAC0B366ACDC60 /* Sources */, + E573664A3C95AFD973D5B3D392F77059 /* Frameworks */, + 1789053DFF49032E8587EA5DAE66FFD3 /* Resources */, ); buildRules = ( ); dependencies = ( - 62484F1F158BEFC07EDDF05DA6DFC680 /* PBXTargetDependency */, ); - name = "Pods-Mute Me"; - productName = "Pods-Mute Me"; - productReference = A212E1D2BC7A106F0B6463091F90FEB8 /* libPods-Mute Me.a */; + name = "MASShortcut-MASShortcut"; + productName = "MASShortcut-MASShortcut"; + productReference = B822D22D1BB8539F8DBBF2BA53655683 /* MASShortcut.bundle */; + productType = "com.apple.product-type.bundle"; + }; + F2DF73D98ECF3AA885B70529062E51F2 /* AMCoreAudio */ = { + isa = PBXNativeTarget; + buildConfigurationList = FB4CC7B56B8FD57B1CB073A923739B6A /* Build configuration list for PBXNativeTarget "AMCoreAudio" */; + buildPhases = ( + 201732951AB0C19FCE19E246F43A4DE1 /* Headers */, + C0A47ECA6AEC8A942D8E6AEB359B323C /* Sources */, + 79DA256310AC3FF7FC0CF4ECB3E444F7 /* Frameworks */, + F67A829BC74401AE68DB21DFF1C7ABA4 /* Copy generated compatibility header */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AMCoreAudio; + productName = AMCoreAudio; + productReference = 2E126F54F7E79480B1976648D32C8D66 /* libAMCoreAudio.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ @@ -366,8 +478,8 @@ D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0700; + LastSwiftUpdateCheck = 0930; + LastUpgradeCheck = 0930; }; buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; @@ -377,301 +489,368 @@ en, ); mainGroup = 7DB346D0F39D3F0E887471402A8071AB; - productRefGroup = 845F177C4E367A46B437CA2784062F52 /* Products */; + productRefGroup = 57946C177876550CC342F7BB749D5AC5 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 2E029AB0CA275443A2AF3531E33683AB /* MASShortcut */, - 21E49887F9334B84548BFF0BA2C69086 /* MASShortcut-MASShortcut */, - AD411026F3BFEA85B8D683794E6457DD /* Pods-Mute Me */, + F2DF73D98ECF3AA885B70529062E51F2 /* AMCoreAudio */, + 31DA45D85CE3DAB6BBD38E00F0A444BA /* MASShortcut */, + 51129A24EE72AC4637629D9606318911 /* MASShortcut-MASShortcut */, + 1E1EC0119E43772249F4DA6C196F1AC1 /* Pods-Mute Me */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - B8F7EFE753FA2FA9DA9FA9242878193C /* Resources */ = { + 1789053DFF49032E8587EA5DAE66FFD3 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1BFB0520F10AC37A104DF56489C393AD /* cs.lproj in Resources */, - D7790A18B5A9A073E65E6C35CC4E93C4 /* de.lproj in Resources */, - D6B7130455C1FC500FCFBB4C7B52F8DF /* en.lproj in Resources */, - FEFD6109965996832710EC2D2FE74A26 /* es.lproj in Resources */, - 0E3FE226CE18F169D10196723C37D1D6 /* fr.lproj in Resources */, - F0FBB86094DE6FFD72E0FA11946335D7 /* it.lproj in Resources */, - 88087104DB90EC679F1E367163351FFD /* ja.lproj in Resources */, - 6229CC2D8700E52B2C67C085FF9563D5 /* ko.lproj in Resources */, - D12DF721C2FBA157157279D77B865C1E /* nl.lproj in Resources */, - F111E58A8F199C64FAA24329DE9DC5C8 /* pl.lproj in Resources */, - 67250F0458194534752D26E44041F059 /* ru.lproj in Resources */, - 2DBA7EDB796E0AF9A189672E9CBA1407 /* zh-Hans.lproj in Resources */, - A358B1CC04588D145AA9D67E26A66AEA /* zh-Hant.lproj in Resources */, + 1C84CDAD529437F703DB82AFEAA5E4B6 /* cs.lproj in Resources */, + A23370E6F15B4D760D58F352944C3980 /* de.lproj in Resources */, + A9BE08C9AD3438D768172849F8906280 /* en.lproj in Resources */, + 2490A627FB16436157C4D688D93B583F /* es.lproj in Resources */, + BFE2D11FD048C0C802913C3EACA335BF /* fr.lproj in Resources */, + DB9C9F72BFAEF42212533B457687EF91 /* it.lproj in Resources */, + 98814E7E8FEEEF74ED4649F9784E04F0 /* ja.lproj in Resources */, + 147CCDE5AD17EEAEB7307135649A1CDA /* ko.lproj in Resources */, + 923B336EBB1CB2B1133BC0C99EA63782 /* nl.lproj in Resources */, + 4CF6A428699BBCD512BCB75DDD04253C /* pl.lproj in Resources */, + A51BA2AC7C6DCC3FBB4DCCC0E0A9C85D /* ru.lproj in Resources */, + 2D21A45126693BB628C5E9218D29BBF7 /* zh-Hans.lproj in Resources */, + 175B873D32A93054ED16A9EA28DF554E /* zh-Hant.lproj in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + F67A829BC74401AE68DB21DFF1C7ABA4 /* Copy generated compatibility header */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h", + "${PODS_ROOT}/Headers/Public/AMCoreAudio/AMCoreAudio.modulemap", + "${PODS_ROOT}/Headers/Public/AMCoreAudio/AMCoreAudio-umbrella.h", + ); + name = "Copy generated compatibility header"; + outputFileListPaths = ( + ); + outputPaths = ( + "${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap", + "${BUILT_PRODUCTS_DIR}/AMCoreAudio-umbrella.h", + "${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "COMPATIBILITY_HEADER_PATH=\"${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h\"\nMODULE_MAP_PATH=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap\"\n\nditto \"${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h\" \"${COMPATIBILITY_HEADER_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/AMCoreAudio/AMCoreAudio.modulemap\" \"${MODULE_MAP_PATH}\"\nditto \"${PODS_ROOT}/Headers/Public/AMCoreAudio/AMCoreAudio-umbrella.h\" \"${BUILT_PRODUCTS_DIR}\"\nprintf \"\\n\\nmodule ${PRODUCT_MODULE_NAME}.Swift {\\n header \\\"${COMPATIBILITY_HEADER_PATH}\\\"\\n requires objc\\n}\\n\" >> \"${MODULE_MAP_PATH}\"\n"; + showEnvVarsInLog = 1; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ - 12F1C704E5AE3C323C402A4B4BA9268E /* Sources */ = { + 3B5D5C57E22CD7600ADDE5721A475DD6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5949E58680693F245B6618769F48E027 /* MASDictionaryTransformer.m in Sources */, + F58931A610D4EE4CE5BA282CE50CDBAE /* MASHotKey.m in Sources */, + 5DB9D8AB23B4B44A2D310195FE6DD9C8 /* MASLocalization.m in Sources */, + 0E7B078C378488D0FE927FAA1A5C96D0 /* MASShortcut-dummy.m in Sources */, + ACFD347C8623905355E68B1BFF70D5C3 /* MASShortcut.m in Sources */, + 68743B36BC7BA3D8353809CFB18E3AAF /* MASShortcutBinder.m in Sources */, + F4BC1C6AE1DA18857CCE4CE5017EB06B /* MASShortcutMonitor.m in Sources */, + 60FEA26188D044E89F8677FF2145602B /* MASShortcutValidator.m in Sources */, + 5991CFA46E6B481A7D16A8FCE2C8AAB3 /* MASShortcutView+Bindings.m in Sources */, + A08D6BAA2DB79A661C32701D100ECC42 /* MASShortcutView.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6CA09106A67B3F4D75AAC0B366ACDC60 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 959B73A9B0B7E25899F6A37ECB3302C5 /* Pods-Mute Me-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 21E448A741CC6884D96A953FA9B7F8E0 /* Sources */ = { + C0A47ECA6AEC8A942D8E6AEB359B323C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5C5FEAFEBC103CA46099D2D65EBC47A1 /* MASDictionaryTransformer.m in Sources */, - BCF8876FA78B037CCD4B6BC9246DC6FD /* MASHotKey.m in Sources */, - 3C5B1682B90C602799A06D0A5FDC68F9 /* MASLocalization.m in Sources */, - 0E9F71B13EB5B5185C1368803180F2BA /* MASShortcut-dummy.m in Sources */, - 3F085DAD796785980C134C9F89C27044 /* MASShortcut.m in Sources */, - 33691F55769BFDF534CD2343841B2B48 /* MASShortcutBinder.m in Sources */, - 4416502FCC3847A2A4239B44A9624A47 /* MASShortcutMonitor.m in Sources */, - 96C33D954D43210E97B3DF6444AB94E5 /* MASShortcutValidator.m in Sources */, - BE1F5449678438070473EA08C4951547 /* MASShortcutView+Bindings.m in Sources */, - E450732C1FBD59C7E1C614CC5B0AA249 /* MASShortcutView.m in Sources */, + 4AE0C21E0BAA974F2C60A080ED8C2C60 /* AMCoreAudio-dummy.m in Sources */, + B012CA369CF29D6A7C9ADC7FAB089BFA /* AudioDevice.swift in Sources */, + 70505A7976C90DA277BCF05983D4C3D0 /* AudioHardware.swift in Sources */, + 3DDE5D8E6BA5807A73AA2DAF0A6380AD /* AudioObject.swift in Sources */, + C2B7C61C31EBBAC3DD5AD0BCF6F08FEE /* AudioStream.swift in Sources */, + 4CBD52728FBB8422C646B006C863DFBC /* Bool+Extensions.swift in Sources */, + 11779DBA685BB660420494534B69AE9C /* BundleInfo.swift in Sources */, + 576F91878CBEE7B98FFE2DBF14513287 /* NotificationCenter.swift in Sources */, + 1C49168C4CA9F8F28855E705CEAAF3BE /* Types.swift in Sources */, + E0474C69B6C6A2948B9C1CC1700FE887 /* Utils.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - EAF659BC5D7419DEE732EC806EF56C72 /* Sources */ = { + D3C064E1A7B19573560C7067BF52FEAD /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5072F8909F7D9030E51C99863E0DCA5F /* Pods-Mute Me-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 62484F1F158BEFC07EDDF05DA6DFC680 /* PBXTargetDependency */ = { + 74663D37B1256C26D923FCA051D14AF5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "MASShortcut-MASShortcut"; + target = 51129A24EE72AC4637629D9606318911 /* MASShortcut-MASShortcut */; + targetProxy = 0C3A21DFDB41A3CB6E4AD1C5DDC20F55 /* PBXContainerItemProxy */; + }; + B96D52435348CF71C0133A549FC16F6B /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = MASShortcut; - target = 2E029AB0CA275443A2AF3531E33683AB /* MASShortcut */; - targetProxy = 864BADC041E6C26B87C3BEBC266C0532 /* PBXContainerItemProxy */; + target = 31DA45D85CE3DAB6BBD38E00F0A444BA /* MASShortcut */; + targetProxy = 9F916A9B1DDCD9C6C3315E1399EE7D5D /* PBXContainerItemProxy */; }; - C5433A9590099A9CA8A6C30603588C9B /* PBXTargetDependency */ = { + CE4273EDC616BFD1B5D413ACFDC58343 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "MASShortcut-MASShortcut"; - target = 21E49887F9334B84548BFF0BA2C69086 /* MASShortcut-MASShortcut */; - targetProxy = AB589568138B5952333D183DCA39836A /* PBXContainerItemProxy */; + name = AMCoreAudio; + target = F2DF73D98ECF3AA885B70529062E51F2 /* AMCoreAudio */; + targetProxy = 38506A9005375B291F3480229AD70EC7 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 34342BBF37D3A9ED85FF2EB654934920 /* Debug */ = { + 02206A39950AB264474BF72228F5C23F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_ALLOWED = NO; CODE_SIGNING_REQUIRED = NO; COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_DEBUG=1", "DEBUG=1", "$(inherited)", ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; - PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; + PRODUCT_NAME = "$(TARGET_NAME)"; STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; SYMROOT = "${SRCROOT}/../build"; }; name = Debug; }; - 4ADF51409C9F39D25DA9E7B14E326488 /* Debug */ = { + 177A3C31A884A9FB4358C0993A597543 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4ABF22BA082314E781B0AA36E9E238C4 /* MASShortcut.xcconfig */; + baseConfigurationReference = 09ACDB21F879D80D2F628185562E7A4A /* AMCoreAudio.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; EXECUTABLE_PREFIX = lib; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/MASShortcut/MASShortcut-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.6; - MTL_ENABLE_DEBUG_INFO = YES; + GCC_PREFIX_HEADER = "Target Support Files/AMCoreAudio/AMCoreAudio-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MODULEMAP_FILE = Headers/Public/AMCoreAudio/AMCoreAudio.modulemap; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_NAME = "$(TARGET_NAME)"; + PRODUCT_MODULE_NAME = AMCoreAudio; + PRODUCT_NAME = AMCoreAudio; PUBLIC_HEADERS_FOLDER_PATH = ""; SDKROOT = macosx; - }; - name = Debug; - }; - 737E5759E3AAFFA34D1366864DD40719 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D9BE4BA371D4340E716B396548885BFB /* Pods-Mute Me.debug.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - EXECUTABLE_PREFIX = lib; - GCC_NO_COMMON_BLOCKS = YES; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MTL_ENABLE_DEBUG_INFO = YES; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.2; }; - name = Debug; + name = Release; }; - 8E6B18C7D47F86023A169919C67AA2BA /* Release */ = { + 5264FC0E0F7539F4AEF4522752B4933D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4ABF22BA082314E781B0AA36E9E238C4 /* MASShortcut.xcconfig */; + baseConfigurationReference = 0D96CB7C478CD981286C75F892355A12 /* MASShortcut.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "-"; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - EXECUTABLE_PREFIX = lib; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/MASShortcut/MASShortcut-prefix.pch"; + COMBINE_HIDPI_IMAGES = YES; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/MASShortcut"; + INFOPLIST_FILE = "Target Support Files/MASShortcut/ResourceBundle-MASShortcut-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; MACOSX_DEPLOYMENT_TARGET = 10.6; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = ""; + PRODUCT_NAME = MASShortcut; SDKROOT = macosx; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = bundle; }; name = Release; }; - C351F93C45351B853B14E951EBE0194B /* Release */ = { + 55998CC6BA9E1A6B83723D47B9B43C94 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7F7B48185DC0E504A7EAF6C3CAC1FBFB /* Pods-Mute Me.release.xcconfig */; + baseConfigurationReference = 0FB17B12CA8811D0A23D3E900BA24288 /* Pods-Mute Me.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; CODE_SIGN_IDENTITY = "-"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; EXECUTABLE_PREFIX = lib; - GCC_NO_COMMON_BLOCKS = YES; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 10.12; - MTL_ENABLE_DEBUG_INFO = NO; + MODULEMAP_FILE = "Target Support Files/Pods-Mute Me/Pods-Mute Me.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SKIP_INSTALL = YES; }; name = Release; }; - C953738A4376755FEA05BB8FF29736EB /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4ABF22BA082314E781B0AA36E9E238C4 /* MASShortcut.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/MASShortcut"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/MASShortcut/ResourceBundle-MASShortcut-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; - MACOSX_DEPLOYMENT_TARGET = 10.6; - PRODUCT_NAME = MASShortcut; - SDKROOT = macosx; - SKIP_INSTALL = YES; - WRAPPER_EXTENSION = bundle; - }; - name = Debug; - }; - F6FC88CB717F413199C282718D2DC09F /* Release */ = { + 62FE7660C9BFFBB21FA80BED50834E37 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_ALLOWED = NO; CODE_SIGNING_REQUIRED = NO; - COPY_PHASE_STRIP = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_RELEASE=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.12; - PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; STRIP_INSTALLED_PRODUCT = NO; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 4.2; SYMROOT = "${SRCROOT}/../build"; - VALIDATE_PRODUCT = YES; }; name = Release; }; - FE5FC25B90CAF06F692706624247B99B /* Release */ = { + A23337F7C0FF3056A6C7F0EA448DFB23 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4ABF22BA082314E781B0AA36E9E238C4 /* MASShortcut.xcconfig */; + baseConfigurationReference = 0D96CB7C478CD981286C75F892355A12 /* MASShortcut.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + EXECUTABLE_PREFIX = lib; + GCC_PREFIX_HEADER = "Target Support Files/MASShortcut/MASShortcut-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.6; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = MASShortcut; + PRODUCT_NAME = MASShortcut; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.2; + }; + name = Release; + }; + B15D47C5D9F1047A7741288EF415BBBB /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0D96CB7C478CD981286C75F892355A12 /* MASShortcut.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/MASShortcut"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Target Support Files/MASShortcut/ResourceBundle-MASShortcut-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; MACOSX_DEPLOYMENT_TARGET = 10.6; @@ -680,7 +859,80 @@ SKIP_INSTALL = YES; WRAPPER_EXTENSION = bundle; }; - name = Release; + name = Debug; + }; + BA82A7769D6BCA62D3D7B4E6342FC5F6 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0D96CB7C478CD981286C75F892355A12 /* MASShortcut.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + EXECUTABLE_PREFIX = lib; + GCC_PREFIX_HEADER = "Target Support Files/MASShortcut/MASShortcut-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.6; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = MASShortcut; + PRODUCT_NAME = MASShortcut; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.2; + }; + name = Debug; + }; + C7023F3E5A3824DB503445EB69825484 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 09ACDB21F879D80D2F628185562E7A4A /* AMCoreAudio.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + EXECUTABLE_PREFIX = lib; + GCC_PREFIX_HEADER = "Target Support Files/AMCoreAudio/AMCoreAudio-prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MODULEMAP_FILE = Headers/Public/AMCoreAudio/AMCoreAudio.modulemap; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PRIVATE_HEADERS_FOLDER_PATH = ""; + PRODUCT_MODULE_NAME = AMCoreAudio; + PRODUCT_NAME = AMCoreAudio; + PUBLIC_HEADERS_FOLDER_PATH = ""; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.2; + }; + name = Debug; + }; + D64028E85DAEFFBC9149E212D1BF48D5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7EF0A9BFDE8644C1FC9E8B49B30D176E /* Pods-Mute Me.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + EXECUTABLE_PREFIX = lib; + MACH_O_TYPE = staticlib; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MODULEMAP_FILE = "Target Support Files/Pods-Mute Me/Pods-Mute Me.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + SDKROOT = macosx; + SKIP_INSTALL = YES; + }; + name = Debug; }; /* End XCBuildConfiguration section */ @@ -688,35 +940,44 @@ 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( - 34342BBF37D3A9ED85FF2EB654934920 /* Debug */, - F6FC88CB717F413199C282718D2DC09F /* Release */, + 02206A39950AB264474BF72228F5C23F /* Debug */, + 62FE7660C9BFFBB21FA80BED50834E37 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 461133804696F2C9B398FD36B4E87314 /* Build configuration list for PBXNativeTarget "Pods-Mute Me" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D64028E85DAEFFBC9149E212D1BF48D5 /* Debug */, + 55998CC6BA9E1A6B83723D47B9B43C94 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - B0CB5289DD0F20D2CAF82C92BB3129B3 /* Build configuration list for PBXNativeTarget "MASShortcut-MASShortcut" */ = { + C1E6AC30F4C5B84ACB2136F98CB7E174 /* Build configuration list for PBXNativeTarget "MASShortcut-MASShortcut" */ = { isa = XCConfigurationList; buildConfigurations = ( - C953738A4376755FEA05BB8FF29736EB /* Debug */, - FE5FC25B90CAF06F692706624247B99B /* Release */, + B15D47C5D9F1047A7741288EF415BBBB /* Debug */, + 5264FC0E0F7539F4AEF4522752B4933D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C59B4804432D9ECA9159C80B7B37BC2A /* Build configuration list for PBXNativeTarget "Pods-Mute Me" */ = { + F155FB4BBE57344E45D3CA53C13D3641 /* Build configuration list for PBXNativeTarget "MASShortcut" */ = { isa = XCConfigurationList; buildConfigurations = ( - 737E5759E3AAFFA34D1366864DD40719 /* Debug */, - C351F93C45351B853B14E951EBE0194B /* Release */, + BA82A7769D6BCA62D3D7B4E6342FC5F6 /* Debug */, + A23337F7C0FF3056A6C7F0EA448DFB23 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C84B7482B124C24B3A3B284872F1F133 /* Build configuration list for PBXNativeTarget "MASShortcut" */ = { + FB4CC7B56B8FD57B1CB073A923739B6A /* Build configuration list for PBXNativeTarget "AMCoreAudio" */ = { isa = XCConfigurationList; buildConfigurations = ( - 4ADF51409C9F39D25DA9E7B14E326488 /* Debug */, - 8E6B18C7D47F86023A169919C67AA2BA /* Release */, + C7023F3E5A3824DB503445EB69825484 /* Debug */, + 177A3C31A884A9FB4358C0993A597543 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Pods/Target Support Files/AMCoreAudio/AMCoreAudio-dummy.m b/Pods/Target Support Files/AMCoreAudio/AMCoreAudio-dummy.m new file mode 100644 index 0000000..06f96c6 --- /dev/null +++ b/Pods/Target Support Files/AMCoreAudio/AMCoreAudio-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_AMCoreAudio : NSObject +@end +@implementation PodsDummy_AMCoreAudio +@end diff --git a/Pods/Target Support Files/AMCoreAudio/AMCoreAudio-prefix.pch b/Pods/Target Support Files/AMCoreAudio/AMCoreAudio-prefix.pch new file mode 100644 index 0000000..082f8af --- /dev/null +++ b/Pods/Target Support Files/AMCoreAudio/AMCoreAudio-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/AMCoreAudio/AMCoreAudio.xcconfig b/Pods/Target Support Files/AMCoreAudio/AMCoreAudio.xcconfig new file mode 100644 index 0000000..ca59ad7 --- /dev/null +++ b/Pods/Target Support Files/AMCoreAudio/AMCoreAudio.xcconfig @@ -0,0 +1,10 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/AMCoreAudio +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/AMCoreAudio" "${PODS_ROOT}/Headers/Public" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" -import-underlying-module -Xcc -fmodule-map-file="${SRCROOT}/${MODULEMAP_FILE}" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/AMCoreAudio +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/MASShortcut/MASShortcut.xcconfig b/Pods/Target Support Files/MASShortcut/MASShortcut.xcconfig index 8aa1c50..073db88 100644 --- a/Pods/Target Support Files/MASShortcut/MASShortcut.xcconfig +++ b/Pods/Target Support Files/MASShortcut/MASShortcut.xcconfig @@ -1,9 +1,9 @@ -CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/MASShortcut +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MASShortcut GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/MASShortcut" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MASShortcut" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/MASShortcut" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MASShortcut" OTHER_LDFLAGS = -framework "AppKit" -framework "Carbon" -PODS_BUILD_DIR = $BUILD_DIR -PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/MASShortcut PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} diff --git a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-acknowledgements.markdown b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-acknowledgements.markdown index 595a10a..730aef1 100644 --- a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-acknowledgements.markdown @@ -1,6 +1,17 @@ # Acknowledgements This application makes use of the following third party libraries: +## AMCoreAudio + +Copyright (c) 2014-2018 Ruben Nine + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + ## MASShortcut Copyright (c) 2012-2013, Vadim Shpakovski diff --git a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-acknowledgements.plist b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-acknowledgements.plist index 7fa5904..857d926 100644 --- a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-acknowledgements.plist @@ -12,6 +12,23 @@ Type PSGroupSpecifier + + FooterText + Copyright (c) 2014-2018 Ruben Nine + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + License + MIT + Title + AMCoreAudio + Type + PSGroupSpecifier + FooterText Copyright (c) 2012-2013, Vadim Shpakovski diff --git a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-frameworks.sh b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-frameworks.sh index 0f29f13..08e3eaa 100755 --- a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-frameworks.sh +++ b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-frameworks.sh @@ -1,11 +1,28 @@ #!/bin/sh set -e +set -u +set -o pipefail + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework install_framework() { if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then @@ -23,9 +40,9 @@ install_framework() source="$(readlink "${source}")" fi - # use filter instead of exclude so missing patterns dont' throw errors - echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" - rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" local basename basename="$(basename -s .framework "$1")" @@ -54,12 +71,40 @@ install_framework() fi } +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + if [ -r "$source" ]; then + # Copy the dSYM into a the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .framework.dSYM "$source")" + binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then + strip_invalid_archs "$binary" + fi + + if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" + fi + fi +} + # Signs a framework with the provided identity code_sign_if_enabled() { - if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # Use the current code_sign_identitiy echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" - local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then code_sign_cmd="$code_sign_cmd &" @@ -72,11 +117,19 @@ code_sign_if_enabled() { # Strip invalid architectures strip_invalid_archs() { binary="$1" - # Get architectures for current file - archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + STRIP_BINARY_RETVAL=0 + return + fi stripped="" - for arch in $archs; do - if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then # Strip non-valid architectures in-place lipo -remove "$arch" -output "$binary" "$binary" || exit 1 stripped="$stripped $arch" @@ -85,6 +138,7 @@ strip_invalid_archs() { if [[ "$stripped" ]]; then echo "Stripped $binary of architectures:$stripped" fi + STRIP_BINARY_RETVAL=1 } if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then diff --git a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-resources.sh b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-resources.sh index 31cb2f4..42a4ed3 100755 --- a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-resources.sh +++ b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-resources.sh @@ -1,5 +1,13 @@ #!/bin/sh set -e +set -u +set -o pipefail + +if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then + # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy + # resources to, so exit 0 (signalling the script phase was successful). + exit 0 +fi mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" @@ -8,7 +16,11 @@ RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt XCASSET_FILES=() -case "${TARGETED_DEVICE_FAMILY}" in +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +case "${TARGETED_DEVICE_FAMILY:-}" in 1,2) TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" ;; @@ -21,6 +33,9 @@ case "${TARGETED_DEVICE_FAMILY}" in 3) TARGET_DEVICE_ARGS="--target-device tv" ;; + 4) + TARGET_DEVICE_ARGS="--target-device watch" + ;; *) TARGET_DEVICE_ARGS="--target-device mac" ;; @@ -41,29 +56,29 @@ EOM fi case $RESOURCE_PATH in *.storyboard) - echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.xib) - echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.framework) - echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" - echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" - rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" ;; *.xcdatamodel) - echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" ;; *.xcdatamodeld) - echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" ;; *.xcmappingmodel) - echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" ;; *.xcassets) @@ -71,16 +86,16 @@ EOM XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") ;; *) - echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" || true echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" ;; esac } if [[ "$CONFIGURATION" == "Debug" ]]; then - install_resource "$PODS_CONFIGURATION_BUILD_DIR/MASShortcut/MASShortcut.bundle" + install_resource "${PODS_CONFIGURATION_BUILD_DIR}/MASShortcut/MASShortcut.bundle" fi if [[ "$CONFIGURATION" == "Release" ]]; then - install_resource "$PODS_CONFIGURATION_BUILD_DIR/MASShortcut/MASShortcut.bundle" + install_resource "${PODS_CONFIGURATION_BUILD_DIR}/MASShortcut/MASShortcut.bundle" fi mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" @@ -91,7 +106,7 @@ if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then fi rm -f "$RESOURCES_TO_COPY" -if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] then # Find all other xcassets (this unfortunately includes those of path pods and other targets). OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) @@ -101,5 +116,9 @@ then fi done <<<"$OTHER_XCASSETS" - printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + else + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" + fi fi diff --git a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-umbrella.h b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-umbrella.h new file mode 100644 index 0000000..d9fa2a9 --- /dev/null +++ b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_Mute_MeVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_Mute_MeVersionString[]; + diff --git a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.debug.xcconfig b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.debug.xcconfig index 778c9de..24ff751 100644 --- a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.debug.xcconfig +++ b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.debug.xcconfig @@ -1,8 +1,12 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MASShortcut" -LIBRARY_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/MASShortcut" -OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/MASShortcut" -OTHER_LDFLAGS = $(inherited) -ObjC -l"MASShortcut" -framework "AppKit" -framework "Carbon" -PODS_BUILD_DIR = $BUILD_DIR -PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AMCoreAudio" "${PODS_ROOT}/Headers/Public/MASShortcut" +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AMCoreAudio" "${PODS_CONFIGURATION_BUILD_DIR}/MASShortcut" +OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/AMCoreAudio/AMCoreAudio.modulemap" -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AMCoreAudio" -isystem "${PODS_ROOT}/Headers/Public/MASShortcut" +OTHER_LDFLAGS = $(inherited) -ObjC -l"AMCoreAudio" -l"MASShortcut" -framework "AppKit" -framework "Carbon" +OTHER_SWIFT_FLAGS = $(inherited) -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/AMCoreAudio/AMCoreAudio.modulemap" $(inherited) "-D" "COCOAPODS" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +SWIFT_INCLUDE_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AMCoreAudio" diff --git a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.modulemap b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.modulemap new file mode 100644 index 0000000..1d10875 --- /dev/null +++ b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.modulemap @@ -0,0 +1,6 @@ +module Pods_Mute_Me { + umbrella header "Pods-Mute Me-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.release.xcconfig b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.release.xcconfig index 778c9de..24ff751 100644 --- a/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.release.xcconfig +++ b/Pods/Target Support Files/Pods-Mute Me/Pods-Mute Me.release.xcconfig @@ -1,8 +1,12 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MASShortcut" -LIBRARY_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/MASShortcut" -OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/MASShortcut" -OTHER_LDFLAGS = $(inherited) -ObjC -l"MASShortcut" -framework "AppKit" -framework "Carbon" -PODS_BUILD_DIR = $BUILD_DIR -PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AMCoreAudio" "${PODS_ROOT}/Headers/Public/MASShortcut" +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AMCoreAudio" "${PODS_CONFIGURATION_BUILD_DIR}/MASShortcut" +OTHER_CFLAGS = $(inherited) -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/AMCoreAudio/AMCoreAudio.modulemap" -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AMCoreAudio" -isystem "${PODS_ROOT}/Headers/Public/MASShortcut" +OTHER_LDFLAGS = $(inherited) -ObjC -l"AMCoreAudio" -l"MASShortcut" -framework "AppKit" -framework "Carbon" +OTHER_SWIFT_FLAGS = $(inherited) -Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/AMCoreAudio/AMCoreAudio.modulemap" $(inherited) "-D" "COCOAPODS" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +SWIFT_INCLUDE_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AMCoreAudio" diff --git a/README.md b/README.md index 2effe1d..9205621 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ Use the Touch Bar app to Mute/Unmute your microphone, or just use the shortcut o When you’re in a meeting using Hangouts, Skype, Slack, or another voice application, it's good practice to stay on mute until someone speaks to you directly - especially if you’re meeting with three or more people. Often, however, you'll need to browse between multiple tabs, and it can take too long to switch back to the meeting app to unmute your microphone. With Mute Me, you can mute or unmute your mic quickly and easily, right from your Touch Bar. +### Colors +- Grey touchbar icon - Devices aren't muted +- Yellow touchbar icon - Devices should be muted but some of them not. (For example, due to another software control) +- Red touchbar icon - All devices are successfuly muted 👍 + ### Options - use long tap on the Touch Bar icon to open Preferences - find the Open at Login option in Preferences @@ -35,6 +40,7 @@ You can find approved ideas for future implementation [here](https://github.com/ - [Alex Barashkov](https://github.com/lnikell) - [Vlad Kamelsky](https://www.facebook.com/vlad.kamelsky) - [Joel Barker](https://github.com/j-cimb-barker) +- [Alexandr Promakh](https://github.com/proAlexandr) --- Made by [Pixel Point](https://pixelpoint.io)