SwiftUI Drum Sequencer

Sometimes people do their best work under constraints. I remember getting up at four one morning in late June of 2022. I hadn't been able to sleep the whole night because of back pain, and I felt extremely unwell. It took me 30 minutes to sit up and take one sip of coffee.

As it turns out, I tested positive for COVID-19 and immediately had more time and less space than I knew what to do with. This was the perfect time to make another tutorial with the Swift Playgrounds App!

A drum sequencer combines the best of both worlds of sequencing and sampling, allowing one to create funky 16th-note-pattern groves made up of unique sounds. An example is the Akai MPC. Building off an earlier tutorial of making drum pads using the Playgrounds App and MIDI Network Sessions in AudioKit—I was able to modify the UI a bit and make it a sequencer.

What's nice about doing this in SwiftUI is how I could use publishers connected to AudioKit's MIDICallbackInstrument to have the UI respond to musical (note) events. I updated the active button number of each pad through the publisher and used the active state to light up the button in the View.

Tap to view Swift Code (Audio Observable Object)

import SwiftUI
import AudioKit

class Audio: ObservableObject{
	private var engine = AudioEngine()
	private var sequencer = AppleSequencer()
	private var sampler = MIDISampler()
	private var midiCallback = MIDICallbackInstrument()
	private var callback: MIDICallback!
	// Updates the state of the button in the View class
	@Published var activeButtonNum = -1
	init() {
		callback = { status, note, velocity in
			if status == 144 { // Note on event
				let beat = self.sequencer.currentRelativePosition.beats * 4
				let pos = Int(beat)
				// Publish for button on color
				self.activeButtonNum = pos
				self.sampler.play(noteNumber: note, velocity: velocity, channel: 0)
			} else if status == 128 { // Note off event
				// Publish for button off color
				self.activeButtonNum = -1
				self.sampler.stop(noteNumber: note, channel: 0)
			}
		}
	}
}
							

The full tutorial can be found here: https://www.youtube.com/watch?v=XcBlWFLuuP4.