Created
May 24, 2017 22:34
-
-
Save jconst/74c42bc2c36c06852701b2879e04a925 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Audiobus.swift | |
// AudioKit | |
// | |
// Created by Daniel Clelland on 2/06/16. | |
// Updated for AudioKit 3 by Aurelius Prochazka. | |
// | |
// Copyright © 2016 AudioKit. All rights reserved. | |
// | |
import Foundation | |
import AudioKit | |
import CoreAudio | |
class Audiobus { | |
// MARK: Client | |
static var client: Audiobus? | |
// MARK: Actions | |
static func start() { | |
guard client == nil else { | |
return | |
} | |
if let apiKey = apiKey { | |
client = Audiobus(apiKey: apiKey) | |
} | |
} | |
private static var apiKey: String? { | |
guard let path = Bundle.main.path(forResource: "Audiobus", ofType: "txt") else { | |
return nil | |
} | |
do { | |
return try String(contentsOfFile: path).replacingOccurrences(of: "\n", with: "") | |
} catch { | |
return nil | |
} | |
} | |
// MARK: Initialization | |
//var controller: ABAudiobusController | |
var audioUnit: AudioUnit { | |
return AudioKit.engine.outputNode.audioUnit! | |
} | |
init(apiKey: String) { | |
//self.controller = ABAudiobusController(apiKey: apiKey) | |
var myDict: NSDictionary? | |
if let path = Bundle.main.path(forResource:"Info", ofType: "plist") { | |
myDict = NSDictionary(contentsOfFile: path) | |
} | |
if let dict = myDict { | |
for component in dict["AudioComponents"] as! [[String: AnyObject]] { | |
let type = fourCC(component["type"] as! String) | |
let subtype = fourCC(component["subtype"] as! String) | |
let name = component["name"] as! String | |
let manufacturer = fourCC(component["manufacturer"] as! String) | |
var desc = AudioComponentDescription(componentType: type, componentSubType: subtype, componentManufacturer: manufacturer, componentFlags: 0, componentFlagsMask: 0) | |
AudioOutputUnitPublish(&desc, name as CFString, 0, audioUnit) | |
/*if type == kAudioUnitType_RemoteInstrument || | |
type == kAudioUnitType_RemoteGenerator { | |
self.controller.addAudioSenderPort( | |
ABAudioSenderPort( | |
name: name, | |
title: name, | |
audioComponentDescription: AudioComponentDescription( | |
componentType: type, | |
componentSubType: subtype, | |
componentManufacturer: manufacturer, | |
componentFlags: 0, | |
componentFlagsMask: 0 | |
), | |
audioUnit: audioUnit | |
) | |
) | |
} | |
if type == kAudioUnitType_RemoteEffect { | |
self.controller.addAudioFilterPort( | |
ABAudioFilterPort( | |
name: name, | |
title: name, | |
audioComponentDescription: AudioComponentDescription( | |
componentType: type, | |
componentSubType: subtype, | |
componentManufacturer: manufacturer, | |
componentFlags: 0, | |
componentFlagsMask: 0 | |
), | |
audioUnit: audioUnit | |
) | |
) | |
}*/ | |
} | |
} | |
startObservingInterAppAudioConnections() | |
//startObservingAudiobusConnections() | |
} | |
deinit { | |
stopObservingInterAppAudioConnections() | |
//stopObservingAudiobusConnections() | |
} | |
// MARK: Properties | |
var isConnected: Bool { | |
return /*controller.isConnectedToAudiobus ||*/ audioUnit.isConnectedToInterAppAudio | |
} | |
var isConnectedToInput: Bool { | |
return /*controller.isConnectedToAudiobus(portOfType: ABPortTypeAudioSender) ||*/ audioUnit.isConnectedToInterAppAudio(nodeOfType: kAudioUnitType_RemoteEffect) | |
} | |
// MARK: Connections | |
private var audioUnitPropertyListener: AudioUnitPropertyListener! | |
private func startObservingInterAppAudioConnections() { | |
audioUnitPropertyListener = AudioUnitPropertyListener { (_, _) in | |
self.updateConnections() | |
} | |
audioUnit.add(listener: audioUnitPropertyListener, toProperty: kAudioUnitProperty_IsInterAppConnected) | |
} | |
private func stopObservingInterAppAudioConnections() { | |
audioUnit.remove(listener: self.audioUnitPropertyListener, fromProperty: kAudioUnitProperty_IsInterAppConnected) | |
} | |
/*private func startObservingAudiobusConnections() { | |
let _ = NotificationCenter.default.addObserver(forName: NSNotification.Name.ABConnectionsChanged, object: nil, queue: nil, using: { _ in | |
self.updateConnections() | |
}) | |
} | |
private func stopObservingAudiobusConnections() { | |
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.ABConnectionsChanged, object: nil) | |
}*/ | |
private func updateConnections() { | |
if isConnected { | |
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "IAAConnected"), object: nil) | |
} else { | |
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "IAADisconnected"), object: nil) | |
} | |
} | |
} | |
/* | |
private extension ABAudiobusController { | |
var isConnectedToAudiobus: Bool { | |
return connected && memberOfActiveAudiobusSession | |
} | |
func isConnectedToAudiobus(portOfType type: ABPortType) -> Bool { | |
guard connectedPorts != nil else { | |
return false | |
} | |
return connectedPorts.flatMap { $0 as? ABPort }.filter { $0.type == type }.isEmpty == false | |
} | |
}*/ | |
private extension AudioUnit { | |
var isConnectedToInterAppAudio: Bool { | |
let value: UInt32 = getValue(forProperty: kAudioUnitProperty_IsInterAppConnected) | |
return value != 0 | |
} | |
func isConnectedToInterAppAudio(nodeOfType type: OSType) -> Bool { | |
let value: AudioComponentDescription = getValue(forProperty: kAudioOutputUnitProperty_NodeComponentDescription) | |
return value.componentType == type | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment