Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix hardcoded MIDI instrument namings #1141

Merged
merged 4 commits into from
Dec 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions AudioKit/Common/MIDI/AKCallbackInstrument.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ open class AKCallbackInstrument: AKMIDIInstrument {

/// Initialize the callback instrument
///
/// - parameter midiInputName: Name of the instrument's MIDI input
/// - parameter callback: Initial callback
///
public init(callback: AKMIDICallback? = nil) {
public init(midiInputName: String = "callback midi in", callback: AKMIDICallback? = nil) {
super.init()
let midi = AudioKit.midi
self.enableMIDI(midi.client, name: "callback midi in")
self.enableMIDI(midi.client, name: midiInputName)
self.callback = callback
avAudioNode = AVAudioMixerNode()
AudioKit.engine.attach(self.avAudioNode)
Expand Down
208 changes: 114 additions & 94 deletions AudioKit/Common/MIDI/AKMIDI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,120 +21,140 @@ import CoreMIDI
/// You then implement the methods you need from AKMIDIListener and use the data how you need.
open class AKMIDI {

// MARK: - Properties
// MARK: - Properties

/// MIDI Client Reference
open var client = MIDIClientRef()
/// MIDI Client Reference
open var client = MIDIClientRef()

/// Array of MIDI In ports
internal var inputPorts: [String: MIDIPortRef] = [:]
/// Array of MIDI In ports
internal var inputPorts: [String: MIDIPortRef] = [:]

/// Virtual MIDI Input destination
open var virtualInput = MIDIPortRef()
/// Virtual MIDI Input destination
open var virtualInput = MIDIPortRef()

/// MIDI Client Name
private let clientName: CFString = "MIDI Client" as CFString
/// MIDI Client Name
private let clientName: CFString = "MIDI Client" as CFString

/// MIDI In Port Name
internal let inputPortName: CFString = "MIDI In Port" as CFString
/// MIDI In Port Name
internal let inputPortName: CFString = "MIDI In Port" as CFString

/// MIDI Out Port Reference
internal var outputPort = MIDIPortRef()
/// MIDI Out Port Reference
internal var outputPort = MIDIPortRef()

/// Virtual MIDI output
open var virtualOutput = MIDIPortRef()
/// Virtual MIDI output
open var virtualOutput = MIDIPortRef()

/// Array of MIDI Endpoints
open var endpoints = [String: MIDIEndpointRef]()
/// Array of MIDI Endpoints
open var endpoints = [String: MIDIEndpointRef]()

/// MIDI Out Port Name
internal var outputPortName: CFString = "MIDI Out Port" as CFString
/// MIDI Out Port Name
internal var outputPortName: CFString = "MIDI Out Port" as CFString

/// Array of all listeners
internal var listeners = [AKMIDIListener]()
/// Array of all listeners
internal var listeners = [AKMIDIListener]()

internal var transformers = [AKMIDITransformer]()
internal var transformers = [AKMIDITransformer]()

// MARK: - Initialization
// MARK: - Initialization

/// Initialize the AKMIDI system
@objc public init() {
/// Initialize the AKMIDI system
@objc public init() {

#if os(iOS)
MIDINetworkSession.default().isEnabled = true
MIDINetworkSession.default().connectionPolicy =
MIDINetworkConnectionPolicy.anyone
#endif
#if os(iOS)
MIDINetworkSession.default().isEnabled = true
MIDINetworkSession.default().connectionPolicy =
MIDINetworkConnectionPolicy.anyone
#endif

if client == 0 {
let result = MIDIClientCreateWithBlock(clientName, &client) {
guard $0.pointee.messageID == .msgSetupChanged else {
return
}
for l in self.listeners {
l.receivedMIDISetupChange()
}
}
if result != noErr {
AKLog("Error creating MIDI client : \(result)")
}
if client == 0 {
let result = MIDIClientCreateWithBlock(clientName, &client) {
guard $0.pointee.messageID == .msgSetupChanged else {
return
}
for l in self.listeners {
l.receivedMIDISetupChange()
}
}
if result != noErr {
AKLog("Error creating MIDI client : \(result)")
}
}

// MARK: - Virtual MIDI

/// Create set of virtual MIDI ports
open func createVirtualPorts(_ uniqueID: Int32 = 2_000_000, name: String? = nil) {
destroyVirtualPorts()
createVirtualInputPort(uniqueID, name: name)
createVirtualOutputPort(uniqueID, name: name)
}

// MARK: - Virtual MIDI

/// Create set of virtual MIDI ports
open func createVirtualPorts(_ uniqueID: Int32 = 2_000_000, name: String? = nil) {
destroyVirtualPorts()
createVirtualInputPort(uniqueID, name: name)
createVirtualOutputPort(uniqueID, name: name)
}

/// Create a virtual MIDI input port
open func createVirtualInputPort(_ uniqueID: Int32 = 2_000_000, name: String? = nil) {
destroyVirtualInputPort()
let virtualPortname = ((name != nil) ? name! : String(clientName))

let result = MIDIDestinationCreateWithBlock(client,
virtualPortname as CFString,
&virtualInput) { packetList, _ in
for packet in packetList.pointee {
// a Core MIDI packet may contain multiple MIDI events
for event in packet {
self.handleMIDIMessage(event)
}
}
}

/// Create a virtual MIDI input port
open func createVirtualInputPort(_ uniqueID: Int32 = 2_000_000, name: String? = nil) {
destroyVirtualPorts()
let virtualPortname = ((name != nil) ? name! : String(clientName))

let result = MIDIDestinationCreateWithBlock(client,
virtualPortname as CFString,
&virtualInput) { packetList, _ in
for packet in packetList.pointee {
// a Core MIDI packet may contain multiple MIDI events
for event in packet {
self.handleMIDIMessage(event)
}
}
}

if result == noErr {
MIDIObjectSetIntegerProperty(virtualInput, kMIDIPropertyUniqueID, uniqueID)
} else {
AKLog("Error creatervirt dest: \(virtualPortname) -- \(virtualInput)")
}
if result == noErr {
MIDIObjectSetIntegerProperty(virtualInput, kMIDIPropertyUniqueID, uniqueID)
} else {
AKLog("Error creatervirt dest: \(virtualPortname) -- \(virtualInput)")
}

/// Create a virtual MIDI output port
open func createVirtualOutputPort(_ uniqueID: Int32 = 2_000_000, name: String? = nil) {
let virtualPortname = ((name != nil) ? name! : String(clientName))

let result = MIDISourceCreate(client, virtualPortname as CFString, &virtualOutput)
if result == noErr {
MIDIObjectSetIntegerProperty(virtualInput, kMIDIPropertyUniqueID, uniqueID + 1)
} else {
AKLog("Error creating virtual source: \(virtualPortname) -- \(virtualOutput)")
}
}

/// Create a virtual MIDI output port
open func createVirtualOutputPort(_ uniqueID: Int32 = 2_000_000, name: String? = nil) {
destroyVirtualOutputPort()
let virtualPortname = ((name != nil) ? name! : String(clientName))

let result = MIDISourceCreate(client, virtualPortname as CFString, &virtualOutput)
if result == noErr {
MIDIObjectSetIntegerProperty(virtualInput, kMIDIPropertyUniqueID, uniqueID + 1)
} else {
AKLog("Error creating virtual source: \(virtualPortname) -- \(virtualOutput)")
}

/// Discard all virtual ports
open func destroyVirtualPorts() {
if virtualInput != 0 {
MIDIEndpointDispose(virtualInput)
virtualInput = 0
}

if virtualOutput != 0 {
MIDIEndpointDispose(virtualOutput)
virtualOutput = 0
}
}

/// Discard all virtual ports
open func destroyVirtualPorts() {
destroyVirtualInputPort()
destroyVirtualOutputPort()
}

/// Closes the virtual input port, if created one already.
///
/// - Returns: Returns true if virtual input closed.
@discardableResult open func destroyVirtualInputPort() -> Bool {
if virtualInput != 0 {
if MIDIEndpointDispose(virtualInput) == noErr {
virtualInput = 0
return true
}
}
return false
}

/// Closes the virtual output port, if created one already.
///
/// - Returns: Returns true if virtual output closed.
@discardableResult open func destroyVirtualOutputPort() -> Bool {
if virtualOutput != 0 {
if MIDIEndpointDispose(virtualOutput) == noErr {
virtualOutput = 0
return true
}
}
return false
}
}
7 changes: 5 additions & 2 deletions AudioKit/Common/MIDI/AKMIDIInstrument.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ open class AKMIDIInstrument: AKPolyphonicNode, AKMIDIListener {
open var name = "AKMIDIInstrument"

/// Initialize the MIDI Instrument
public override init() {
///
/// - Parameter midiOutputName: Name of the instrument's MIDI output
///
public init(midiOutputName: String? = nil) {
super.init()
enableMIDI()
enableMIDI(name: midiOutputName ?? "Unnamed")
}

/// Enable MIDI input from a given MIDI client
Expand Down
5 changes: 3 additions & 2 deletions AudioKit/Common/MIDI/AKMIDINode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ open class AKMIDINode: AKNode, AKMIDIListener {
/// Initialize the MIDI node
///
/// - parameter node: A polyphonic node that will be triggered via MIDI
/// - parameter midiOutputName: Name of the node's MIDI output
///
@objc public init(node: AKPolyphonicNode) {
@objc public init(node: AKPolyphonicNode, midiOutputName: String? = nil) {
internalNode = node
super.init()
avAudioNode = internalNode.avAudioNode
enableMIDI()
enableMIDI(name: midiOutputName ?? "Unnamed")
}

/// Enable MIDI input from a given MIDI client
Expand Down
7 changes: 5 additions & 2 deletions AudioKit/Common/MIDI/AKMIDISampler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ open class AKMIDISampler: AKSampler {
open var name = "MIDI Sampler"

/// Initialize the MIDI Sampler
public override init() {
///
/// - Parameter midiOutputName: Name of the instrument's MIDI output
///
public init(midiOutputName: String? = nil) {
super.init()
enableMIDI()
enableMIDI(name: midiOutputName ?? name)
}

/// Enable MIDI input from a given MIDI client
Expand Down
2 changes: 1 addition & 1 deletion AudioKit/Common/MIDI/Sequencer/AKMusicTrack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ open class AKMusicTrack {

// MARK: - Initialization

@objc public init(name: String = "unnamed") {
@objc public init(name: String = "Unnamed") {
self.name = name
MusicSequenceNewTrack(sequencer.sequence!, &internalMusicTrack)
MusicSequenceNewTrack(sequencer.sequence!, &initMusicTrack)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ open class AKSynthKick: AKMIDIInstrument {
var filter: AKMoogLadder

/// Create the synth kick voice
public override init() {
///
/// - Parameter midiOutputName: Name of the instrument's MIDI output.
public override init(midiOutputName: String? = nil) {

generator = AKOperationGenerator { _ in
let frequency = AKOperation.lineSegment(trigger: AKOperation.trigger, start: 120, end: 40, duration: 0.03)
Expand All @@ -25,7 +27,7 @@ open class AKSynthKick: AKMIDIInstrument {
filter.cutoffFrequency = 666
filter.resonance = 0.00

super.init()
super.init(midiOutputName: midiOutputName)
avAudioNode = filter.avAudioNode
generator.start()
}
Expand Down