Skip to content

Lazy Chord loading on Key Type #23

@SebastianBoldt

Description

@SebastianBoldt

Description

From what I understand, when you initialize a Key, all the chords are generated inside the init.
However, if you want to create all the available keys for a certain note, the performance is pretty bad.

Here is a piece of code that illustrates this concept:

let newKeys = Scale.allCases.map {
    Key(root: note, scale: $0)
}

This code creates an array of keys for all the scales of a given note.

Proposed Solution

I would suggest implementing lazy chord creation. This would allow users to request the chords for a specific key only when needed, instead of generating them automatically during initialization. I believe that generating chords during initialization is unnecessarily complex and pollutes the domain of the Key Object, in addition, it also impacts the performance.

/// All the traditional triads representable root, third, and fifth from each note in the key
public func primaryTriads() ->[Chord] {
    let table = ChordTable.shared
    var primaryTriads: [Chord] = []
    let allowablePrimaryTriads: [ChordType] = [.majorTriad, .minorTriad, .diminishedTriad, .augmentedTriad]

    for (_, chord) in table.chords where chord.noteClassSet.isSubset(of: noteSet.noteClassSet) {
        if allowablePrimaryTriads.contains(chord.type) {
            primaryTriads.append(Chord(chord.root, type: chord.type))
        }
    }

    let primaryTriadsStartingWithC = primaryTriads.sorted(by: { $0.root.letter < $1.root.letter })
    let rootPosition = primaryTriadsStartingWithC.firstIndex(where: { $0.root == root }) ?? 0
    return Array(primaryTriadsStartingWithC.rotatingLeft(positions: rootPosition))
}

/// All chords that fit in the key
public func chords() -> [Chord] {
    let table = ChordTable.shared
    var chords: [Chord] = []
    for (_, chord) in table.chords where chord.noteClassSet.isSubset(of: noteSet.noteClassSet) {
        chords.append(Chord(chord.root, type: chord.type))
    }
    return chords
}

We could also think about adding a static global cache, similar to Chordtable, that stores a key and all the corresponding chords globally for faster access.

Wdyt?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions