Euphoria
synth.h
Go to the documentation of this file.
1 #pragma once
2 
3 
4 
5 #include <map>
6 
7 #include "core/key.h"
8 
9 
10 namespace eu::minsynth
11 {
12  enum class Tuning
13  {
14  a4,
15  boston,
16  new_york,
17  europe,
18  french,
19  baroque,
20  chorton,
21  classical,
22  max_value
23  };
24 
25 
26  enum class ChordEmulation
27  {
28  none,
29  major,
30  minor,
31  diminished,
32  augmented,
33  major7,
34  dominant7,
35  augmented7,
38  max_value
39  };
40 
41 
42  enum class MidiEvent
43  {
44  note_off = 0b000,
45  note_on = 0b001,
46  aftertouch = 0b010,
47  control_change = 0b011,
48  program_change = 0b100,
49  channel_pressure = 0b101,
50  pitch_bend = 0b110
51  };
52 
53 
54  enum class ArpMode
55  {
56  up,
57  down,
60  random,
62  max_value
63  };
64 
65 
66  enum class OscilatorType
67  {
68  sine,
69  square,
70  triangle,
71  sawtooth,
72  noise,
73  max_value
74  };
75 
76 
77  // https://pages.mtu.edu/~suits/notefreqs.html
78  namespace base_frequencies
79  {
80  constexpr float c0 = 16.35f;
81  constexpr float a4 = 440.0f;
82  constexpr float boston_a4 = 441.0f;
83  constexpr float new_york_a4 = 442.0f;
84  constexpr float europe_a4 = 443.0f;
85  constexpr float french_a4 = 435.0f;
86  constexpr float baroque_a4 = 415.0f;
87  constexpr float chorton_a4 = 466.0f; // 460-470
88  constexpr float classical_a4 = 430.0f; // 460-470
89  }
90 
91  std::string to_string(Tuning t);
92  std::string to_string(ChordEmulation em);
93  std::string to_string(ArpMode mode);
94  std::string to_string(OscilatorType osc);
95 
96  std::string from_midi_event_to_string(MidiEvent e);
97 
99 
100  float from_tone_to_frequency(int tone, float base_frequency);
101 
102  // nodes
103 
104 
105  struct Node
106  {
107  Node() = default;
108  virtual ~Node() = default;
109 
110  Node(const Node&) = delete;
111  Node(Node&&) = delete;
112  void operator=(const Node&) = delete;
113  void operator=(Node&&) = delete;
114 
115  virtual void update(float dt, float current_time);
116  };
117 
118  struct ToneTaker
119  {
120  ToneTaker() = default;
121  virtual ~ToneTaker() = default;
122 
123  ToneTaker(const ToneTaker&) = delete;
124  ToneTaker(ToneTaker&&) = delete;
125  void operator=(const ToneTaker&) = delete;
126  void operator=(ToneTaker&&) = delete;
127 
128  virtual void on_tone(int tone, bool down, float time) = 0;
129  };
130 
131  struct ToneSender
132  {
133  ToneTaker* next_node = nullptr;
134 
135  void send_tone(int tone, bool down, float time) const;
136  };
137 
139  {
140  FrequencyTaker() = default;
141  virtual ~FrequencyTaker() = default;
142 
143  FrequencyTaker(const FrequencyTaker&) = delete;
145  void operator=(const FrequencyTaker&) = delete;
146  void operator=(FrequencyTaker&&) = delete;
147 
148  virtual void on_frequency_down(int id, float freq, float time) = 0;
149  virtual void on_frequency_up(int id, float frequency, float time) = 0;
150  };
151 
152  struct WaveOut
153  {
154  WaveOut() = default;
155  virtual ~WaveOut() = default;
156 
157  WaveOut(const WaveOut&) = delete;
158  WaveOut(WaveOut&&) = delete;
159  void operator=(const WaveOut&) = delete;
160  void operator=(WaveOut&&) = delete;
161 
162  virtual float get_output(float time) = 0;
163  };
164 
165  // Tone -> Frequency
167  : public ToneTaker
168  , public Node
169  {
171  FrequencyTaker* next = nullptr;
172 
173  void on_tone(int tone, bool down, float time) override;
174 
175  [[nodiscard]] float calc_frequency(int semitone) const;
176  };
177 
178  struct PianoKey
179  {
180  int semitone;
182  std::string name;
184 
185  PianoKey(int st, core::Key kc, const std::string& n, int octave);
186  };
187 
188  struct MidiInNode : public virtual Node
189  {
190  ToneTaker* tones = nullptr;
191  float last_time = 0;
192  bool open_virtual_port = false;
193  unsigned int port_number = 1;
194 
195  void on_midi_message(float dt, const std::vector<unsigned char>& bytes);
196 
197  static bool is_status_message(unsigned char b);
198  static void debug_callback(double dt, const std::vector<unsigned char>& bytes);
199  };
200 
201 
202  // Node handles input from keyboard. Input -> Tones
203  struct KeyboardInputNode : public virtual Node
204  {
205  std::vector<PianoKey> keys;
206  bool octave_shift = false;
207  ToneTaker* tones = nullptr;
209 
210  void on_input(core::Key input, bool was_pressed, float time);
211 
212  void on_chord
213  (
214  int base,
215  bool was_pressed,
216  float time,
217  int first,
218  int second
219  ) const;
220 
221  void on_chord
222  (
223  int base,
224  bool was_pressed,
225  float time,
226  const std::vector<int>& integer_notation
227  ) const;
228  };
229 
230 
231  // Single Tone node, Tone->Tone.
233  : public ToneTaker
234  , public ToneSender
235  , public Node
236  {
237  std::map<int, float> down_tones;
238 
239  void on_tone(int tone, bool down, float time) override;
240 
241  [[nodiscard]] int get_current_tone() const;
242  };
243 
244 
246  : public ToneTaker
247  , public ToneSender
248  , public Node
249  {
250  std::map<int, float> down_tones;
252  int index = 0;
253  std::vector<int> tones;
255  int octaves = 3;
256  float update_time = 1.0f;
257  float tone_time = 0.3f;
258  std::map<int, float> active_tones;
259 
260  void update(float dt, float current_time) override;
261  void on_tone(int tone, bool down, float time) override;
262  };
263 
264 
265  float run_oscilator(float frequency, float time, OscilatorType osc);
266 
267 
269  {
270  float frequency;
271  float time_start;
272  };
273 
275  {
276  bool alive;
277  float frequency;
278  float time_end;
279  float scale;
280  };
281 
282 
283  float to01(float lower_bound, float value, float upper_bound);
284 
285  struct Envelope
286  {
287  float time_to_start = 0.01f;
288  float time_to_end = 0.01f;
289 
290  [[nodiscard]] float get_live(float wave, float start_time, float current_time) const;
291  [[nodiscard]] float get_dead(float wave, float end_time, float current_time) const;
292  };
293 
294 
297  : public virtual WaveOut
298  , public virtual FrequencyTaker
299  , public Node
300  {
301  std::map<int, LiveFrequency> live;
302  std::vector<DeadFrequency> dead;
305 
306  [[nodiscard]] int get_total_tones() const;
307  [[nodiscard]] int get_alive_tones() const;
308  [[nodiscard]] int get_dead_tones() const;
309 
310  void update(float dt, float current_time) override;
311  void on_frequency_down(int id, float freq, float time) override;
312  void on_frequency_up(int id, float frequency, float time) override;
313  float get_output(float time) override;
314  };
315 
316 
317  struct Effect : public WaveOut
318  {
319  WaveOut* in = nullptr;
320 
321  float get_output(float time) override;
322 
323  virtual float on_wave(float wave) = 0;
324  };
325 
326  struct VolumeNode
327  : public Effect
328  , public Node
329  {
330  float volume = 0.5f;
331 
332  float on_wave(float wave) override;
333  };
334 
336  : public Effect
337  , public Node
338  {
339  int times = 0;
340 
341  float on_wave(float wave) override;
342  };
343 
344 
345  using KeyboardLayout = std::vector<std::vector<core::Key>>;
346 
347 
349 
351  (
352  std::vector<PianoKey>* keys,
353  int base_octave,
354  int octave_offset
355  );
356 
357 
358 }
ParserBase * base
Definition: argparse.cc:887
Key
Definition: key.h:26
constexpr float classical_a4
Definition: synth.h:88
constexpr float baroque_a4
Definition: synth.h:86
constexpr float chorton_a4
Definition: synth.h:87
constexpr float boston_a4
Definition: synth.h:82
constexpr float europe_a4
Definition: synth.h:84
constexpr float french_a4
Definition: synth.h:85
constexpr float a4
Definition: synth.h:81
constexpr float c0
Definition: synth.h:80
constexpr float new_york_a4
Definition: synth.h:83
ChordEmulation
Definition: synth.h:27
const KeyboardLayout & create_qwerty_keyboard_layout()
Definition: synth.cc:860
std::string from_midi_event_to_string(MidiEvent e)
Definition: synth.cc:84
float from_tone_to_frequency(int tone, float base_frequency)
Definition: synth.cc:183
float to01(float lower_bound, float value, float upper_bound)
Definition: synth.cc:642
std::vector< std::vector< core::Key > > KeyboardLayout
Definition: synth.h:345
std::string to_string(Tuning t)
Definition: synth.cc:30
float from_tuning_to_base_frequency(Tuning t)
Definition: synth.cc:66
OscilatorType
Definition: synth.h:67
void setup_qwerty_two_octave_layout(std::vector< PianoKey > *keys, int base_octave, int octave_offset)
Definition: synth.cc:927
float run_oscilator(float frequency, float time, OscilatorType osc)
Definition: synth.cc:622
void update(float dt, float current_time) override
Definition: synth.cc:518
std::map< int, float > down_tones
Definition: synth.h:250
std::vector< int > tones
Definition: synth.h:253
std::map< int, float > active_tones
Definition: synth.h:258
void on_tone(int tone, bool down, float time) override
Definition: synth.cc:567
float get_output(float time) override
Definition: synth.cc:790
WaveOut * in
Definition: synth.h:319
virtual float on_wave(float wave)=0
float get_live(float wave, float start_time, float current_time) const
Definition: synth.cc:649
float get_dead(float wave, float end_time, float current_time) const
Definition: synth.cc:666
virtual void on_frequency_up(int id, float frequency, float time)=0
void operator=(FrequencyTaker &&)=delete
virtual void on_frequency_down(int id, float freq, float time)=0
virtual ~FrequencyTaker()=default
FrequencyTaker(const FrequencyTaker &)=delete
FrequencyTaker(FrequencyTaker &&)=delete
void operator=(const FrequencyTaker &)=delete
std::vector< PianoKey > keys
Definition: synth.h:205
void on_chord(int base, bool was_pressed, float time, int first, int second) const
Definition: synth.cc:360
ChordEmulation chords_emulation
Definition: synth.h:208
void on_input(core::Key input, bool was_pressed, float time)
Definition: synth.cc:389
unsigned int port_number
Definition: synth.h:193
void on_midi_message(float dt, const std::vector< unsigned char > &bytes)
Definition: synth.cc:296
static void debug_callback(double dt, const std::vector< unsigned char > &bytes)
Definition: synth.cc:259
static bool is_status_message(unsigned char b)
Definition: synth.cc:251
ToneTaker * tones
Definition: synth.h:190
void operator=(Node &&)=delete
Node(Node &&)=delete
virtual void update(float dt, float current_time)
Definition: synth.cc:189
Node(const Node &)=delete
void operator=(const Node &)=delete
virtual ~Node()=default
Node represents a single Oscilator. Frequency -> WaveOutput.
Definition: synth.h:300
int get_dead_tones() const
Definition: synth.cc:696
int get_total_tones() const
Definition: synth.cc:684
int get_alive_tones() const
Definition: synth.cc:690
std::vector< DeadFrequency > dead
Definition: synth.h:302
void update(float dt, float current_time) override
Definition: synth.cc:702
float get_output(float time) override
Definition: synth.cc:734
std::map< int, LiveFrequency > live
Definition: synth.h:301
void on_frequency_down(int id, float freq, float time) override
Definition: synth.cc:720
OscilatorType oscilator
Definition: synth.h:303
minsynth::Envelope envelope
Definition: synth.h:304
void on_frequency_up(int id, float frequency, float time) override
Definition: synth.cc:726
core::Key keycode
Definition: synth.h:181
PianoKey(int st, core::Key kc, const std::string &n, int octave)
Definition: synth.cc:241
std::string name
Definition: synth.h:182
float on_wave(float wave) override
Definition: synth.cc:809
std::map< int, float > down_tones
Definition: synth.h:237
int get_current_tone() const
Definition: synth.cc:489
void on_tone(int tone, bool down, float time) override
Definition: synth.cc:454
ToneTaker * next_node
Definition: synth.h:133
void send_tone(int tone, bool down, float time) const
Definition: synth.cc:194
void operator=(ToneTaker &&)=delete
ToneTaker(const ToneTaker &)=delete
virtual ~ToneTaker()=default
void operator=(const ToneTaker &)=delete
ToneTaker(ToneTaker &&)=delete
virtual void on_tone(int tone, bool down, float time)=0
void on_tone(int tone, bool down, float time) override
Definition: synth.cc:204
float calc_frequency(int semitone) const
Definition: synth.cc:222
float on_wave(float wave) override
Definition: synth.cc:802
WaveOut(WaveOut &&)=delete
void operator=(const WaveOut &)=delete
virtual float get_output(float time)=0
virtual ~WaveOut()=default
WaveOut(const WaveOut &)=delete
void operator=(WaveOut &&)=delete