1#ifndef MCC_CHORD_CHORD_PATTERN_H
2#define MCC_CHORD_CHORD_PATTERN_H
4#include <MCC_BuildSettings.h>
8#include <MCC/Interval/Interval.h>
14struct ChordPatternStorage;
39 friend struct Detail::ChordPatternStorage;
44 constexpr ChordPattern(uint32_t semitones, uint8_t steps0,
45 uint8_t steps1, uint8_t steps2,
46 uint8_t steps3) noexcept
47 : _semitones(semitones), _steps{steps0, steps1, steps2, steps3} {}
51 static constexpr int32_t NaturalSemitones(int32_t steps)
noexcept {
52 return (steps / 7) * 12 + (steps % 7) * 2 - ((steps % 7) >= 3 ? 1 : 0);
55 constexpr uint8_t StepsAt(uint8_t index)
const noexcept {
56 return static_cast<uint8_t
>((_steps[index / 2] >> ((index % 2) * 4)) & 0x0F);
59 MCC_CONSTEXPR14 int32_t SemitonesAt(uint8_t index)
const noexcept {
61 for (int32_t k = 0; k < 24; ++k) {
62 if ((_semitones >> k) & 1u) {
74 constexpr ChordPattern() noexcept : _semitones(0), _steps{0, 0, 0, 0} {}
88 static MCC_CONSTEXPR14 ChordPattern
FromFormula(
const char* formula)
noexcept {
90 if (formula ==
nullptr) {
94 int32_t previous = -1;
98 while (formula[i] !=
'\0') {
99 if (formula[i] ==
' ') {
102 int32_t accidental = 0;
103 while (formula[i] ==
'b' || formula[i] ==
'#') {
104 accidental += (formula[i] ==
'#') ? 1 : -1;
108 while (formula[i] >=
'0' && formula[i] <=
'9' && number < 100) {
109 number = number * 10 + (formula[i] -
'0');
112 if (number < 1 || number > 13 ||
113 (formula[i] !=
' ' && formula[i] !=
'\0')) {
116 const int32_t steps = number - 1;
117 const int32_t semitones = NaturalSemitones(steps) + accidental;
118 if (count ==
MaximumTones || semitones <= previous || semitones > 23 ||
119 (count == 0 && (steps != 0 || semitones != 0)) ||
123 pattern._semitones |= (
static_cast<uint32_t
>(1) << semitones);
124 pattern._steps[count / 2] =
static_cast<uint8_t
>(
125 pattern._steps[count / 2] | (steps << ((count % 2) * 4)));
126 previous = semitones;
130 return count == 0 ?
Invalid() : pattern;
134 constexpr bool IsValid() const noexcept {
return _semitones != 0; }
139 for (int32_t k = 0; k < 24; ++k) {
140 count =
static_cast<uint8_t
>(count + ((_semitones >> k) & 1u));
154 const uint8_t index =
static_cast<uint8_t
>(tone - 1);
163 return static_cast<uint16_t
>((_semitones | (_semitones >> 12)) & 0x0FFFu);
167 friend MCC_CONSTEXPR14
bool operator==(
const ChordPattern& a,
const ChordPattern& b)
noexcept {
168 if (a._semitones != b._semitones) {
171 for (uint8_t i = 0; i < 4; ++i) {
172 if (a._steps[i] != b._steps[i]) {
180 friend MCC_CONSTEXPR14
bool operator!=(
const ChordPattern& a,
const ChordPattern& b)
noexcept {
188struct ChordPatternStorage {
189 static constexpr ChordPattern Make(uint32_t semitones, uint8_t steps0,
190 uint8_t steps1, uint8_t steps2,
191 uint8_t steps3)
noexcept {
192 return ChordPattern(semitones, steps0, steps1, steps2, steps3);
constexpr ChordPattern() noexcept
Creates the invalid pattern (SPEC-ERR-2).
Definition ChordPattern.h:74
static constexpr ChordPattern Invalid() noexcept
Returns the invalid pattern.
Definition ChordPattern.h:77
friend MCC_CONSTEXPR14 bool operator!=(const ChordPattern &a, const ChordPattern &b) noexcept
Negation of operator==.
Definition ChordPattern.h:180
constexpr bool IsValid() const noexcept
Returns true unless this is the invalid pattern.
Definition ChordPattern.h:134
static MCC_CONSTEXPR14 ChordPattern FromFormula(const char *formula) noexcept
Builds a pattern from a chord formula such as "1 3 5 b7 9".
Definition ChordPattern.h:88
friend MCC_CONSTEXPR14 bool operator==(const ChordPattern &a, const ChordPattern &b) noexcept
Compares tones, including their written steps.
Definition ChordPattern.h:167
static constexpr uint8_t MaximumTones
Largest number of tones: a full thirteenth chord.
Definition ChordPattern.h:36
constexpr uint16_t PitchClassMask() const noexcept
Returns the twelve-bit set of semitones above the root reduced modulo 12; bit k is set when a tone so...
Definition ChordPattern.h:162
MCC_CONSTEXPR14 uint8_t ToneCount() const noexcept
Returns the number of tones, or 0 for the invalid pattern.
Definition ChordPattern.h:137
MCC_CONSTEXPR14 Interval ToneInterval(int32_t tone) const noexcept
Returns the ascending interval from the root to tone (1-based, in root-position order),...
Definition ChordPattern.h:150
Directed interval: a diatonic step count and a chromatic semitone count (SPEC-INT-1).
Definition Interval.h:30
static MCC_CONSTEXPR14 Interval FromSteps(int32_t diatonicSteps, int32_t semitones) noexcept
Creates the interval spanning diatonicSteps letters and semitones semitones, both signed (SPEC-INT-1)...
Definition Interval.h:111
static constexpr Interval Invalid() noexcept
Returns the invalid interval.
Definition Interval.h:139
Music Composition Core public namespace.
Definition Version.h:4