MCC
Loading...
Searching...
No Matches
Letter.h
1#ifndef MCC_PITCH_LETTER_H
2#define MCC_PITCH_LETTER_H
3
4#include <MCC_BuildSettings.h>
5
6#include <stdint.h>
7
8#include <Foundation/Math/Arithmetic.h>
9
10namespace MCC {
11
22enum class Letter : uint8_t {
23 C = 0,
24 D = 1,
25 E = 2,
26 F = 3,
27 G = 4,
28 A = 5,
29 B = 6
30};
31
33constexpr uint8_t LetterCount = 7;
34
36namespace Detail {
37
38constexpr bool IsLetter(Letter letter) noexcept {
39 return static_cast<uint8_t>(letter) < LetterCount;
40}
41
42} // namespace Detail
44
49constexpr uint8_t DiatonicIndex(Letter letter) noexcept {
50 return Detail::IsLetter(letter) ? static_cast<uint8_t>(letter) : 0;
51}
52
58MCC_CONSTEXPR14 uint8_t NaturalSemitone(Letter letter) noexcept {
59 // Computed rather than tabled so AVR keeps no lookup table in RAM.
60 const int32_t index = DiatonicIndex(letter);
61 return static_cast<uint8_t>(index * 2 - (index >= 3 ? 1 : 0));
62}
63
69constexpr Letter MoveLetter(Letter letter, int32_t steps) noexcept {
70 return static_cast<Letter>(Foundation::Math::FloorMod(
71 DiatonicIndex(letter) + Foundation::Math::FloorMod(steps, LetterCount),
73}
74
75} // namespace MCC
76
77#endif // MCC_PITCH_LETTER_H
constexpr uint8_t LetterCount
Number of diatonic letters.
Definition Letter.h:33
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 uint8_t DiatonicIndex(Letter letter) noexcept
Returns the diatonic index of letter: C = 0 ... B = 6.
Definition Letter.h:49
Letter
Diatonic letter name.
Definition Letter.h:22
Music Composition Core public namespace.
Definition Version.h:4