8#include <initializer_list>
66 static constexpr std::optional<PitchClassSet>
68 std::uint16_t
mask = 0;
69 for (
const auto pitch_class : pitch_classes) {
72 mask =
static_cast<std::uint16_t
>(
mask | (1u <<
static_cast<unsigned>(pitch_class)));
77 constexpr std::uint16_t
mask() const noexcept {
80 constexpr bool empty() const noexcept {
83 constexpr std::size_t
size() const noexcept {
84 return std::popcount(mask_);
88 return is_valid(pitch_class) && ((mask_ >>
static_cast<unsigned>(pitch_class)) & 1u) != 0;
91 constexpr std::optional<PitchClass>
at(std::size_t index)
const noexcept {
94 const auto pitch_class =
static_cast<PitchClass>(pitch);
107 std::size_t index = 0;
108 for (
int pitch = 0; pitch < static_cast<int>(pitch_class); ++pitch)
109 if ((mask_ & (1u << pitch)) != 0)
115 std::uint16_t result = 0;
117 if ((mask_ & (1u << pitch)) == 0)
119 result =
static_cast<std::uint16_t
>(
120 result | (1u <<
static_cast<unsigned>(
127 std::uint16_t result = 0;
128 const int center = 2 *
static_cast<int>(axis);
130 if ((mask_ & (1u << pitch)) == 0)
132 result =
static_cast<std::uint16_t
>(
141 struct TrustedMask {};
144 std::uint16_t mask_ = 0;
169 std::uint16_t mask = 0;
170 for (
const int semitone : semitones)
172 mask =
static_cast<std::uint16_t
>(mask | (1u << semitone));
244 constexpr std::array<std::uint16_t, kNamedScaleCount> masks{{
256 detail::pitch_class_mask({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}),
260 const auto index =
static_cast<std::size_t
>(scale);
261 if (index >= masks.size())
291 return intervals_.
transposed(
static_cast<int>(root_));
294 return intervals_.size();
302 const auto interval = intervals_.at(degree);
305 return transpose(root_,
static_cast<int>(*interval));
311 return intervals_.index_of(
319 int octave = degree / count;
320 int within = degree % count;
325 const auto interval = intervals_.at(
static_cast<std::size_t
>(within));
327 static_cast<int>(*interval);
328 if (semitones < std::numeric_limits<int>::min() ||
329 semitones > std::numeric_limits<int>::max())
331 return static_cast<int>(semitones);
335 return Scale(
transpose(root_, semitones), intervals_);
338 constexpr std::optional<Scale>
rotated(std::size_t degree)
const noexcept {
339 const auto pivot = intervals_.at(degree);
342 const int semitones =
static_cast<int>(*pivot);
343 return Scale(
transpose(root_, semitones), intervals_.transposed(-semitones));
constexpr std::uint16_t mask() const noexcept
Definition pitch.hpp:77
constexpr bool contains(PitchClass pitch_class) const noexcept
Definition pitch.hpp:87
constexpr PitchClassSet() noexcept=default
constexpr std::optional< std::size_t > index_of(PitchClass pitch_class) const noexcept
Definition pitch.hpp:104
constexpr auto operator<=>(const PitchClassSet &) const =default
static constexpr std::optional< PitchClassSet > from_mask(std::uint16_t mask) noexcept
Definition pitch.hpp:60
constexpr PitchClassSet inverted(PitchClass axis=PitchClass::c) const noexcept
Definition pitch.hpp:126
static constexpr std::optional< PitchClassSet > from_pitch_classes(std::span< const PitchClass > pitch_classes) noexcept
Definition pitch.hpp:67
constexpr std::size_t size() const noexcept
Definition pitch.hpp:83
constexpr PitchClassSet transposed(int semitones) const noexcept
Definition pitch.hpp:114
constexpr std::optional< PitchClass > at(std::size_t index) const noexcept
Definition pitch.hpp:91
constexpr bool empty() const noexcept
Definition pitch.hpp:80
static constexpr std::optional< Scale > from_intervals(PitchClass root, PitchClassSet intervals) noexcept
Definition pitch.hpp:268
constexpr std::optional< int > degree_to_semitones(int degree) const noexcept
Definition pitch.hpp:315
constexpr std::size_t degree_count() const noexcept
Definition pitch.hpp:293
constexpr Scale transposed(int semitones) const noexcept
Definition pitch.hpp:334
static constexpr std::optional< Scale > named(PitchClass root, NamedScale name) noexcept
Definition pitch.hpp:275
constexpr std::optional< Scale > rotated(std::size_t degree) const noexcept
Definition pitch.hpp:338
constexpr PitchClassSet intervals() const noexcept
Definition pitch.hpp:287
constexpr PitchClass root() const noexcept
Definition pitch.hpp:284
constexpr std::optional< std::size_t > degree_index(PitchClass pitch_class) const noexcept
Definition pitch.hpp:308
constexpr PitchClassSet pitch_classes() const noexcept
Definition pitch.hpp:290
constexpr bool contains(PitchClass pitch_class) const noexcept
Definition pitch.hpp:297
constexpr auto operator<=>(const Scale &) const =default
constexpr std::optional< PitchClass > degree_pitch_class(std::size_t degree) const noexcept
Definition pitch.hpp:301
Definition harmony.hpp:99
constexpr std::uint16_t pitch_class_mask(std::initializer_list< int > semitones) noexcept
Definition pitch.hpp:168
constexpr bool is_valid(PitchClass pitch_class) noexcept
Definition pitch.hpp:34
constexpr std::array< ScaleCompatibilityEntry, 14 > kForgePrimitiveScales
Definition pitch.hpp:226
constexpr std::array< ScaleCompatibilityEntry, 10 > kPulpSignalScales
Definition pitch.hpp:184
constexpr std::size_t kNamedScaleCount
Definition pitch.hpp:164
constexpr PitchClass transpose(PitchClass pitch_class, int semitones) noexcept
Definition pitch.hpp:51
constexpr std::array< ScaleCompatibilityEntry, 10 > kPulpTimelineScales
Definition pitch.hpp:198
NamedScale
Definition pitch.hpp:147
@ lydian
Definition pitch.hpp:152
@ minor_pentatonic
Definition pitch.hpp:157
@ natural_minor
Definition pitch.hpp:149
@ phrygian
Definition pitch.hpp:151
@ blues
Definition pitch.hpp:160
@ locrian
Definition pitch.hpp:158
@ melodic_minor
Definition pitch.hpp:155
@ whole_tone
Definition pitch.hpp:161
@ dorian
Definition pitch.hpp:150
@ chromatic
Definition pitch.hpp:159
@ mixolydian
Definition pitch.hpp:153
@ harmonic_minor
Definition pitch.hpp:154
@ major_pentatonic
Definition pitch.hpp:156
@ major
Definition pitch.hpp:148
constexpr std::array< ScaleCompatibilityEntry, 10 > kForgeRuntimeScales
Definition pitch.hpp:212
constexpr PitchClass wrap_pitch_class(int index) noexcept
Definition pitch.hpp:44
constexpr int kPitchClassesPerOctave
Definition pitch.hpp:16
PitchClass
Definition pitch.hpp:19
@ a
Definition pitch.hpp:29
@ c
Definition pitch.hpp:20
@ a_sharp
Definition pitch.hpp:30
@ d
Definition pitch.hpp:22
@ f
Definition pitch.hpp:25
@ d_sharp
Definition pitch.hpp:23
@ b
Definition pitch.hpp:31
@ g_sharp
Definition pitch.hpp:28
@ f_sharp
Definition pitch.hpp:26
@ g
Definition pitch.hpp:27
@ e
Definition pitch.hpp:24
@ c_sharp
Definition pitch.hpp:21
constexpr std::uint16_t kPitchClassMask
Definition pitch.hpp:17
constexpr std::optional< PitchClassSet > scale_intervals(NamedScale scale) noexcept
Definition pitch.hpp:243
constexpr std::optional< PitchClass > pitch_class_from_index(int index) noexcept
Definition pitch.hpp:38
@ octave
Definition chord.hpp:28
@ major
Definition chord.hpp:17
NamedScale scale
Definition pitch.hpp:180
std::string_view stored_name
Definition pitch.hpp:179