Skip to content

Instantly share code, notes, and snippets.

@davidfloegel
Last active July 13, 2020 18:51
Show Gist options
  • Save davidfloegel/056b870eb89416da267882172947af59 to your computer and use it in GitHub Desktop.
Save davidfloegel/056b870eb89416da267882172947af59 to your computer and use it in GitHub Desktop.
New Midi Player
//
// MidiPlayer.swift
// harmonic
//
// Created by David Floegel on 03/07/2020.
//
import Foundation
import AudioKit
@objc(MidiPlayer)
class MidiPlayer: NSObject {
var sequencer = AKSequencer()
var sampler = AKAppleSampler()
var noteNumbers: [NSNumber] = []
override init() {
super.init()
self.setupSynth()
}
func setupSynth() {
try? sampler.loadSoundFont("UprightPiano", preset: 0, bank: 0)
sequencer = AKSequencer(targetNode: sampler)
let _ = sequencer.addTrack(for: sampler)
try? AudioKit.stop()
AudioKit.output = sampler
try? AudioKit.start()
}
@objc
func playNotation(_ bpm: NSNumber, midiNotes: [NSDictionary]) {
sequencer.tracks[0].clear()
for (i, note) in midiNotes.enumerated() {
sequencer.tracks[0].add(
noteNumber: UInt8(truncating: note["midiValue"] as! NSNumber),
velocity: 100,
position: Double(i),
duration: Double(truncating: note["duration"] as! NSNumber) / 1000
)
noteNumbers.append(note["midiValue"] as! NSNumber)
}
// TODO for some reason this doesn't correspond to the total of note durations
// it's also very unclear whether this is milliseconds, or seconds, or whatever.
sequencer.length = 600 // sequencer.tracks[0].length
sequencer.tempo = Double(truncating: bpm)
sequencer.loopEnabled = false
sequencer.playFromStart()
}
@objc
func stopNotation() {
sequencer.tracks[0].stop()
sequencer.stop()
for (note) in self.noteNumbers {
try? self.sampler.stop(noteNumber: UInt8(truncating: note), channel: 0)
}
}
@objc
static func requiresMainQueueSetup() -> Bool {
return true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment