8#include "maiacore/interval.h"
9#include "maiacore/key.h"
10#include "maiacore/note.h"
15 bool wasEnharmonized =
false;
16 int enharmonicDiatonicDistance = 0;
18 NoteData() : note(
Note(
"rest")), wasEnharmonized(false), enharmonicDiatonicDistance(0) {}
20 NoteData(
const Note& _originalNotes,
const bool _wasEnhar,
const int _enharDiat)
21 : note(_originalNotes),
22 wasEnharmonized(_wasEnhar),
23 enharmonicDiatonicDistance(_enharDiat){};
25 friend bool operator<(
const NoteData& lhs,
const NoteData& rhs) {
26 return lhs.note.getMidiNumber() < rhs.note.getMidiNumber();
33typedef std::vector<NoteData> NoteDataHeap;
35typedef std::tuple<NoteDataHeap, float> HeapData;
37bool operator<(
const HeapData& a,
const HeapData& b);
39void printHeap(
const NoteDataHeap& heap);
41void sortHeapOctaves(NoteDataHeap* heap);
59typedef std::tuple<int, float, std::string, int, float, int, float, std::string, int, float, float,
61 SetharesDissonanceTableRow;
62typedef std::vector<SetharesDissonanceTableRow> SetharesDissonanceTable;
75 std::vector<Note> _originalNotes;
80 std::vector<Note> _openStack;
85 std::vector<Note> _closeStack;
90 std::vector<HeapData> _stackedHeaps;
95 std::vector<Interval> _closeStackintervals;
105 bool _isStackedInThirds;
110 void computeIntervals();
116 void stackInThirds(
const bool enharmonyNotes =
false);
123 HeapData stackInThirdsTemplateMatch(
const NoteDataHeap& heap)
const;
129 std::vector<NoteDataHeap> computeEnharmonicUnitsGroups()
const;
136 std::vector<NoteDataHeap> computeEnharmonicHeaps(
const std::vector<NoteDataHeap>& heaps)
const;
143 std::vector<NoteDataHeap> removeHeapsWithDuplicatedPitchSteps(
144 std::vector<NoteDataHeap>& heaps)
const;
151 std::vector<NoteDataHeap> computeAllHeapInversions(NoteDataHeap& heap)
const;
158 std::vector<NoteDataHeap> filterTertianHeapsOnly(
const std::vector<NoteDataHeap>& heaps)
const;
165 std::vector<Note> computeBestOpenStackHeap(std::vector<HeapData>& stackedHeaps);
171 void computeCloseStack(
const std::vector<Note>& openStack);
179 template <
typename T>
180 float computeStandardDeviation(
const std::vector<T>& v)
const {
181 const float sum = std::accumulate(v.begin(), v.end(), 0);
182 const float mean = sum / v.size();
184 std::vector<float> diff(v.size());
185 std::transform(v.begin(), v.end(), diff.begin(), [mean](
double x) { return x - mean; });
186 const float sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
187 const float stdev = std::sqrt(sq_sum / v.size());
205 explicit Chord(
const std::vector<Note>& notes,
const RhythmFigure rhythmFigure = RhythmFigure::QUARTER);
212 explicit Chord(
const std::vector<std::string>& pitches,
const RhythmFigure rhythmFigure = RhythmFigure::QUARTER);
265 void setDuration(
const float quarterDuration,
const int divisionsPerQuarterNote = 256);
419 const std::string& higherBoundPitch = {})
const;
1123 std::vector<Interval>
getIntervals(
const bool firstNoteAsReference =
false)
const;
1314 const int numPartialsPerNote = 6,
1315 const std::function<std::vector<float>(std::vector<float>)> amplCallback =
nullptr,
1316 const float partialsDecayExpRate = 0.88f)
const;
1368 const int numPartials = 6,
const bool useMinModel =
true,
1369 const std::function<std::vector<float>(std::vector<float>)> amplCallback =
nullptr,
1370 const float partialsDecayExpRate = 0.88f)
const;
1383 const int numPartialsPerNote = 6,
const bool useMinModel =
true,
1384 const std::function<std::vector<float>(std::vector<float>)> amplCallback =
nullptr,
1385 const float partialsDecayExpRate = 0.88f,
1386 const std::function<
float(std::vector<float>)> dissCallback =
nullptr)
const;
1434 size_t sizeA = this->
size();
1435 size_t sizeB = otherChord.
size();
1437 if (sizeA != sizeB) {
1441 for (
size_t i = 0; i < sizeA; i++) {
1442 if (_originalNotes[i] != otherChord.
getNote(i)) {
1470 size_t sizeA = this->
size();
1471 size_t sizeB = otherChord.
size();
1473 if (sizeA != sizeB) {
1477 for (
size_t i = 0; i < sizeA; i++) {
1478 if (_originalNotes[i] != otherChord.
getNote(i)) {
1518 Chord operator+(
const Chord& otherChord)
const {
1521 const size_t sizeChord = otherChord.
size();
1522 for (
size_t i = 0; i < sizeChord; i++) {
1533 std::vector<Note>::iterator
begin() {
return _originalNotes.begin(); }
1539 std::vector<Note>::iterator
end() {
return _originalNotes.end(); }
Represents a musical chord.
Definition: chord.h:70
bool haveSixth(const bool useEnharmony=false) const
Checks if the chord contains any sixth interval (major or minor) between its notes.
bool isMajorChord()
Determines if the chord is a major triad.
int getMeanMidiValue() const
Calculates the arithmetic mean of the MIDI numbers of all notes in the chord.
bool haveAnyOctaveAugmentedOctave(const bool useEnharmony=false) const
Checks if the chord contains an augmented octave interval between any two notes, ignoring octave diff...
bool haveMinorInterval(const bool useEnharmony=false) const
Check if the chord contains at least one minor interval.
bool haveFifth(const bool useEnharmony=false) const
Checks if the chord contains any fifth interval (perfect, augmented, or diminished) between its notes...
bool haveMinorSecond(const bool useEnharmony=false)
Checks if the chord contains a minor second interval (e.g., C and Db).
bool haveAnyOctaveDiminishedOctave(const bool useEnharmony=false) const
Checks if the chord contains a diminished octave interval between any two notes, ignoring octave diff...
bool haveMajorInterval(const bool useEnharmony=false) const
Check if the chord contains at least one major interval.
float getMeanFrequency(const float freqA4=440.0f) const
Calculates the arithmetic mean of the frequencies of all notes in the chord.
void setDuration(const Duration &duration)
Set the duration for all notes in the chord.
bool isTonal(std::function< bool(const Chord &chord)> model=nullptr)
Determines if the chord is tonal according to a given model or default rules.
std::vector< Interval > getOpenStackIntervals(const bool firstNoteAsReference=false)
Returns the intervals between notes in the open stack as Interval objects.
std::string getQuality()
Returns a string describing the chord quality (e.g., "major", "minor", "diminished",...
void removeTopNote()
Remove the top (last) note from the chord.
Chord getOpenStackChord(const bool enharmonyNotes=false)
Returns a Chord object representing the open stack (stacked in thirds).
bool haveAnyOctavePerfectFifth(const bool useEnharmony=false) const
Checks if the chord contains a perfect fifth interval between any two notes, ignoring octave differen...
bool haveOctave(const bool useEnharmony=false) const
Checks if the chord contains any octave interval (perfect, augmented, or diminished) between its note...
std::vector< Interval > getIntervalsFromOriginalSortedNotes() const
Returns the intervals between the sorted original notes as Interval objects.
bool isSus()
Determines if the chord is a suspended chord (sus2 or sus4).
std::string getMeanPitch(const std::string &accType={}) const
Returns the pitch name corresponding to the mean MIDI value of the chord.
bool operator==(const Chord &otherChord) const
Equality operator comparing chords by pitch-space note ordering.
Definition: chord.h:1433
bool isDyad()
Determines if the chord is a dyad (contains exactly two distinct notes).
void addNote(const Note ¬e)
Add a Note object to the chord.
float getMeanOfExtremesFrequency(const float freqA4=440.0f) const
Calculates the mean frequency between the lowest and highest notes in the chord.
bool haveAnyOctaveMinorSeventh(const bool useEnharmony=false) const
Checks if the chord contains a minor seventh interval between any two notes, ignoring octave differen...
void printStack() const
Prints the pitches of all notes in the open stack to the log.
void insertNote(Note &insertNote, int positionNote=0)
Insert a note at a specific position in the chord.
bool haveAnyOctaveFifth() const
Checks if the chord contains a generic fifth interval (perfect, augmented, or diminished,...
std::vector< Note >::iterator end()
Returns an iterator to the end of the original notes vector.
Definition: chord.h:1539
std::vector< HeapData > getStackedHeaps(const bool enharmonyNotes=false)
Get all possible stacked heaps (enharmonic variants) for the chord.
const Note & getBassNote()
Get the bass note of the chord (lowest note).
bool haveSharpEleventh(const bool useEnharmony=false)
Checks if the chord contains a sharp eleventh interval (e.g., C and F# two octaves apart).
bool havePerfectEleventh(const bool useEnharmony=false)
Checks if the chord contains a perfect eleventh interval (e.g., C and F two octaves apart).
void toInversion(int inversionNumber)
Invert the chord by moving the lowest note up by one octave, repeated inversionNumber times.
void removeDuplicateNotes()
Remove duplicate notes (by pitch) from the chord.
std::vector< Note > getOpenStackNotes()
Returns the notes of the chord in open stack (stacked in thirds) order.
bool haveMajorSeventh(const bool useEnharmony=false)
Checks if the chord contains a major seventh interval (e.g., C and B).
bool isDominantSeventhChord()
Determines if the chord is a dominant seventh chord.
bool haveAnyOctaveDiminishedSeventh(const bool useEnharmony=false) const
Checks if the chord contains a diminished seventh interval between any two notes, ignoring octave dif...
Chord()
Construct an empty Chord object.
bool haveMinorNinth(const bool useEnharmony=false)
Checks if the chord contains a minor ninth interval (e.g., C and Db an octave apart).
void setDuration(const float quarterDuration, const int divisionsPerQuarterNote=256)
Set the duration for all notes in the chord using quarter note value.
bool havePerfectUnisson(const bool useEnharmony=false) const
Checks if the chord contains a perfect unison interval (e.g., two notes with the same pitch).
bool isInRootPosition()
Checks if the chord is in root position (lowest note is the root).
bool isDiminishedChord()
Determines if the chord is a diminished triad.
void info()
Prints detailed information about the chord, including name, size, notes, and stack.
bool haveAugmentedFourth(const bool useEnharmony=false)
Checks if the chord contains an augmented fourth interval (tritone, e.g., C and F#).
bool haveAnyOctaveSecond() const
Checks if the chord contains a generic second interval (major or minor, any octave).
bool haveDiminishedUnisson(const bool useEnharmony=false) const
Checks if the chord contains a diminished unison interval (e.g., C and Cb).
bool haveAnyOctaveThird() const
Checks if the chord contains a generic third interval (major or minor, any octave).
bool haveAnyOctaveFourth() const
Checks if the chord contains a generic fourth interval (perfect, augmented, or diminished,...
float getSetharesDissonance(const int numPartialsPerNote=6, const bool useMinModel=true, const std::function< std::vector< float >(std::vector< float >)> amplCallback=nullptr, const float partialsDecayExpRate=0.88f, const std::function< float(std::vector< float >)> dissCallback=nullptr) const
Calculates the total Sethares dissonance for the chord.
float getQuarterDuration() const
Get the shortest duration in quarter notes among all notes.
bool haveAnyOctaveMajorSeventh(const bool useEnharmony=false) const
Checks if the chord contains a major seventh interval between any two notes, ignoring octave differen...
bool isMinorChord()
Determines if the chord is a minor triad.
bool haveAnyOctaveMajorThird(const bool useEnharmony=false) const
Checks if the chord contains a major third interval between any two notes, ignoring octave difference...
bool haveMinorThird(const bool useEnharmony=false)
Checks if the chord contains a minor third interval (e.g., C and Eb).
bool operator!=(const Chord &otherChord) const
Inequality operator comparing chords by pitch-space note ordering.
Definition: chord.h:1469
bool haveAnyOctavePerfectFourth(const bool useEnharmony=false) const
Checks if the chord contains a perfect fourth interval between any two notes, ignoring octave differe...
std::vector< int > toCents() const
Returns a vector with the intervals (in cents) between each pair of adjacent notes in the chord.
bool haveAnyOctaveMajorSecond(const bool useEnharmony=false) const
Checks if the chord contains a major second interval between any two notes, ignoring octave differenc...
const Note & operator[](size_t index) const
Array subscript operator for read-only access to notes in original (unsorted) order.
Definition: chord.h:1399
Chord(const std::vector< std::string > &pitches, const RhythmFigure rhythmFigure=RhythmFigure::QUARTER)
Construct a Chord from a vector of pitch strings.
Chord(const std::vector< Note > ¬es, const RhythmFigure rhythmFigure=RhythmFigure::QUARTER)
Construct a Chord from a vector of Note objects.
Chord getCloseStackChord(const bool enharmonyNotes=false)
Returns a Chord object representing the closed stack (stacked in thirds, closed position).
bool havePerfectFifth(const bool useEnharmony=false)
Checks if the chord contains a perfect fifth interval (e.g., C and G).
bool haveAugmentedFifth(const bool useEnharmony=false)
Checks if the chord contains an augmented fifth interval (e.g., C and G#).
void addNote(const std::string &pitch)
Add a note to the chord by pitch string.
bool haveAnyOctaveSeventh() const
Checks if the chord contains a generic seventh interval (major, minor, or diminished,...
Note & operator[](size_t index)
Array subscript operator for mutable access to notes in original (unsorted) order.
Definition: chord.h:1411
void transposeStackOnly(const int semiTonesNumber)
Transpose only the stacked (open) version of the chord by a number of semitones.
bool haveNinth(const bool useEnharmony=false) const
Checks if the chord contains any ninth interval (major or minor) between its notes.
const Note & getNote(const int noteIndex) const
Get a const reference to a note at a given index.
bool isWholeDiminishedChord()
Determines if the chord is a fully diminished seventh chord.
std::vector< int > getMidiIntervals(const bool firstNoteAsReference=false) const
Returns the intervals between notes in the chord as MIDI semitone values.
float getCloseStackHarmonicComplexity(const bool useEnharmony=false)
Compute the harmonic complexity of the chord in closed position.
bool haveAnyOctavePerfectOctave(const bool useEnharmony=false) const
Checks if the chord contains a perfect octave interval between any two notes, ignoring octave differe...
int getDegree(const Key &key, bool enharmonyNotes=false)
Returns the scale degree of the chord's root in a given key.
float getHarmonicDensity(const std::string &lowerBoundPitch={}, const std::string &higherBoundPitch={}) const
Compute the harmonic density of the chord in a pitch range.
float getFrequencyStd(const float freqA4=440.0f) const
Calculates the standard deviation of the frequencies of all notes in the chord.
bool haveAnyOctaveMinorSecond(const bool useEnharmony=false) const
Checks if the chord contains a minor second interval between any two notes, ignoring octave differenc...
void removeNote(int noteIndex)
Remove a note at a specific index from the chord.
std::string getName()
Get the chord name using tonal analysis (e.g., "Cm7", "G7").
bool haveSecond(const bool useEnharmony=false) const
Checks if the chord contains any second interval (major or minor) between its notes.
bool haveAnyOctaveMinorSixth(const bool useEnharmony=false) const
Checks if the chord contains a minor sixth interval between any two notes, ignoring octave difference...
bool isAugmentedChord()
Determines if the chord is an augmented triad.
bool haveMajorSixth(const bool useEnharmony=false)
Checks if the chord contains a major sixth interval (e.g., C and A).
std::string getDuration() const
Get the shortest duration type among all notes in the chord.
std::string getMeanOfExtremesPitch(const std::string &accType={}) const
Returns the pitch name corresponding to the mean of the lowest and highest MIDI values in the chord.
bool havePerfectOctave(const bool useEnharmony=false)
Checks if the chord contains a perfect octave interval (e.g., C4 and C5).
bool haveAnyOctaveOctave() const
Checks if the chord contains a generic octave interval (perfect, augmented, or diminished,...
bool isSorted() const
Checks if the notes in the chord are sorted in ascending order by MIDI number.
bool haveMinorSeventh(const bool useEnharmony=false)
Checks if the chord contains a minor seventh interval (e.g., C and Bb).
bool haveSeventh(const bool useEnharmony=false) const
Checks if the chord contains any seventh interval (major, minor, or diminished) between its notes.
bool haveThird(const bool useEnharmony=false) const
Checks if the chord contains any third interval (major or minor) between its notes.
bool havePerfectFourth(const bool useEnharmony=false)
Checks if the chord contains a perfect fourth interval (e.g., C and F).
std::vector< Interval > getIntervals(const bool firstNoteAsReference=false) const
Returns the intervals between notes in the chord as Interval objects.
void clear()
Remove all notes from the chord, resetting its state.
bool haveMinorSixth(const bool useEnharmony=false)
Checks if the chord contains a minor sixth interval (e.g., C and Ab).
bool isHalfDiminishedChord()
Determines if the chord is a half-diminished seventh chord.
bool haveDiminishedSeventh(const bool useEnharmony=false)
Checks if the chord contains a diminished seventh interval (e.g., C and Bbb).
bool haveAnyOctaveMinorThird(const bool useEnharmony=false) const
Checks if the chord contains a minor third interval between any two notes, ignoring octave difference...
bool haveDiminishedFifth(const bool useEnharmony=false)
Checks if the chord contains a diminished fifth interval (tritone, e.g., C and Gb).
bool haveThirdteenth(const bool useEnharmony=false) const
Checks if the chord contains any thirteenth interval (major or minor) between its notes.
int size() const
Returns the number of notes in the chord.
bool haveAugmentedInterval(const bool useEnharmony=false) const
Check if the chord contains at least one augmented interval.
bool haveDiminishedOctave(const bool useEnharmony=false)
Checks if the chord contains a diminished octave interval (e.g., C and Cb an octave apart).
bool haveMajorNinth(const bool useEnharmony=false)
Checks if the chord contains a major ninth interval (e.g., C and D an octave apart).
void transpose(const int semiTonesNumber)
Transpose all notes in the chord by a number of semitones.
~Chord()
Destroy the Chord object and release resources.
std::vector< Note >::iterator begin()
Returns an iterator to the beginning of the original notes vector.
Definition: chord.h:1533
std::vector< Interval > getCloseStackIntervals(const bool firstNoteAsReference=false)
Returns the intervals between notes in the closed stack as Interval objects.
bool haveMajorThird(const bool useEnharmony=false)
Checks if the chord contains a major third interval (e.g., C and E).
const Note & getRoot()
Get the root note of the chord (after stacking in thirds).
bool haveAnyOctaveDiminishedFifth(const bool useEnharmony=false) const
Checks if the chord contains a diminished fifth interval between any two notes, ignoring octave diffe...
int getDurationTicks() const
Get the minimum duration in ticks among all notes.
float getMidiValueStd() const
Calculates the standard deviation of the MIDI numbers of all notes in the chord.
bool haveMinorThirdteenth(const bool useEnharmony=false)
Checks if the chord contains a minor thirteenth interval (e.g., C and Ab two octaves plus a sixth apa...
bool haveAnyOctaveMajorSixth(const bool useEnharmony=false) const
Checks if the chord contains a major sixth interval between any two notes, ignoring octave difference...
float getHarmonicDensity(int lowerBoundMIDI=-1, int higherBoundMIDI=-1) const
Compute the harmonic density of the chord in a MIDI range.
Note & getNote(int noteIndex)
Get a reference to a note at a given index.
bool haveEleventh(const bool useEnharmony=false) const
Checks if the chord contains any eleventh interval (perfect or sharp) between its notes.
bool haveMajorSecond(const bool useEnharmony=false)
Checks if the chord contains a major second interval (e.g., C and D).
std::pair< std::vector< float >, std::vector< float > > getHarmonicSpectrum(const int numPartialsPerNote=6, const std::function< std::vector< float >(std::vector< float >)> amplCallback=nullptr, const float partialsDecayExpRate=0.88f) const
Computes the combined harmonic spectrum of the chord by summing the spectra of all notes.
bool havePerfectInterval(const bool useEnharmony=false) const
Check if the chord contains at least one perfect interval.
const std::vector< Note > & getNotes() const
Get all notes in the chord (original order).
Chord getCloseChord(const bool enharmonyNotes=false)
Returns a Chord object representing the closed chord, with octaves adjusted to match the original.
std::string getRomanDegree(const Key &key, bool enharmonyNotes=false)
Returns the Roman numeral degree of the chord's root in a given key.
SetharesDissonanceTable getSetharesDyadsDissonanceValue(const int numPartials=6, const bool useMinModel=true, const std::function< std::vector< float >(std::vector< float >)> amplCallback=nullptr, const float partialsDecayExpRate=0.88f) const
Calculates the Sethares dissonance value for all dyads in the chord.
bool haveAnyOctaveAugmentedFourth(const bool useEnharmony=false) const
Checks if the chord contains an augmented fourth interval between any two notes, ignoring octave diff...
bool haveFourth(const bool useEnharmony=false) const
Checks if the chord contains any fourth interval (perfect, augmented, or diminished) between its note...
bool haveDiminishedInterval(const bool useEnharmony=false) const
Check if the chord contains at least one diminished interval.
int stackSize()
Returns the number of notes in the open stack (after stacking in thirds).
bool haveMajorThirdteenth(const bool useEnharmony=false)
Checks if the chord contains a major thirteenth interval (e.g., C and A two octaves plus a sixth apar...
bool haveAnyOctaveAugmentedFifth(const bool useEnharmony=false) const
Checks if the chord contains an augmented fifth interval between any two notes, ignoring octave diffe...
bool haveAnyOctaveSixth() const
Checks if the chord contains a generic sixth interval (major or minor, any octave).
bool haveAugmentedOctave(const bool useEnharmony=false)
Checks if the chord contains an augmented octave interval (e.g., C and C# an octave apart).
bool haveAugmentedUnisson(const bool useEnharmony=false) const
Checks if the chord contains an augmented unison interval (e.g., C and C#).
friend std::ostream & operator<<(std::ostream &os, const Chord &chord)
Output stream operator for Chord. Prints the chord as a list of pitches.
void sortNotes()
Sorts the notes in the chord in ascending order by MIDI number.
void print() const
Prints the pitches of all notes in the chord to the log.
int getMeanOfExtremesMidiValue() const
Calculates the mean MIDI value between the lowest and highest notes in the chord.
Represents the duration of a musical note, supporting multiple temporal representations.
Definition: duration.h:15
Represents a musical key signature (tonality), including circle of fifths and mode (major/minor).
Definition: key.h:11
Represents a musical note, including pitch, duration, articulation, and MusicXML-related attributes.
Definition: note.h:19