Skip to content

Commit

Permalink
MIDI tweaks; update/reduce macro usage
Browse files Browse the repository at this point in the history
  • Loading branch information
dashodanger committed Jun 28, 2024
1 parent aeb0417 commit 23e0b8f
Show file tree
Hide file tree
Showing 90 changed files with 8,531 additions and 7,715 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
string(TIMESTAMP BUILD_TIMESTAMP "%Y.%m.%d" UTC)
add_compile_definitions(OBSIDIAN_TIMESTAMP="${BUILD_TIMESTAMP}")
if(CONSOLE_ONLY)
add_compile_definitions(CONSOLE_ONLY)
add_compile_definitions(OBSIDIAN_CONSOLE_ONLY)
endif()
if(WIN32)
add_compile_definitions(WIN32_LEAN_AND_MEAN)
Expand Down
24 changes: 14 additions & 10 deletions libraries/steve/src/Chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@

using namespace steve;

uint8_t ChordDescription::get_tone(uint8_t index) const {
uint8_t tone = 0;
while(index > 0) {
tone += 1;
if(((1 << tone) & tones) != 0) {
index -= 1;
uint8_t ChordDescription::get_tone(uint8_t index) const
{
uint8_t tone = 0;
while (index > 0)
{
tone += 1;
if (((1 << tone) & tones) != 0)
{
index -= 1;
}
}
}
return tone;
return tone;
}

std::string Chord::to_short_string() const {
return key_name(key) + desc->suffix;
std::string Chord::to_short_string() const
{
return key_name(key) + desc->suffix;
}
38 changes: 24 additions & 14 deletions libraries/steve/src/Chord.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,38 @@
#include "ItemDescription.h"
#include "Steve.h"

namespace steve {
struct ChordDescription : public ItemDescription {
namespace steve
{
struct ChordDescription : public ItemDescription
{
std::string suffix;
ToneSet tones = 1;
bool uppercase = false;
ToneSet tones = 1;
bool uppercase = false;

uint8_t get_tone(uint8_t index) const;

inline uint8_t get_tone_count() const { return tone_set_count(tones); }
};
inline uint8_t get_tone_count() const
{
return tone_set_count(tones);
}
};

struct Chord {
struct Chord
{
public:
std::shared_ptr<const ChordDescription> desc;
uint8_t key;
ToneSet tones;
uint8_t key;
ToneSet tones;

inline Chord(std::shared_ptr<const ChordDescription> desc, uint8_t key)
: desc(desc), key(key), tones(tone_set_shift(desc->tones, key)) {
: desc(desc), key(key), tones(tone_set_shift(desc->tones, key))
{
}

std::string to_short_string() const;
inline Chord shifted(uint8_t semitones) const { return Chord(desc, (key + semitones) % 12); }
};
}
std::string to_short_string() const;
inline Chord shifted(uint8_t semitones) const
{
return Chord(desc, (key + semitones) % 12);
}
};
} // namespace steve
12 changes: 7 additions & 5 deletions libraries/steve/src/ChordChange.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
#include "Chord.h"
#include "ItemDescription.h"

namespace steve {
struct ChordChange : ItemDescription {
namespace steve
{
struct ChordChange : ItemDescription
{
std::shared_ptr<ChordDescription> source_chord, target_chord;
uint8_t tone_shift = 0;
};
}
uint8_t tone_shift = 0;
};
} // namespace steve
195 changes: 105 additions & 90 deletions libraries/steve/src/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,111 +13,126 @@

using namespace steve;

std::shared_ptr<ChordChange> Config::get_chord_change(const std::shared_ptr<ChordDescription>& source, const std::shared_ptr<ChordDescription>& target, uint8_t tone_shift) {
std::shared_ptr<ChordChange> chord_change = _chord_changes.get_item(source->name + "->" + target->name + "+" + std::to_string(tone_shift));
chord_change->source_chord = source;
chord_change->target_chord = target;
chord_change->tone_shift = tone_shift;
return chord_change;
std::shared_ptr<ChordChange> Config::get_chord_change(const std::shared_ptr<ChordDescription> &source,
const std::shared_ptr<ChordDescription> &target,
uint8_t tone_shift)
{
std::shared_ptr<ChordChange> chord_change =
_chord_changes.get_item(source->name + "->" + target->name + "+" + std::to_string(tone_shift));
chord_change->source_chord = source;
chord_change->target_chord = target;
chord_change->tone_shift = tone_shift;
return chord_change;
}

Config::Config() {
_creators.get_item("Arpeggio")->func = [](Music* music) {
return new Arpeggio(music);
};
_creators.get_item("Bass")->func = [](Music* music) {
return new Bass(music);
};
_creators.get_item("Chords")->func = [](Music* music) {
return new Chords(music);
};
_creators.get_item("Drums")->func = [](Music* music) {
return new Drums(music);
};
_creators.get_item("Melody")->func = [](Music* music) {
return new Melody(music);
};
Config::Config()
{
_creators.get_item("Arpeggio")->func = [](Music *music) { return new Arpeggio(music); };
_creators.get_item("Bass")->func = [](Music *music) { return new Bass(music); };
_creators.get_item("Chords")->func = [](Music *music) { return new Chords(music); };
_creators.get_item("Drums")->func = [](Music *music) { return new Drums(music); };
_creators.get_item("Melody")->func = [](Music *music) { return new Melody(music); };
}

void Config::compute_cache() {
// This needs to happen before computing scale chords
_chords.compute_cache();
for(auto& scale : _scales.get_all()) {
scale->compute_chords(*this);
}

_scales.compute_cache();
_instruments.compute_cache();
_creators.compute_cache();
_signatures.compute_cache();
_chord_changes.compute_cache();
void Config::compute_cache()
{
// This needs to happen before computing scale chords
_chords.compute_cache();
for (auto &scale : _scales.get_all())
{
scale->compute_chords(*this);
}

_scales.compute_cache();
_instruments.compute_cache();
_creators.compute_cache();
_signatures.compute_cache();
_chord_changes.compute_cache();
}

void Config::list_scales(std::ostream& out) const {
for(const auto& scale_desc : _scales.get_allowed()) {
Scale scale(scale_desc, 0);
out << scale.desc->name << ":" << std::endl;
for(const auto& chord : scale.desc->chords) {
out << '\t' << scale.get_degree_string_for_chord(chord) << "\n";
void Config::list_scales(std::ostream &out) const
{
for (const auto &scale_desc : _scales.get_allowed())
{
Scale scale(scale_desc, 0);
out << scale.desc->name << ":" << std::endl;
for (const auto &chord : scale.desc->chords)
{
out << '\t' << scale.get_degree_string_for_chord(chord) << "\n";
}
}
}
}

uint32_t Config::get_random_tempo() const {
const float tempo_range = max_tempo - min_tempo;
const uint32_t full_precision_tempo = uint32_t(tempo_range * Rand::next_normal()) + min_tempo;
return (full_precision_tempo / 5) * 5;
uint32_t Config::get_random_tempo() const
{
const float tempo_range = max_tempo - min_tempo;
const uint32_t full_precision_tempo = uint32_t(tempo_range * Rand::next_normal()) + min_tempo;
return (full_precision_tempo / 5) * 5;
}

std::vector<Chord> Config::get_chords_inside(ToneSet tones) const {
std::vector<Chord> chords;
for(const auto& desc : _chords.get_allowed()) {
for(int key(0); key < 12; key++) {
const Chord shifted_chord(desc, key);
if((tones | shifted_chord.tones) == tones) { // All chord tones are in the toneset
chords.push_back(shifted_chord);
}
std::vector<Chord> Config::get_chords_inside(ToneSet tones) const
{
std::vector<Chord> chords;
for (const auto &desc : _chords.get_allowed())
{
for (int key(0); key < 12; key++)
{
const Chord shifted_chord(desc, key);
if ((tones | shifted_chord.tones) == tones)
{ // All chord tones are in the toneset
chords.push_back(shifted_chord);
}
}
}
}
return chords;
}
std::vector<Chord> Config::get_chord_progression(const Scale& scale) const {
std::vector<Chord> chords;

// Start with first degree chord
chords.push_back(Chord(_chords.get_random_item([scale](std::shared_ptr<ChordDescription> chord) {
return std::find_if(scale.desc->chords.begin(), scale.desc->chords.end(), [chord](const Chord& scale_chord) {
return scale_chord.desc == chord && scale_chord.key == 0;
}) != scale.desc->chords.end();
}),
scale.key));

// Progress backwards
while(chords.size() < 4) {
const Chord dest_chord = chords.back();
const std::shared_ptr<ChordChange> chord_change = _chord_changes.get_random_item([&](std::shared_ptr<ChordChange> chord_change) {
return dest_chord.desc == chord_change->target_chord && tone_set_within(scale.tones, tone_set_shift(chord_change->source_chord->tones, (dest_chord.key - chord_change->tone_shift + 12) % 12));
});
chords.push_back(Chord(chord_change->source_chord, (dest_chord.key - chord_change->tone_shift + 12) % 12));
}

// Reverse but keep first as start
std::reverse(chords.begin() + 1, chords.end());

return chords;
return chords;
}
std::vector<Chord> Config::get_chord_progression(const Scale &scale) const
{
std::vector<Chord> chords;

// Start with first degree chord
chords.push_back(Chord(_chords.get_random_item([scale](std::shared_ptr<ChordDescription> chord) {
return std::find_if(scale.desc->chords.begin(), scale.desc->chords.end(), [chord](const Chord &scale_chord) {
return scale_chord.desc == chord && scale_chord.key == 0;
}) != scale.desc->chords.end();
}),
scale.key));

// Progress backwards
while (chords.size() < 4)
{
const Chord dest_chord = chords.back();
const std::shared_ptr<ChordChange> chord_change =
_chord_changes.get_random_item([&](std::shared_ptr<ChordChange> chord_change) {
return dest_chord.desc == chord_change->target_chord &&
tone_set_within(scale.tones,
tone_set_shift(chord_change->source_chord->tones,
(dest_chord.key - chord_change->tone_shift + 12) % 12));
});
chords.push_back(Chord(chord_change->source_chord, (dest_chord.key - chord_change->tone_shift + 12) % 12));
}

// Reverse but keep first as start
std::reverse(chords.begin() + 1, chords.end());

std::vector<std::shared_ptr<const CreatorDescription>> Config::get_creators() const {
std::vector<std::shared_ptr<const CreatorDescription>> creators;
return chords;
}

while(creators.empty()) {
for(const auto creator : _creators.get_allowed()) {
const uint32_t count = Rand::next(creator->min_count, creator->max_count);
for(uint32_t i = 0; i < count; i++) {
creators.push_back(creator);
}
std::vector<std::shared_ptr<const CreatorDescription>> Config::get_creators() const
{
std::vector<std::shared_ptr<const CreatorDescription>> creators;

while (creators.empty())
{
for (const auto creator : _creators.get_allowed())
{
const uint32_t count = Rand::next(creator->min_count, creator->max_count);
for (uint32_t i = 0; i < count; i++)
{
creators.push_back(creator);
}
}
}
}

return creators;
return creators;
}
48 changes: 30 additions & 18 deletions libraries/steve/src/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,43 @@
#include "TimeSignature.h"
#include "creator/Creator.h"

namespace steve {
class Config {
namespace steve
{
class Config
{
protected:
uint32_t min_tempo = 0, max_tempo = 360;
ConfigItemList<TimeSignature> _signatures;
uint32_t min_tempo = 0, max_tempo = 360;
ConfigItemList<TimeSignature> _signatures;
ConfigItemList<CreatorDescription> _creators;
ConfigItemList<ChordDescription> _chords;
ConfigItemList<ScaleDescription> _scales;
ConfigItemList<ChordChange> _chord_changes;
ConfigItemList<Instrument> _instruments;
ConfigItemList<ChordDescription> _chords;
ConfigItemList<ScaleDescription> _scales;
ConfigItemList<ChordChange> _chord_changes;
ConfigItemList<Instrument> _instruments;

std::shared_ptr<ChordChange> get_chord_change(const std::shared_ptr<ChordDescription>& source, const std::shared_ptr<ChordDescription>& target, uint8_t tone_shift);
std::shared_ptr<ChordChange> get_chord_change(const std::shared_ptr<ChordDescription> &source,
const std::shared_ptr<ChordDescription> &target, uint8_t tone_shift);

public:
Config();
void compute_cache();
void list_scales(std::ostream&) const;
void list_scales(std::ostream &) const;

uint32_t get_random_tempo() const;
std::vector<Chord> get_chords_inside(ToneSet tones) const;
std::vector<Chord> get_chord_progression(const Scale&) const;
uint32_t get_random_tempo() const;
std::vector<Chord> get_chords_inside(ToneSet tones) const;
std::vector<Chord> get_chord_progression(const Scale &) const;
std::vector<std::shared_ptr<const CreatorDescription>> get_creators() const;

inline const auto& get_signatures() const { return _signatures; }
inline const auto& get_scales() const { return _scales; }
inline const auto& get_instruments() const { return _instruments; }
};
}
inline const auto &get_signatures() const
{
return _signatures;
}
inline const auto &get_scales() const
{
return _scales;
}
inline const auto &get_instruments() const
{
return _instruments;
}
};
} // namespace steve
Loading

0 comments on commit 23e0b8f

Please sign in to comment.