Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Swan's Quest, Chapter 4
// This code is for the Advice from the Lizard main.swift file
// It uses the playInstrument function to play an A4 with an electric guitar.
func performance(owner: Assessable) {
// TODO: Play an instrument using the calls the Lizard told you about
playInstrument(.electricGuitar, note: MIDINotes.a4)
// Let the Lizard know when you're done
owner.endPerformance()
}
// Touch "Run My Code" to continue your quest...
// The Lizard has decoded the sheet music, in case you need it:
let bassNotes: [MIDINotes] = [
.g3, .rest, .g2, .rest,
.c3, .g3, .c4, .rest,
.b4, .rest, .as4, .rest,
.f2, .rest, .f3, .e3,
.d3, .rest, .g2, .rest,
.c4, .rest, .rest, .rest,
.a3, .rest, .fs3, .rest,
.f3, .d3, .c4, .a3
]
let trebleNotes: [MIDINotes] = [
.rest, .b3, .c4, .d4,
.e4, .rest, .rest, .d4,
.e4, .a4, .g4, .e4,
.d4, .c4, .a3, .rest,
.rest, .c4, .e4, .f4,
.g4, .rest, .rest, .a4,
.g4, .e4, .c4, .e4,
.d4, .rest, .rest, .rest
]
func performance(owner: Assessable) {
let numberOfBeats = 32 // two bars of 4/4
let duration = 16.0 // seconds
var bass = Track(instrument: .bassGuitar, length: numberOfBeats)
var piano = Track(instrument: .piano, length: numberOfBeats)
bass.notes = bassNotes
piano.notes = trebleNotes
let tracks = [bass, piano]
let interval = duration / Double(numberOfBeats)
var index = 0
Timer.scheduledTimer(withTimeInterval: interval, repeats: true, block: { timer in
for track in tracks {
playInstrument(track.instrument, note: track.note(for: index))
}
if index + 1 < numberOfBeats {
index = index + 1
}
else {
index = 0
// Don't forget to call endPerformance() after you played through the song once.
owner.endPerformance()
}
})
}
//
// Sequencer.swift
//
// Copyright © 2020 Apple Inc. All rights reserved.
//
public protocol MIDINoteProtocol {
/// note as an 8-bit MIDI code
var midiCode: UInt8 { get }
}
public protocol TrackProtocol {
associatedtype NoteType : MIDINoteProtocol
/// The kind of instrument that the track sequences
var instrument: Instrument.Kind { get }
/// Number of beats contained in the sequence
var length: Int { get }
/// MIDI code for the sequence frame
func note(for frame: Int) -> NoteType
}
// The Wizard has provided a MIDI Notes implementation for you.
public enum MIDINotes : UInt8, MIDINoteProtocol {
case rest = 0
case c1 = 24
case cs1 = 25
case d1 = 26
case ds1 = 27
case e1 = 28
case f1 = 29
case fs1 = 30
case g1 = 31
case gs1 = 32
case a1 = 33
case as1 = 34
case b1 = 35
case c2 = 36
case cs2 = 37
case d2 = 38
case ds2 = 39
case e2 = 40
case f2 = 41
case fs2 = 42
case g2 = 43
case gs2 = 44
case a2 = 45
case as2 = 46
case b2 = 47
case c3 = 48
case cs3 = 49
case d3 = 50
case ds3 = 51
case e3 = 52
case f3 = 53
case fs3 = 54
case g3 = 55
case gs3 = 56
case a3 = 57
case as3 = 58
case b3 = 59
case c4 = 60
case cs4 = 61
case d4 = 62
case ds4 = 63
case e4 = 64
case f4 = 65
case fs4 = 66
case g4 = 67
case gs4 = 68
case a4 = 69
case as4 = 70
case b4 = 71
case c5 = 72
case cs5 = 73
case d5 = 74
case ds5 = 75
case e5 = 76
case f5 = 77
case fs5 = 78
case g5 = 79
case gs5 = 80
case a5 = 81
case as5 = 82
case b5 = 83
/// note as an 8-bit MIDI code
public var midiCode: UInt8 {
return self.rawValue
}
}
// This is the big addition, the definition of a Track struct.
public struct Track : TrackProtocol {
public var instrument: Instrument.Kind
public var length: Int
public var notes: [MIDINotes]? = nil
public init(instrument: Instrument.Kind, length: Int) {
self.instrument = instrument
self.length = length
}
public func note(for frame: Int) -> MIDINotes {
guard let n = notes, frame < n.count else {
return .rest
}
return n[frame]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.