Skip to content

Commit

Permalink
added new pitch and notes helper function (#24)
Browse files Browse the repository at this point in the history
* added new pitch and notes helper function + unit-tests

* fixed PR remarks

* improved ordering
  • Loading branch information
SebastianBoldt authored Jan 26, 2024
1 parent 3879e73 commit 27e8c54
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 4 deletions.
26 changes: 25 additions & 1 deletion Sources/Tonic/Chord.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ extension Chord: CustomStringConvertible {
}

extension Chord {

public static func getRankedChords(from notes: [Note]) -> [Chord] {
let potentialChords = ChordTable.shared.getAllChordsForNoteSet(NoteSet(notes: notes))
let orderedNotes = notes.sorted(by: { f, s in f.noteNumber < s.noteNumber })
Expand All @@ -142,3 +141,28 @@ extension Chord {
return sortedRanks.map({ $0.1 })
}
}

extension Chord {
/// Returns all Pitches of a certain chord, taking into account the inversion, starting at the given octave
/// - Parameter octave: octave of the chord for inversion 0
/// - Returns: All pitches in that Chord
public func pitches(octave: Int) -> [Pitch] {
return notes(octave: octave).map { $0.pitch }
}

/// Returns all Notes of a certain chord, taking into account the inversion, starting at the given octave
/// - Parameter octave: initial octave of the chord for inversion 0
/// - Returns: All notes in that chord
public func notes(octave: Int) -> [Note] {
var notes = noteClasses.map {
Note($0.letter, accidental: $0.accidental, octave: octave)
}

for step in 0..<inversion {
let index = step % notes.count
notes[index].octave += 1
}

return notes.sorted()
}
}
83 changes: 80 additions & 3 deletions Tests/TonicTests/ChordTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,85 @@ class ChordTests: XCTestCase {
// should return the same array, in reversed order
XCTAssertEqual(gChords.map { $0.description }, ["Gsus4", "Csus2"])
XCTAssertEqual(cChords.map { $0.description }, ["Csus2", "Gsus4"])



}

func testPitchesWithNoInversion() {
// Arrange
let chord = Chord(.C, type: .majorTriad, inversion: 0)
let expectedPitches = [
Note(.C, octave: 0),
Note(.E, octave: 0),
Note(.G, octave: 0)
].map { $0.pitch }

// Act
let pitches = chord.pitches(octave: 0)

// Assert
XCTAssertEqual(
pitches,
expectedPitches,
"Pitches should match expected pitches for no inversion"
)
}

func testPitchesWithInversion() {
// Arrange
let chord = Chord(.C, type: .majorTriad, inversion: 1)
let expectedPitches = [
Note(.E, octave: 4),
Note(.G, octave: 4),
Note(.C, octave: 5)
].map { $0.pitch }

// Act
let pitches = chord.pitches(octave: 4)

// Assert
XCTAssertEqual(
pitches,
expectedPitches,
"Pitches should match expected pitches for 1st inversion"
)
}

func testNotesWithNoInversion() {
// Arrange
let chord = Chord(.C, type: .majorTriad, inversion: 0)
let expectedNotes = [
Note(.C, octave: 4),
Note(.E, octave: 4),
Note(.G, octave: 4)
]

// Act
let notes = chord.notes(octave: 4)

// Assert
XCTAssertEqual(
notes,
expectedNotes,
"Notes should match expected notes for no inversion"
)
}

func testNotesWithInversion() {
// Arrange
let chord = Chord(.C, type: .majorTriad, inversion: 1)
let expectedNotes = [
Note(.E, octave: 4),
Note(.G, octave: 4),
Note(.C, octave: 5)
]

// Act
let notes = chord.notes(octave: 4)

// Assert
XCTAssertEqual(
notes,
expectedNotes,
"Notes should match expected notes for 1st inversion"
)
}
}

0 comments on commit 27e8c54

Please sign in to comment.