MCC
Loading...
Searching...
No Matches
NoteName.h
1#ifndef MCC_PITCH_NOTE_NAME_H
2#define MCC_PITCH_NOTE_NAME_H
3
4#include <MCC_BuildSettings.h>
5
6#include <stdint.h>
7
8#include <Foundation/Math/Arithmetic.h>
9
10#include <MCC/Pitch/Accidental.h>
11#include <MCC/Pitch/PitchClass.h>
12#include <MCC/Pitch/Letter.h>
13
14namespace MCC {
15
29class NoteName {
30 static constexpr uint8_t InvalidLetter = 0xFF;
31
32 uint8_t _letter;
33 MCC::Accidental _accidental;
34
35public:
37 constexpr NoteName() noexcept
38 : _letter(InvalidLetter), _accidental(MCC::Accidental::Invalid()) {}
39
46 constexpr NoteName(MCC::Letter letter, MCC::Accidental accidental) noexcept
47 : _letter(IsSpellable(letter, accidental)
48 ? static_cast<uint8_t>(letter)
49 : InvalidLetter),
50 _accidental(IsSpellable(letter, accidental)
51 ? accidental
53
55 constexpr explicit NoteName(MCC::Letter letter) noexcept
57
59 static constexpr NoteName Invalid() noexcept { return NoteName(); }
60
62 constexpr bool IsValid() const noexcept { return _letter != InvalidLetter; }
63
68 constexpr MCC::Letter Letter() const noexcept {
69 return IsValid() ? static_cast<MCC::Letter>(_letter) : MCC::Letter::C;
70 }
71
76 constexpr MCC::Accidental Accidental() const noexcept { return _accidental; }
77
83 MCC_CONSTEXPR14 MCC::PitchClass PitchClass() const noexcept {
84 if (!IsValid()) {
86 }
87 return MCC::PitchClass(Foundation::Math::FloorMod(
88 NaturalSemitone(Letter()) + _accidental.Semitones(),
90 }
91
99 MCC_CONSTEXPR14 NoteName MovedDiatonically(int32_t steps) const noexcept {
100 if (!IsValid()) {
101 return Invalid();
102 }
103 return NoteName(MoveLetter(Letter(), steps), _accidental);
104 }
105
113 MCC_CONSTEXPR14 NoteName Altered(int32_t semitones) const noexcept {
114 if (!IsValid()) {
115 return Invalid();
116 }
117 return NoteName(Letter(), _accidental.Altered(semitones));
118 }
119
124 friend constexpr bool operator==(NoteName a, NoteName b) noexcept {
125 return a._letter == b._letter && a._accidental == b._accidental;
126 }
127
128 friend constexpr bool operator!=(NoteName a, NoteName b) noexcept {
129 return !(a == b);
130 }
131
136 friend constexpr bool operator<(NoteName a, NoteName b) noexcept {
137 return (a._letter != b._letter)
138 ? a._letter < b._letter
139 : a._accidental < b._accidental;
140 }
141
142 friend constexpr bool operator>(NoteName a, NoteName b) noexcept {
143 return b < a;
144 }
145
146 friend constexpr bool operator<=(NoteName a, NoteName b) noexcept {
147 return !(b < a);
148 }
149
150 friend constexpr bool operator>=(NoteName a, NoteName b) noexcept {
151 return !(a < b);
152 }
153
154private:
155 static constexpr bool IsSpellable(
156 MCC::Letter letter,
157 MCC::Accidental accidental
158 ) noexcept {
159 return Detail::IsLetter(letter) && accidental.IsValid();
160 }
161};
162
169constexpr bool IsEnharmonic(NoteName a, NoteName b) noexcept {
170 return a.IsValid() && b.IsValid() && a.PitchClass() == b.PitchClass();
171}
172
173} // namespace MCC
174
175#endif // MCC_PITCH_NOTE_NAME_H
Chromatic alteration of a letter, from -4 (quadruple flat) to +4 (quadruple sharp).
Definition Accidental.h:20
static constexpr Accidental Natural() noexcept
Returns the natural (0).
Definition Accidental.h:66
static constexpr Accidental Invalid() noexcept
Returns the invalid accidental.
Definition Accidental.h:51
Written note name: a letter plus an accidental, without octave.
Definition NoteName.h:29
constexpr NoteName(MCC::Letter letter, MCC::Accidental accidental) noexcept
Creates the note name spelled letter + accidental.
Definition NoteName.h:46
constexpr MCC::Accidental Accidental() const noexcept
Returns the written accidental; invalid for the invalid note name.
Definition NoteName.h:76
MCC_CONSTEXPR14 NoteName Altered(int32_t semitones) const noexcept
Keeps the letter and alters the accidental by semitones: C# altered by +1 is C##, never D.
Definition NoteName.h:113
friend constexpr bool operator==(NoteName a, NoteName b) noexcept
Written equality: letter and accidental (SPEC-EQ-1). All invalid note names are equal (SPEC-ERR-6).
Definition NoteName.h:124
constexpr MCC::Letter Letter() const noexcept
Returns the written letter, or Letter::C for the invalid note name (SPEC-ERR-7).
Definition NoteName.h:68
friend constexpr bool operator<(NoteName a, NoteName b) noexcept
Written order: letter, then accidental (SPEC-ORD-5). The invalid note name sorts last.
Definition NoteName.h:136
static constexpr NoteName Invalid() noexcept
Returns the invalid note name.
Definition NoteName.h:59
constexpr NoteName(MCC::Letter letter) noexcept
Creates the natural note name of letter.
Definition NoteName.h:55
constexpr bool IsValid() const noexcept
Returns true unless this is the invalid note name.
Definition NoteName.h:62
constexpr NoteName() noexcept
Creates the invalid note name (SPEC-ERR-2).
Definition NoteName.h:37
MCC_CONSTEXPR14 MCC::PitchClass PitchClass() const noexcept
Returns (NaturalSemitone(letter) + accidental) mod 12, always in [0, 11] (SPEC-ORD-4)....
Definition NoteName.h:83
MCC_CONSTEXPR14 NoteName MovedDiatonically(int32_t steps) const noexcept
Moves the letter by steps diatonic letters and keeps the written accidental: C# moved by 2 is E#,...
Definition NoteName.h:99
Pitch class 0-11 with spelling discarded (C = 0).
Definition PitchClass.h:21
static constexpr uint8_t Count
Number of pitch classes in an octave.
Definition PitchClass.h:24
static constexpr PitchClass Invalid() noexcept
Returns the invalid pitch class.
Definition PitchClass.h:49
MCC_CONSTEXPR14 uint8_t NaturalSemitone(Letter letter) noexcept
Returns the semitone offset of the natural letter above C: 0 2 4 5 7 9 11 (SPEC-ORD-1).
Definition Letter.h:58
constexpr Letter MoveLetter(Letter letter, int32_t steps) noexcept
Moves letter by steps diatonic letters, wrapping around the octave: MoveLetter(Letter::B,...
Definition Letter.h:69
constexpr bool IsEnharmonic(Pitch a, Pitch b) noexcept
Returns true when a and b are valid and have the same chromatic index (SPEC-EQ-2): B#3 and C4 are enh...
Definition Pitch.h:240
Letter
Diatonic letter name.
Definition Letter.h:22
Music Composition Core public namespace.
Definition Version.h:4