Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy Chord loading on Key Type #23

Open
SebastianBoldt opened this issue Jan 26, 2024 · 1 comment
Open

Lazy Chord loading on Key Type #23

SebastianBoldt opened this issue Jan 26, 2024 · 1 comment

Comments

@SebastianBoldt
Copy link
Contributor

SebastianBoldt commented Jan 26, 2024

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?

@aure
Copy link
Member

aure commented Jan 26, 2024

These sound like good solutions. Thank you for pushing on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants