21 #ifndef LVTK_SYNTH_HPP 22 #define LVTK_SYNTH_HPP 28 #include <lvtk/plugin.hpp> 35 static const unsigned char INVALID_KEY = 255;
40 static inline float key2hz(
unsigned char key) {
41 return 440.0f * std::pow(2.0f, (key - 69) / 12.0f);
61 void on(
unsigned char key,
unsigned char velocity) { }
67 void off(
unsigned char velocity) { }
73 unsigned char get_key()
const {
return lvtk::INVALID_KEY; }
80 void render(uint32_t from, uint32_t to) { }
86 void set_port_buffers(vector<void*>& ports) { m_ports = &ports; }
91 template <
typename T>
inline T*&
p(uint32_t port) {
92 return reinterpret_cast<T*&
>((*m_ports)[port]);
96 float*&
p(uint32_t port) {
97 return reinterpret_cast<float*&
>((*m_ports)[port]);
101 vector<void*>* m_ports;
178 template <
class V,
class D,
179 class Ext1 = end,
class Ext2 = end,
class Ext3 = end,
180 class Ext4 = end,
class Ext5 = end,
class Ext6 = end,
182 class Synth :
public Plugin<D, URID<true>, Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7>
196 Synth(uint32_t ports, uint32_t midi_input)
198 m_midi_input (midi_input)
200 m_midi_type = Parent::map (LV2_MIDI__MidiEvent);
207 for (
unsigned i = 0; i < m_voices.size(); ++i)
224 for (
unsigned i = 0; i < m_voices.size(); ++i)
226 if (m_voices[i]->
get_key() == lvtk::INVALID_KEY)
248 if (size != 3)
return;
249 LV2_Midi_Message_Type type (lv2_midi_message_type (data));
254 static_cast<D*
>(
this)->find_free_voice(data[1], data[2]);
255 if (voice < m_voices.size())
256 m_voices[voice]->
on(data[1], data[2]);
258 else if (data[0] == 0x80)
260 for (
unsigned i = 0; i < m_voices.size(); ++i)
262 if (m_voices[i]->
get_key() == data[1])
264 m_voices[i]->off(data[2]);
272 handle_atom_event (LV2_Atom_Event* ev) { }
310 run(uint32_t sample_count)
312 D* synth =
static_cast<D*
>(
this);
315 for (
unsigned i = 0; i < m_audio_ports.size(); ++i)
316 std::memset(
p(m_audio_ports[i]), 0,
sizeof(float) * sample_count);
319 for (
unsigned i = 0; i < m_voices.size(); ++i)
320 m_voices[i]->set_port_buffers(Parent::m_ports);
322 const LV2_Atom_Sequence* seq = p<LV2_Atom_Sequence> (m_midi_input);
323 uint32_t last_frame = 0;
325 for (LV2_Atom_Event* ev = lv2_atom_sequence_begin (&seq->body);
326 !lv2_atom_sequence_is_end(&seq->body, seq->atom.size, ev);
327 ev = lv2_atom_sequence_next (ev))
329 synth->pre_process (last_frame, ev->time.frames);
330 for (uint32_t i = 0; i < m_voices.size(); ++i)
331 m_voices[i]->
render (last_frame, ev->time.frames);
332 synth->post_process (last_frame, ev->time.frames);
334 if (ev->body.type == m_midi_type)
335 synth->handle_midi (ev->body.size, (uint8_t*) LV2_ATOM_BODY (&ev->body));
337 synth->handle_atom_event (ev);
339 last_frame = ev->time.frames;
342 if (last_frame < sample_count)
344 synth->pre_process (last_frame, sample_count);
345 for (uint32_t i = 0; i < m_voices.size(); ++i)
346 m_voices[i]->
render (last_frame, sample_count);
347 synth->post_process (last_frame, sample_count);
365 uint32_t p3 = -1, uint32_t p4 = -1,
366 uint32_t p5 = -1, uint32_t p6 = -1)
368 if (p1 == uint32_t(-1))
370 m_audio_ports.push_back(p1);
371 if (p2 == uint32_t(-1))
373 m_audio_ports.push_back(p2);
374 if (p3 == uint32_t(-1))
376 m_audio_ports.push_back(p3);
377 if (p4 == uint32_t(-1))
379 m_audio_ports.push_back(p4);
380 if (p5 == uint32_t(-1))
382 m_audio_ports.push_back(p5);
383 if (p6 == uint32_t(-1))
385 m_audio_ports.push_back(p6);
399 void add_voices(V* v01 = 0, V* v02 = 0, V* v03 = 0, V* v04 = 0, V* v05 = 0,
400 V* v06 = 0, V* v07 = 0, V* v08 = 0, V* v09 = 0, V* v10 = 0,
401 V* v11 = 0, V* v12 = 0, V* v13 = 0, V* v14 = 0, V* v15 = 0,
402 V* v16 = 0, V* v17 = 0, V* v18 = 0, V* v19 = 0, V* v20 = 0)
406 m_voices.push_back(v01);
409 m_voices.push_back(v02);
412 m_voices.push_back(v03);
415 m_voices.push_back(v04);
418 m_voices.push_back(v05);
421 m_voices.push_back(v06);
424 m_voices.push_back(v07);
427 m_voices.push_back(v08);
430 m_voices.push_back(v09);
433 m_voices.push_back(v10);
436 m_voices.push_back(v11);
439 m_voices.push_back(v12);
442 m_voices.push_back(v13);
445 m_voices.push_back(v14);
448 m_voices.push_back(v15);
451 m_voices.push_back(v16);
454 m_voices.push_back(v17);
457 m_voices.push_back(v18);
460 m_voices.push_back(v19);
463 m_voices.push_back(v20);
470 template <
typename T> T*&
472 return reinterpret_cast<T*&
>(Parent::m_ports[port]);
478 return reinterpret_cast<float*&
>(Parent::m_ports[port]);
485 vector<uint32_t> m_audio_ports;
488 uint32_t m_midi_input;
491 LV2_URID m_midi_type;
unsigned char get_key() const
Definition: synth.hpp:73
void pre_process(uint32_t from, uint32_t to)
Definition: synth.hpp:286
void post_process(uint32_t from, uint32_t to)
Definition: synth.hpp:301
float *& p(uint32_t port)
Definition: synth.hpp:96
void render(uint32_t from, uint32_t to)
Definition: synth.hpp:80
void on(unsigned char key, unsigned char velocity)
Definition: synth.hpp:61
void off(unsigned char velocity)
Definition: synth.hpp:67
void handle_midi(uint32_t size, unsigned char *data)
Definition: synth.hpp:246
void add_voices(V *v01=0, V *v02=0, V *v03=0, V *v04=0, V *v05=0, V *v06=0, V *v07=0, V *v08=0, V *v09=0, V *v10=0, V *v11=0, V *v12=0, V *v13=0, V *v14=0, V *v15=0, V *v16=0, V *v17=0, V *v18=0, V *v19=0, V *v20=0)
Definition: synth.hpp:399
Definition: feature.hpp:34
T *& p(uint32_t port)
Definition: synth.hpp:91
Definition: plugin.hpp:159
float *& p(uint32_t port)
Definition: synth.hpp:477
void add_audio_outputs(uint32_t p1=-1, uint32_t p2=-1, uint32_t p3=-1, uint32_t p4=-1, uint32_t p5=-1, uint32_t p6=-1)
Definition: synth.hpp:364
unsigned find_free_voice(unsigned char key, unsigned char velocity)
Definition: synth.hpp:222
void run(uint32_t sample_count)
Definition: synth.hpp:310
T *& p(uint32_t port)
Definition: synth.hpp:471
~Synth()
Definition: synth.hpp:205
Synth(uint32_t ports, uint32_t midi_input)
Definition: synth.hpp:196
Definition: synth.hpp:182