MIDIPianoSampler
An easy to use CoreMIDI and AudioSampler library.
Usage
Create a MIDIController
which handles MIDI devices and receives MIDI messages.
// Create the MIDISession.
let controller = MIDIController()
// Retreive the devices connected to the system.
let devices = controller.inputDevices
// Set a selected device for the controller as input.
controller.set(device: selectedDevice)
Create an AudioSampler
which receives the MIDI messages and synthetizes them.
// soundbankURL can be a URL to an sf2 soundbank file.
let sampler = try AudioSampler(soundbank: soundbankURL)
// Attach a MIDIService to the sampler.
sampler.attach(controller)
// Connect the sampler.node to an AVAudioEngine.
audioEngine.attach(sampler.node)
audioEngine.connect(sampler.node, to: audioEngine.mainMixerNode, format: nil)
try engine.start()
Advanced
Decoding MIDIEvent
The AudioSampler
handles noteOn noteOff and sustain pedal messages.
enum MIDIEvent {
case noteOn(note: Note, velocity: Velocity)
case noteOff(note: Note)
case sustain(Bool)
}
The conversion from CoreMIDI.MIDIEventPacket
to MIDIEvent
happanes in a MIDICodingStrategy
implementation.
protocol MIDICodingStrategy {
var verion: MIDIProtocolID { get }
func decode(event: MIDIEventPacket) -> MIDIEvent?
}
Confirming to this protocol you can create your own custom MIDIEvent conversion for your own MIDI controller.
let controller = MIDIController(decoder: CustomAKAICoder())
Or you can use the default MIDI 1.0 coder and add a fallback operator for unhandled MIDI events.
let controller = MIDIController(decoder: .default_v1.fallback(PadsDecoder()))