8 #include <fmt/format.h>
17 using namespace fmt::literals;
35 case Tuning::boston:
return "Boston 441 Hz";
36 case Tuning::new_york:
return "New York 442 Hz";
37 case Tuning::europe:
return "europe 443 Hz";
38 case Tuning::french:
return "French 435 Hz";
39 case Tuning::baroque:
return "baroque 415 hz";
40 case Tuning::chorton:
return "chorton 466 Hz";
41 case Tuning::classical:
return "classical 430 Hz";
42 default:
return "???";
52 case ChordEmulation::major:
return "Major triad";
53 case ChordEmulation::minor:
return "Minor Triad";
54 case ChordEmulation::diminished:
return "diminished triad";
55 case ChordEmulation::augmented:
return "augmented triad";
56 case ChordEmulation::major7:
return "Major 7th";
57 case ChordEmulation::dominant7:
return "Dominant 7th";
58 case ChordEmulation::augmented7:
return "augmented 7th";
59 case ChordEmulation::augmented_major7:
return "augmented Major 7th";
60 case ChordEmulation::minor_major7:
return "Minor major 7th";
61 default:
return "???";
88 case MidiEvent::note_off:
return "Off";
89 case MidiEvent::note_on:
return "On";
90 case MidiEvent::aftertouch:
return "aftertouch";
91 case MidiEvent::control_change:
return "CC";
92 case MidiEvent::program_change:
return "PC";
93 case MidiEvent::channel_pressure:
return "Channel Pressure";
94 case MidiEvent::pitch_bend:
return "pitch_bend";
107 case ArpMode::up_down_inclusive:
return "Up/Down (inclusive)";
108 case ArpMode::up_down_exclusive:
return "Up/Down (exclusive)";
109 case ArpMode::random:
return "Random";
110 case ArpMode::random_no_repeat:
return "Random (no repeat)";
111 default:
return "???";
121 case OscilatorType::sine:
return "Sine";
123 case OscilatorType::triangle:
return "Triangle";
124 case OscilatorType::sawtooth:
return "sawtooth";
125 case OscilatorType::noise:
return "noise";
130 template <
int steps_per_octave>
136 = std::pow(2.0f, 1.0f /
static_cast<float>(steps_per_octave));
137 for(
int octave_index = 0; octave_index < steps_per_octave; octave_index += 1)
139 step_data[octave_index] = std::pow(
base,
static_cast<float>(octave_index));
143 [[nodiscard]] constexpr
float
146 float freq = octave_base_frequency;
150 while(step >= steps_per_octave)
153 step -= steps_per_octave;
159 step += steps_per_octave;
162 ASSERT(step >= 0 && step < steps_per_octave);
163 const auto rf = freq * step_data[step];
168 float step_data[steps_per_octave] = {
174 template <
int tones_per_octave>
179 return converter.get_frequency(tone, base_frequency);
185 return from_tone_to_frequency_impl<12>(tone, base_frequency);
189 Node::update(
float ,
float )
194 ToneSender::send_tone(
int tone,
bool down,
float time)
const
196 if(next_node !=
nullptr)
198 next_node->on_tone(tone,
down, time);
204 ToneToFrequencyConverterNode::on_tone(
int tone,
bool down,
float time)
213 next->on_frequency_down(tone, calc_frequency(tone), time);
217 next->on_frequency_up(tone, calc_frequency(tone), time);
222 ToneToFrequencyConverterNode::calc_frequency(
int semitone)
const
225 const int tone = semitone - 9;
235 name_and_octave(
const std::string& name,
int octave)
237 return fmt::format(
"{}{}", name, octave);
241 PianoKey::PianoKey(
int st,
core::Key kc,
const std::string& n,
int octave)
244 , name(name_and_octave(n, octave))
245 , octave_shift(false)
253 const auto is_status = ((b >> 7) & 0x1) == 1;
261 const std::vector<unsigned char>& bytes
264 using Byte =
unsigned char;
266 const Byte message_mask = 0x7;
267 const Byte channel_mask = 0xF;
274 const Byte channel = (b >> 0) & channel_mask;
275 const Byte message = (b >> 4) & message_mask;
280 static_cast<unsigned int>(channel),
286 LOG_INFO(
"{0}",
static_cast<unsigned int>(b));
298 using Byte =
unsigned char;
307 LOG_ERROR(
"todo: need to handle data message without status.");
311 const auto bytes_size = bytes.size();
313 const Byte message_mask = 0x7;
316 const Byte message = (bytes[0] >> 4) & message_mask;
318 const auto event =
static_cast<MidiEvent>(message);
326 const auto note = bytes[1];
327 const auto velocity = bytes[2];
331 LOG_ERROR(
"Unexpected midi command in note on/off data.");
338 const int tone = note;
347 LOG_ERROR(
"todo: need to handle note on/off with other sizes.");
379 const std::vector<int>& integer_notation
382 for(
auto i: integer_notation)
404 const auto octave_shift_semitones = key.octave_shift ? 24 : 0;
405 const int tone = key.semitone + octave_shift_semitones;
407 const auto minor3rd = 3;
408 const auto major3rd = 4;
415 on_chord(tone, was_pressed, time, major3rd, minor3rd);
418 on_chord(tone, was_pressed, time, minor3rd, major3rd);
421 on_chord(tone, was_pressed, time, minor3rd, minor3rd);
424 on_chord(tone, was_pressed, time, major3rd, major3rd);
427 on_chord(tone, was_pressed, time, {0, 4, 7, 11});
430 on_chord(tone, was_pressed, time, {0, 4, 7, 10});
433 on_chord(tone, was_pressed, time, {0, 4, 8, 10});
436 on_chord(tone, was_pressed, time, {0, 4, 8, 11});
439 on_chord(tone, was_pressed, time, {0, 3, 7, 11});
474 if(playing_tone == tone)
491 bool has_tone =
false;
532 const int last_index =
index;
533 index = rand() % size;
536 while(
index == last_index)
538 index = rand() % size;
551 std::vector<int> erase;
554 if(tone.second < current_time)
556 send_tone(tone.first,
false, tone.second);
557 erase.emplace_back(tone.first);
560 for(
auto tone: erase)
584 for(
int octave_index = 0; octave_index <
octaves; octave_index += 1)
586 tt.insert(t.first + octave_index * 12);
592 tones.insert(
tones.begin(), tt.begin(), tt.end());
595 tones.insert(
tones.begin(), tt.rbegin(), tt.rend());
598 tones.insert(
tones.begin(), tt.begin(), tt.end());
599 tones.insert(
tones.begin(), tt.rbegin(), tt.rend());
602 tones.insert(
tones.begin(), tt.begin(), tt.end());
605 tt.erase(tt.begin());
609 tones.insert(
tones.begin(), tt.rbegin(), tt.rend());
613 tones.insert(
tones.begin(), tt.begin(), tt.end());
631 return (2 /
pi) * (frequency *
pi * fmodf(time, 1 / frequency) -
pi / 2);
635 return 2 * (
static_cast<float>(rand()) /
static_cast<float>(RAND_MAX)) - 1;
642 to01(
float lower_bound,
float value,
float upper_bound)
644 return (value - lower_bound) / (upper_bound - lower_bound);
651 if(current_time < start_time)
668 if(current_time < end_time)
678 return wave * (1 -
to01(end_time, current_time, end_time +
time_to_end));
712 return df.time_end + envelope.time_to_end < current_time;
738 const int maxtones = 10;
741 for(
const auto& li:
live)
743 if(tone++ > maxtones)
747 const auto& f = li.second;
757 for(
const auto& d:
dead)
759 if(tone++ > maxtones)
777 template <
typename T>
779 insert(std::vector<T>* to,
const std::vector<T>& from)
781 for(
const auto& t: from)
812 const auto negative = wave < 0;
813 for(
int time_counter = 0; time_counter <
times; time_counter += 1)
817 return negative ? w * -1 : w;
821 std::vector<PianoKey>
842 PianoKey(semitone_offset + 0, c,
"C", octave),
843 PianoKey(semitone_offset + 1, c_sharp,
"C#", octave),
844 PianoKey(semitone_offset + 2, d,
"D", octave),
845 PianoKey(semitone_offset + 3, d_sharp,
"D#", octave),
846 PianoKey(semitone_offset + 4, e,
"E", octave),
848 PianoKey(semitone_offset + 5, f,
"F", octave),
849 PianoKey(semitone_offset + 6, f_sharp,
"F#", octave),
850 PianoKey(semitone_offset + 7, g,
"G", octave),
851 PianoKey(semitone_offset + 8, g_sharp,
"G#", octave),
852 PianoKey(semitone_offset + 9, a,
"A", octave),
853 PianoKey(semitone_offset + 10, a_sharp,
"A#", octave),
854 PianoKey(semitone_offset + 11, b,
"B", octave),
866 {K::num_1, K::num_2, K::num_3, K::num_4, K::num_5, K::num_6, K::num_7, K::num_8, K::num_9, K::num_0},
867 {K::q, K::w, K::e, K::r, K::t, K::y, K::u, K::i, K::o, K::p},
868 {K::a, K::s, K::d, K::f, K::g, K::h, K::j, K::k, K::l},
869 {K::z, K::x, K::c, K::v, K::b, K::n, K::m},
879 std::vector<PianoKey>* keys,
887 const auto key = [&](
int x,
int y) ->
core::Key
889 const auto wy = start_row - y + 1;
894 const auto& r = k[wy];
895 const auto wx = start_col + x;
902 const auto white_key = key;
903 const auto black_key = key;
910 base_octave + octave,
913 white_key(0, 0), white_key(1, 0), white_key(2, 0),
915 white_key(3, 0), white_key(4, 0), white_key(5, 0), white_key(6, 0),
917 black_key(1, 1), black_key(2, 1),
919 black_key(4, 1), black_key(5, 1), black_key(6, 1)
928 std::vector<PianoKey>* keys,
constexpr float classical_a4
constexpr float baroque_a4
constexpr float chorton_a4
constexpr float boston_a4
constexpr float europe_a4
constexpr float french_a4
constexpr float new_york_a4
float from_tone_to_frequency_impl(int tone, float base_frequency)
const KeyboardLayout & create_qwerty_keyboard_layout()
std::string from_midi_event_to_string(MidiEvent e)
float from_tone_to_frequency(int tone, float base_frequency)
float to01(float lower_bound, float value, float upper_bound)
std::vector< std::vector< core::Key > > KeyboardLayout
void setup_one_octave_layout(std::vector< PianoKey > *keys, int base_octave, int octave, const KeyboardLayout &k, int start_row, int start_col)
std::string to_string(OscilatorType osc)
float from_tuning_to_base_frequency(Tuning t)
void setup_qwerty_two_octave_layout(std::vector< PianoKey > *keys, int base_octave, int octave_offset)
float run_oscilator(float frequency, float time, OscilatorType osc)
std::vector< PianoKey > build_one_cctave_of_piano_keys(int octave, int semitone_offset, core::Key c, core::Key d, core::Key e, core::Key f, core::Key g, core::Key a, core::Key b, core::Key c_sharp, core::Key d_sharp, core::Key f_sharp, core::Key g_sharp, core::Key a_sharp)
int c_sizet_to_int(size_t t)
constexpr float abs(float r)
float sin(const Angle &ang)
constexpr float as_radians() const
constexpr float from_percent_of_360() const
void update(float dt, float current_time) override
std::map< int, float > down_tones
float current_time_in_interval
std::map< int, float > active_tones
void on_tone(int tone, bool down, float time) override
float get_output(float time) override
virtual float on_wave(float wave)=0
float get_live(float wave, float start_time, float current_time) const
float get_dead(float wave, float end_time, float current_time) const
void on_midi_message(float dt, const std::vector< unsigned char > &bytes)
static void debug_callback(double dt, const std::vector< unsigned char > &bytes)
static bool is_status_message(unsigned char b)
int get_dead_tones() const
int get_total_tones() const
int get_alive_tones() const
std::vector< DeadFrequency > dead
void update(float dt, float current_time) override
float get_output(float time) override
std::map< int, LiveFrequency > live
void on_frequency_down(int id, float freq, float time) override
minsynth::Envelope envelope
void on_frequency_up(int id, float frequency, float time) override
float on_wave(float wave) override
std::map< int, float > down_tones
int get_current_tone() const
void on_tone(int tone, bool down, float time) override
void send_tone(int tone, bool down, float time) const
virtual void on_tone(int tone, bool down, float time)=0
constexpr ToneToFrequencyConverter()
constexpr float get_frequency(int halfstep, float octave_base_frequency) const
float on_wave(float wave) override
virtual float get_output(float time)=0