I had some issues with the code, so I ended up creating an initializer instead of relying on automatic-synthesis. Also, I don't quite understand why all functions needed to be public... possibly because only public functions can be called from other pages?
Here's my solution for the performance:
Code Block public class Track : TrackProtocol { public let instrument: Instrument.Kind public let length: Int public let notes: [MIDINotes] public init(instrument: Instrument.Kind, length: Int, notes: [MIDINotes]) { self.instrument = instrument self.length = length self.notes = notes } public func note(for frame: Int) -> MIDINotes { guard frame < notes.count else { return .rest } return notes[frame] } }
Here's my solution for the performance:
Code Block func performance(owner: Assessable) { let numberOfBeats = 32 // two bars of 4/4 let duration = 16.0 // seconds var bass = Track(instrument: .bassGuitar, length: numberOfBeats, notes: bassNotes) var piano = Track(instrument: .piano, length: numberOfBeats, notes: trebleNotes) let tracks = [bass, piano] let interval = duration / Double(numberOfBeats) var index = 0 Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { (timer) in guard index < numberOfBeats else { owner.endPerformance() timer.invalidate() return } for track in tracks { playInstrument(track.instrument, note: track.note(for: index)) } index += 1 } }