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

added new pitch and notes helper function #24

Merged
merged 3 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
)
}
}
Loading