1
1
mirror of https://github.com/bitgapp/eqMac.git synced 2024-12-12 16:24:12 +03:00
eqMac/native/app/Source/Audio/AudioDeviceEvents.swift

244 lines
9.2 KiB
Swift

//
// DeviceEvents.swift
// eqMac
//
// Created by Roman Kisil on 14/11/2018.
// Copyright © 2018 Roman Kisil. All rights reserved.
//
import Foundation
import AMCoreAudio
import EmitterKit
struct ListChangedDevices {
let added: [AudioDevice]
let removed: [AudioDevice]
}
enum AudioDeviceEventType {
case isJackConnectedChanged
case isRunningSomewhereChanged
case volumeChanged
case muteChanged
case isAliveChanged
case nominalSampleRateChanged
case availableNominalSampleRatesChanged
case clockSourceChanged
case nameChanged
case listChanged
case isRunningChanged
case preferredChannelsForStereoChanged
case hogModeChanged
case outputChanged
case inputChanged
case systemDeviceChanged
}
class AudioDeviceEvents: EventSubscriber {
static var events = AudioDeviceEvents()
var hashValue: Int = 1
static var listeners: [EmitterKit.EventListener<AudioDevice>] = [] as! [EmitterKit.EventListener<AudioDevice>]
// Per Device
let isJackConnectedChangedEvent = EmitterKit.Event<AudioDevice>()
let isRunningSomewhereChangedEvent = EmitterKit.Event<AudioDevice>()
var volumeChangedEvent = EmitterKit.Event<AudioDevice>()
let muteChangedEvent = EmitterKit.Event<AudioDevice>()
var isAliveChangedEvent = EmitterKit.Event<AudioDevice>()
var nominalSampleRateChangedEvent = EmitterKit.Event<AudioDevice>()
let availableNominalSampleRatesChangedEvent = EmitterKit.Event<AudioDevice>()
let clockSourceChangedEvent = EmitterKit.Event<AudioDevice>()
let nameChangedEvent = EmitterKit.Event<AudioDevice>()
let listChangedEvent = EmitterKit.Event<AudioDevice>()
let isRunningChangedEvent = EmitterKit.Event<AudioDevice>()
let preferredChannelsForStereoChangedEvent = EmitterKit.Event<AudioDevice>()
let hogModeChangedEvent = EmitterKit.Event<AudioDevice>()
// Hardware Events
let deviceListChangedEvent = EmitterKit.Event<ListChangedDevices>()
static var deviceListChangedListeners: [EmitterKit.EventListener<ListChangedDevices>] = [] as! [EmitterKit.EventListener<ListChangedDevices>]
let outputChangedEvent = EmitterKit.Event<AudioDevice>()
let inputChangedEvent = EmitterKit.Event<AudioDevice>()
let systemDeviceChangedEvent = EmitterKit.Event<AudioDevice>()
init () {
NotificationCenter.defaultCenter.subscribe(
self,
eventType: AudioHardwareEvent.self,
dispatchQueue: DispatchQueue.main
)
NotificationCenter.defaultCenter.subscribe(
self,
eventType: AudioDeviceEvent.self,
dispatchQueue: DispatchQueue.main
)
}
internal func eventReceiver(_ event: AMCoreAudio.Event) {
switch event {
case let event as AudioHardwareEvent:
switch event {
case .defaultOutputDeviceChanged(let device): outputChangedEvent.emit(device)
case .deviceListChanged(var added, var removed):
added = added.filter { $0.isHardware }
removed = removed.filter { $0.isHardware }
if (added.count > 0 || removed.count > 0) {
deviceListChangedEvent.emit(ListChangedDevices(
added: added,
removed: removed
))
}
case .defaultInputDeviceChanged(let device): inputChangedEvent.emit(device)
case .defaultSystemOutputDeviceChanged(let device): systemDeviceChangedEvent.emit(device)
}
case let event as AudioDeviceEvent:
let emitter = AudioDeviceEvents.getEventEmitterFromEvent(event)
let device = AudioDeviceEvents.getDeviceFromEvent(event)
emitter.emit(device)
default: return
}
}
static func recreateEventEmitters(_ eventsToRecreate: [AudioDeviceEventType]) throws {
for event in eventsToRecreate {
switch event {
case .isAliveChanged:
events.isAliveChangedEvent = EmitterKit.Event<AudioDevice>()
break
case .volumeChanged:
events.volumeChangedEvent = EmitterKit.Event<AudioDevice>()
break
case .nominalSampleRateChanged:
events.nominalSampleRateChangedEvent = EmitterKit.Event<AudioDevice>()
break
default:
throw "This event can't be recreated, or change this code"
}
}
}
static func getEventEmitterFromEvent (_ event: AudioDeviceEvent) -> EmitterKit.Event<AudioDevice> {
let eventType = getEventTypeFromEvent(event)
let emitter = getEventEmitterFromEventType(eventType)
return emitter
}
static func getEventTypeFromEvent (_ event: AudioDeviceEvent) -> AudioDeviceEventType {
switch event {
case .isRunningSomewhereDidChange(_): return .isRunningSomewhereChanged
case .volumeDidChange(_, _, _): return .volumeChanged
case .muteDidChange(_, _, _): return .muteChanged
case .isAliveDidChange(_): return .isAliveChanged
case .isJackConnectedDidChange(_): return .isJackConnectedChanged
case .nominalSampleRateDidChange(_): return .nominalSampleRateChanged
case .availableNominalSampleRatesDidChange(_): return .availableNominalSampleRatesChanged
case .clockSourceDidChange(_): return .clockSourceChanged
case .nameDidChange(_): return .nameChanged
case .listDidChange(_): return .listChanged
case .isRunningDidChange(_): return .isRunningChanged
case .preferredChannelsForStereoDidChange(_): return .preferredChannelsForStereoChanged
case .hogModeDidChange(_): return .hogModeChanged
}
}
static func getDeviceFromEvent (_ event: AudioDeviceEvent) -> AudioDevice {
switch event {
case .isRunningSomewhereDidChange(let device): return device
case .volumeDidChange(let device, _, _): return device
case .muteDidChange(let device, _, _): return device
case .isAliveDidChange(let device): return device
case .isJackConnectedDidChange(let device): return device
case .nominalSampleRateDidChange(let device): return device
case .availableNominalSampleRatesDidChange(let device): return device
case .clockSourceDidChange(let device): return device
case .nameDidChange(let device): return device
case .listDidChange(let device): return device
case .isRunningDidChange(let device): return device
case .preferredChannelsForStereoDidChange(let device): return device
case .hogModeDidChange(let device): return device
}
}
static func getEventEmitterFromEventType (_ event: AudioDeviceEventType) -> EmitterKit.Event<AudioDevice> {
switch event {
case .isRunningSomewhereChanged: return events.isRunningSomewhereChangedEvent
case .volumeChanged: return events.volumeChangedEvent
case .muteChanged: return events.muteChangedEvent
case .isAliveChanged: return events.isAliveChangedEvent
case .isJackConnectedChanged: return events.isJackConnectedChangedEvent
case .nominalSampleRateChanged: return events.nominalSampleRateChangedEvent
case .availableNominalSampleRatesChanged: return events.availableNominalSampleRatesChangedEvent
case .clockSourceChanged: return events.clockSourceChangedEvent
case .nameChanged: return events.nameChangedEvent
case .listChanged: return events.listChangedEvent
case .isRunningChanged: return events.isRunningChangedEvent
case .preferredChannelsForStereoChanged: return events.preferredChannelsForStereoChangedEvent
case .hogModeChanged: return events.hogModeChangedEvent
case .outputChanged: return events.outputChangedEvent
case .inputChanged: return events.inputChangedEvent
case .systemDeviceChanged: return events.systemDeviceChangedEvent
}
}
@discardableResult
static func on (_ event: AudioDeviceEventType, retain: Bool = true, _ handler: @escaping (AudioDevice) -> Void) -> EmitterKit.EventListener<AudioDevice> {
let emitter = getEventEmitterFromEventType(event)
let listener: EmitterKit.EventListener<AudioDevice> = emitter.on(handler)
if (retain) {
listeners.append(listener)
}
return listener
}
@discardableResult
static func on (_ event: AudioDeviceEventType, onDevice device: AudioDevice, retain: Bool = true, _ handler: @escaping () -> Void) -> EmitterKit.EventListener<AudioDevice> {
return on(event, retain: retain) { if $0.id == device.id { handler() }}
}
@discardableResult
static func once (_ event: AudioDeviceEventType, _ handler: @escaping (AudioDevice) -> Void) -> EmitterKit.EventListener<AudioDevice> {
let emitter = getEventEmitterFromEventType(event)
let listener: EmitterKit.EventListener<AudioDevice> = emitter.once(handler: handler)
return listener
}
static func once (_ event: AudioDeviceEventType, onDevice device: AudioDevice, _ handler: @escaping () -> Void) {
let emitter = getEventEmitterFromEventType(event)
emitter.once { d in
if (d.id == device.id) {
handler()
} else {
once(event, onDevice: device, handler)
}
}
}
@discardableResult
static func onDeviceListChanged (_ handler: @escaping (ListChangedDevices) -> Void) -> EmitterKit.EventListener<ListChangedDevices> {
let listener = events.deviceListChangedEvent.on(handler)
deviceListChangedListeners.append(listener)
return listener
}
static func start () {
for listener in listeners {
listener.isListening = true
}
}
static func stop () {
for listener in listeners {
listener.isListening = false
}
listeners.removeAll()
for listener in deviceListChangedListeners {
listener.isListening = false
}
deviceListChangedListeners.removeAll()
}
}