SpectMorph
smmidisynth.hh
1 // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl-2.1.html
2 
3 #ifndef SPECTMORPH_MIDI_SYNTH_HH
4 #define SPECTMORPH_MIDI_SYNTH_HH
5 
6 #include "smmorphplansynth.hh"
7 #include "smnotifybuffer.hh"
8 #include "sminsteditsynth.hh"
9 #include "smrtmemory.hh"
10 
11 #include <array>
12 
13 namespace SpectMorph {
14 
16 {
18  {
19  int key;
20  int channel;
21  int clap_id;
22  };
23  virtual void terminated_voice (TerminatedVoice& voice) = 0;
24 };
25 
26 class MidiSynth
27 {
28 private:
29  enum EventType {
30  EVENT_NOTE_ON,
31  EVENT_NOTE_OFF,
32  EVENT_CONTROL_VALUE,
33  EVENT_MOD_VALUE,
34  EVENT_PITCH_EXPRESSION,
35  EVENT_PITCH_BEND,
36  EVENT_CC
37  };
38 
39  struct NoteEvent
40  {
41  int clap_id;
42  int channel;
43  int key;
44  float velocity;
45  };
46  struct ExpressionEvent
47  {
48  int channel;
49  int key;
50  float value;
51  };
52  struct ValueEvent
53  {
54  int control_input;
55  float value;
56  };
57  struct ModValueEvent
58  {
59  int clap_id;
60  int channel;
61  int key;
62  int control_input;
63  float value;
64  };
65  struct PitchBendEvent
66  {
67  int channel;
68  float value;
69  };
70  struct CCEvent
71  {
72  int controller;
73  int value;
74  };
75  struct Event
76  {
77  EventType type;
78  unsigned int offset;
79 
80  union {
81  NoteEvent note; // EVENT_NOTE_ON, EVENT_NOTE_OFF
82  ExpressionEvent expr; // EVENT_PITCH_EXPRESSION
83  ValueEvent value; // EVENT_CONTROL_VALUE
84  ModValueEvent mod; // EVENT_MOD_VALUE
85  PitchBendEvent pitch_bend; // EVENT_PITCH_BEND
86  CCEvent cc; // EVENT_CC
87  };
88  };
89  std::vector<Event> events;
90 
91  typedef std::array<float, MorphPlan::N_CONTROL_INPUTS> ModArray;
92 
93  class Voice
94  {
95  public:
96  enum State {
97  STATE_IDLE,
98  STATE_ON,
99  STATE_RELEASE
100  };
101  enum class MonoType {
102  POLY,
103  MONO,
104  SHADOW
105  };
106  MorphPlanVoice *mp_voice;
107 
108  State state;
109  MonoType mono_type;
110  bool pedal;
111  int midi_note;
112  int channel;
113  double gain;
114  double freq;
115  double pitch_bend_freq;
116  double pitch_bend_factor;
117  int pitch_bend_steps;
118  int note_id;
119  int clap_id;
120 
121  ModArray modulation;
122 
123  Voice() :
124  mp_voice (NULL),
125  state (STATE_IDLE),
126  pedal (false)
127  {
128  modulation.fill (0);
129  }
130  ~Voice()
131  {
132  mp_voice = NULL;
133  }
134  };
135 
136  constexpr static int MAX_VOICES = 256;
137 
138  MorphPlanSynth morph_plan_synth;
139  InstEditSynth m_inst_edit_synth;
140 
141  std::vector<Voice> voices;
142  std::vector<Voice *> idle_voices;
143  std::vector<Voice *> active_voices;
144  ModArray global_modulation;
145  double m_mix_freq;
146  double m_gain = 1;
147  double m_tempo = 120;
148  double m_ppq_pos = 0;
149  TimeInfoGenerator m_time_info_gen;
150  bool pedal_down;
151  uint64 audio_time_stamp;
152  bool mono_enabled;
153  float portamento_glide;
154  int portamento_note_id;
155  int next_note_id;
156  bool inst_edit = false;
157  bool m_control_by_cc = false;
158  RTMemoryArea m_rt_memory_area;
159  NotifyBuffer m_notify_buffer;
160  MidiSynthCallbacks *m_process_callbacks = nullptr;
161 
162  std::vector<float> control = std::vector<float> (MorphPlan::N_CONTROL_INPUTS);
163 
164  Voice *alloc_voice();
165  void free_unused_voices();
166  bool update_mono_voice();
167  float freq_from_note (float note);
168  void notify_active_voice_status();
169 
170  void set_mono_enabled (bool new_value);
171  void process_audio (float *output, size_t n_values);
172  void process_note_on (const NoteEvent& note);
173  void process_note_off (int channel, int midi_note);
174  void process_midi_controller (int controller, int value);
175  void process_pitch_bend (int channel, double semi_tones);
176  void process_mod_value (const ModValueEvent& mod);
177  void start_pitch_bend (Voice *voice, double dest_freq, double time_ms);
178  void kill_all_active_voices();
179 
180 public:
181  MidiSynth (double mix_freq, size_t n_voices);
182 
183  void add_midi_event (size_t offset, const unsigned char *midi_data);
184  void process (float *output, size_t n_values, MidiSynthCallbacks *process_callbacks = nullptr);
185 
186  void add_note_on_event (uint offset, int clap_id, int channel, int key, float velocity);
187  void add_note_off_event (uint offset, int channel, int key);
188  void add_control_input_event (uint offset, int i, float value);
189  void add_pitch_expression_event (uint offset, float value, int channel, int key);
190  void add_modulation_event (uint offset, int i, float value, int clap_id, int channel, int key);
191 
192  void set_control_input (int i, float value);
193 
194  void set_tempo (double tempo);
195  void set_ppq_pos (double ppq_pos);
196  MorphPlanSynth::UpdateP prepare_update (const MorphPlan& plan);
197  void apply_update (MorphPlanSynth::UpdateP update);
198  double mix_freq() const;
199 
200  size_t active_voice_count() const;
201 
202  void set_inst_edit (bool inst_edit);
203  void set_gain (double gain);
204  void set_control_by_cc (bool control_by_cc);
205  InstEditSynth *inst_edit_synth();
206  NotifyBuffer *notify_buffer();
207 };
208 
210 {
211 public:
212  virtual
214  {
215  }
216  static SynthNotifyEvent *
217  create (NotifyBuffer& buffer);
218 };
219 
220 enum NotifyEventType
221 {
222  INST_EDIT_VOICE_EVENT = 748293, // some random number
223  VOICE_OP_VALUES_EVENT,
224  ACTIVE_VOICE_STATUS_EVENT
225 };
226 
228 {
229  struct Voice
230  {
231  int note;
232  int layer;
233  float current_pos;
234  float fundamental_note;
235  };
236  InstEditVoiceEvent (NotifyBuffer& buffer) :
237  voices (buffer.read_seq<Voice>()),
238  peak (buffer.read_float())
239  {
240  }
241  std::vector<Voice> voices;
242  float peak;
243 };
244 
246 {
247  struct Voice
248  {
249  uintptr_t voice;
250  uintptr_t op;
251  float value;
252  };
253  VoiceOpValuesEvent (NotifyBuffer& buffer) :
254  voices (buffer.read_seq<Voice>())
255  {
256  }
257  std::vector<Voice> voices;
258 };
259 
261 {
263  voice (buffer.read_seq<uintptr_t>()),
264  velocity (buffer.read_seq<float>())
265  {
266  for (auto& ctrl : control)
267  ctrl = buffer.read_seq<float>();
268  }
269  std::vector<uintptr_t> voice;
270  std::vector<float> velocity;
271  std::vector<float> control[MorphPlan::N_CONTROL_INPUTS];
272 };
273 
274 }
275 
276 #endif /* SPECTMORPH_MIDI_SYNTH_HH */
Definition: sminsteditsynth.hh:17
Definition: smmidisynth.hh:27
Definition: smmorphplansynth.hh:20
Definition: smmorphplanvoice.hh:16
Definition: smmorphplan.hh:18
Definition: smnotifybuffer.hh:29
Definition: smrtmemory.hh:16
Definition: smmidisynth.hh:210
Definition: smtimeinfo.hh:18
Definition: smmidisynth.hh:261
Definition: smmidisynth.hh:230
Definition: smmidisynth.hh:228
Definition: smmidisynth.hh:16
Definition: smmidisynth.hh:248
Definition: smmidisynth.hh:246