KamaroY
KamaroY

Reputation: 35

How to use AudioKit Sequencer to configure time signature for a metronome?

Thanks for AudioKit!

I'm a beginner in Swift and AudioKit, so this may be an easy question:

I want to build a metronome app. From the example in Audiokit's new CookBook and the old AKMetronome(), I can see how to build a simple metronome using AudioKit. But I don't know how to play beats with compound time signatures (3/8, 7/8, etc.). Both examples here use a time signature with 4 as a fixed bottom number and the top number can be changed (i.e. we can have 1/4, 3/4, 6/4 but not 3/8, 6/8).

Is there a way to change the bottom number?

Link for AKMetronome: https://audiokit.io/docs/Classes/AKMetronome.html#/s:8AudioKit11AKMetronomeC5resetyyF

AudioKit Cookbook's Shaker Metronome: https://github.com/AudioKit/Cookbook/blob/main/Cookbook/Cookbook/Recipes/Shaker.swift

Upvotes: 1

Views: 724

Answers (1)

vindur
vindur

Reputation: 436

I made some changes to the Shaker Metronome's code to illustrate how you could create a metronome that plays different time signatures such as 6/8, 5/8, 7/8, and so on.

First I added some information to the ShakerMetronomeData structure:

enum Figure: Double {
    case quarter = 1.0
    case eighth = 0.5
}

struct ShakerMetronomeData {
    var isPlaying = false
    var tempo: BPM = 120
    var timeSignatureTop: Int = 4
    var downbeatNoteNumber = MIDINoteNumber(6)
    var beatNoteNumber = MIDINoteNumber(10)
    var beatNoteVelocity = 100.0
    var currentBeat = 0
    var figure: Figure = .quarter
    var pattern: [Int] = [4]
}

Then, the part of the updateSequences function that plays the metronome clicks would become:

func updateSequences() {
    var track = sequencer.tracks.first!

    track.length = Double(data.timeSignatureTop)

    track.clear()
    var startTime: Double = 0.0
    for numberOfBeatsInGroup in data.pattern {
        track.sequence.add(noteNumber: data.downbeatNoteNumber, position: 0.0, duration: 0.4)
        startTime += data.figure.rawValue
        let vel = MIDIVelocity(Int(data.beatNoteVelocity))
        for beat in 1 ..< numberOfBeatsInGroup {
            track.sequence.add(noteNumber: data.beatNoteNumber, velocity: vel, position: startTime, duration: 0.1)
            startTime += data.figure.rawValue
        }
    }
}

These would be the values of the figure and pattern members of the structure for different time signatures:

/*
    Time signature  Figure    Pattern
    4/4             .quarter  [4]
    3/4             .quarter  [3]
    6/8             .eighth   [3,3]
    5/8             .eighth   [5]
    7/8             .eighth   [2,2,3]
*/

Please note I haven't tested this code, but it illustrates how you could play beats with a compound time signature.

This could be improved by having three different sounds instead of two: one for the start of each bar, one for the beginning of each group, and one for the downbeats.

Upvotes: 1

Related Questions