Chapter 4

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?

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
    }
}

Chapter 4
 
 
Q