SpectMorph
smsynthinterface.hh
1 // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl-2.1.html
2 
3 #ifndef SPECTMORPH_SYNTH_INTERFACE_HH
4 #define SPECTMORPH_SYNTH_INTERFACE_HH
5 
6 #include "smmidisynth.hh"
7 #include "smproject.hh"
8 #include "smmorphplansynth.hh"
9 
10 namespace SpectMorph
11 {
12 
14 {
15  Project *m_project = nullptr;
16 public:
17  SynthInterface (Project *project)
18  {
19  m_project = project;
20  }
21  Project *
22  get_project()
23  {
24  return m_project;
25  }
26  template<class DATA>
27  void
28  send_control_event (const std::function<void(Project *)>& func, DATA *data = nullptr)
29  {
30  m_project->synth_take_control_event (new InstFunc (func, [data]() { delete data;}));
31  }
32  void
33  send_control_event (const std::function<void(Project *)>& func)
34  {
35  m_project->synth_take_control_event (new InstFunc (func, []() {}));
36  }
37  void
38  synth_inst_edit_update (bool active, WavSet *take_wav_set, WavSet *ref_wav_set)
39  {
40  /* ownership:
41  * - take_wav_set is owned by the event
42  * - ref_wav_set is _not_ owned and will not be freed
43  */
44  struct EventData
45  {
46  InstEditSynth::Decoders decoders;
47  } *event_data = new EventData;
48 
49  event_data->decoders = m_project->midi_synth()->inst_edit_synth()->create_decoders (take_wav_set, ref_wav_set);
50 
51  send_control_event (
52  [=] (Project *project)
53  {
54  project->midi_synth()->set_inst_edit (active);
55 
56  if (active)
57  project->midi_synth()->inst_edit_synth()->swap_decoders (event_data->decoders);
58  },
59  event_data);
60  }
61  void
62  synth_inst_edit_gain (float gain)
63  {
64  send_control_event (
65  [=] (Project *project)
66  {
67  project->midi_synth()->inst_edit_synth()->set_gain (gain);
68  });
69  }
70  void
71  synth_inst_edit_midi_to_reference (bool midi_to_reference)
72  {
73  send_control_event (
74  [=] (Project *project)
75  {
76  project->midi_synth()->inst_edit_synth()->set_midi_to_reference (midi_to_reference);
77  });
78  }
79  void
80  synth_inst_edit_note (int note, bool on, unsigned int layer)
81  {
82  send_control_event (
83  [=] (Project *project)
84  {
85  if (on)
86  project->midi_synth()->inst_edit_synth()->process_note_on (/* channel */ 0, note, /* clap id */ -1, layer);
87  else
88  project->midi_synth()->inst_edit_synth()->process_note_off (/* channel */ 0, note, layer);
89  });
90  }
91  void
92  emit_apply_update (MorphPlanSynth::UpdateP update)
93  {
94  /* ownership of update is transferred to the event */
95  struct EventData
96  {
97  MorphPlanSynth::UpdateP update;
98  } *event_data = new EventData;
99 
100  event_data->update = update;
101  send_control_event (
102  [=] (Project *project)
103  {
104  project->midi_synth()->apply_update (event_data->update);
105  },
106  event_data);
107  }
108  void
109  emit_update_gain (double gain)
110  {
111  send_control_event (
112  [=] (Project *project)
113  {
114  project->midi_synth()->set_gain (gain);
115  });
116  }
117  void
118  emit_add_rebuild_result (int object_id, WavSet *take_wav_set)
119  {
120  /* ownership of take_wav_set is transferred to the event */
121  struct EventData
122  {
123  std::unique_ptr<WavSet> wav_set;
124  } *event_data = new EventData;
125 
126  event_data->wav_set.reset (take_wav_set);
127 
128  send_control_event (
129  [=] (Project *project)
130  {
131  // uses swap to assign the new unique ptr and ensure the old one gets freed
132  // outside the audio thread
133  project->add_rebuild_result (object_id, event_data->wav_set);
134  },
135  event_data);
136  }
137  void
138  emit_clear_wav_sets()
139  {
140  struct EventData
141  {
142  std::vector<std::unique_ptr<WavSet>> wav_sets;
143  } *event_data = new EventData;
144 
145  /* avoid malloc in audio threads if wav sets are added */
146  event_data->wav_sets.reserve (Project::WAV_SETS_RESERVE);
147 
148  send_control_event (
149  [=] (Project *project)
150  {
151  // uses swap to ensure that old wav_sets get freed outside the audio thread
152  project->clear_wav_sets (event_data->wav_sets);
153  },
154  event_data);
155  }
156  void
157  generate_notify_events()
158  {
159  NotifyBuffer *notify_buffer = m_project->notify_buffer();
160  if (notify_buffer->start_read())
161  {
162  while (notify_buffer->remaining())
163  {
164  SynthNotifyEvent *sn_event = SynthNotifyEvent::create (*notify_buffer);
165  signal_notify_event (sn_event);
166  delete sn_event;
167  }
168  notify_buffer->end_read();
169  }
170  else
171  {
172  // this allocates memory, but it is OK because we are in the UI thread
173  notify_buffer->resize_if_necessary();
174  }
175  }
176  Signal<SynthNotifyEvent *> signal_notify_event;
177 };
178 
179 }
180 
181 #endif
Definition: smnotifybuffer.hh:29
Definition: smproject.hh:67
Definition: smsignal.hh:150
Definition: smsynthinterface.hh:14
Definition: smmidisynth.hh:210
Definition: smwavset.hh:29
Definition: sminsteditsynth.hh:19
Definition: smproject.hh:35