30 #include <lv2plugin.hpp>
31 #include <lv2_event_helpers.h>
37 static const unsigned char INVALID_KEY = 255;
42 static inline float key2hz(
unsigned char key) {
43 return 8.1758 * std::pow(1.0594, key);
62 void on(
unsigned char key,
unsigned char velocity) { }
68 void off(
unsigned char velocity) { }
73 unsigned char get_key()
const {
return LV2::INVALID_KEY; }
80 void render(uint32_t from, uint32_t to) { }
86 void set_port_buffers(std::vector<void*>& ports) { m_ports = &ports; }
92 template <
typename T>
inline T*&
p(uint32_t port) {
93 return reinterpret_cast<T*&
>((*m_ports)[port]);
98 float*&
p(uint32_t port) {
99 return reinterpret_cast<float*&
>((*m_ports)[port]);
104 std::vector<void*>* m_ports;
181 template <
class V,
class D,
182 class Ext1 = End,
class Ext2 = End,
class Ext3 = End,
183 class Ext4 = End,
class Ext5 = End,
class Ext6 = End,
186 Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7> {
192 Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7>
202 Synth(uint32_t ports, uint32_t midi_input)
204 m_midi_input(midi_input) {
206 Parent::uri_to_id(LV2_EVENT_URI,
207 "http://lv2plug.in/ns/ext/midi#MidiEvent");
214 for (
unsigned i = 0; i < m_voices.size(); ++i)
229 for (
unsigned i = 0; i < m_voices.size(); ++i) {
230 if (m_voices[i]->get_key() == INVALID_KEY)
250 if (data[0] == 0x90) {
253 if (voice < m_voices.size())
254 m_voices[voice]->on(data[1], data[2]);
256 else if (data[0] == 0x80) {
257 for (
unsigned i = 0; i < m_voices.size(); ++i) {
258 if (m_voices[i]->get_key() == data[1]) {
259 m_voices[i]->off(data[2]);
302 void run(uint32_t sample_count) {
305 for (
unsigned i = 0; i < m_audio_ports.size(); ++i)
306 std::memset(
p(m_audio_ports[i]), 0,
307 sizeof(
float) * sample_count);
310 for (
unsigned i = 0; i < m_voices.size(); ++i)
311 m_voices[i]->set_port_buffers(Parent::m_ports);
313 LV2_Event_Iterator iter;
314 lv2_event_begin(&iter, p<LV2_Event_Buffer>(m_midi_input));
317 uint32_t samples_done = 0;
319 while (samples_done < sample_count) {
320 uint32_t to = sample_count;
322 if (lv2_event_is_valid(&iter)) {
323 ev = lv2_event_get(&iter, &event_data);
325 lv2_event_increment(&iter);
327 if (to > samples_done) {
328 static_cast<D*
>(
this)->
pre_process(samples_done, to);
329 for (
unsigned i = 0; i < m_voices.size(); ++i)
330 m_voices[i]->render(samples_done, to);
340 if (ev->type == m_midi_type)
341 static_cast<D*
>(
this)->
handle_midi(ev->size, event_data);
360 uint32_t p3 = -1, uint32_t p4 = -1,
361 uint32_t p5 = -1, uint32_t p6 = -1) {
362 if (p1 == uint32_t(-1))
364 m_audio_ports.push_back(p1);
365 if (p2 == uint32_t(-1))
367 m_audio_ports.push_back(p2);
368 if (p3 == uint32_t(-1))
370 m_audio_ports.push_back(p3);
371 if (p4 == uint32_t(-1))
373 m_audio_ports.push_back(p4);
374 if (p5 == uint32_t(-1))
376 m_audio_ports.push_back(p5);
377 if (p6 == uint32_t(-1))
379 m_audio_ports.push_back(p6);
392 void add_voices(V* v01 = 0, V* v02 = 0, V* v03 = 0, V* v04 = 0, V* v05 = 0,
393 V* v06 = 0, V* v07 = 0, V* v08 = 0, V* v09 = 0, V* v10 = 0,
394 V* v11 = 0, V* v12 = 0, V* v13 = 0, V* v14 = 0, V* v15 = 0,
395 V* v16 = 0, V* v17 = 0, V* v18 = 0, V* v19 = 0, V* v20 = 0){
398 m_voices.push_back(v01);
401 m_voices.push_back(v02);
404 m_voices.push_back(v03);
407 m_voices.push_back(v04);
410 m_voices.push_back(v05);
413 m_voices.push_back(v06);
416 m_voices.push_back(v07);
419 m_voices.push_back(v08);
422 m_voices.push_back(v09);
425 m_voices.push_back(v10);
428 m_voices.push_back(v11);
431 m_voices.push_back(v12);
434 m_voices.push_back(v13);
437 m_voices.push_back(v14);
440 m_voices.push_back(v15);
443 m_voices.push_back(v16);
446 m_voices.push_back(v17);
449 m_voices.push_back(v18);
452 m_voices.push_back(v19);
455 m_voices.push_back(v20);
462 template <
typename T> T*&
p(uint32_t port) {
463 return reinterpret_cast<T*&
>(Parent::m_ports[port]);
468 float*&
p(uint32_t port) {
469 return reinterpret_cast<float*&
>(Parent::m_ports[port]);
475 std::vector<V*> m_voices;
479 std::vector<uint32_t> m_audio_ports;
483 uint32_t m_midi_input;
487 uint32_t m_midi_type;
Definition: lv2plugin.hpp:137
Definition: lv2synth.hpp:186
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: lv2synth.hpp:359
float *& p(uint32_t port)
Definition: lv2synth.hpp:468
Synth(uint32_t ports, uint32_t midi_input)
Definition: lv2synth.hpp:202
~Synth()
Definition: lv2synth.hpp:213
void handle_midi(uint32_t size, unsigned char *data)
Definition: lv2synth.hpp:247
void run(uint32_t sample_count)
Definition: lv2synth.hpp:302
T *& p(uint32_t port)
Definition: lv2synth.hpp:462
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: lv2synth.hpp:392
unsigned find_free_voice(unsigned char key, unsigned char velocity)
Definition: lv2synth.hpp:228
void post_process(uint32_t from, uint32_t to)
Definition: lv2synth.hpp:293
void pre_process(uint32_t from, uint32_t to)
Definition: lv2synth.hpp:278
Definition: lv2synth.hpp:50
void render(uint32_t from, uint32_t to)
Definition: lv2synth.hpp:80
float *& p(uint32_t port)
Definition: lv2synth.hpp:98
T *& p(uint32_t port)
Definition: lv2synth.hpp:92
unsigned char get_key() const
Definition: lv2synth.hpp:73
void on(unsigned char key, unsigned char velocity)
Definition: lv2synth.hpp:62
void off(unsigned char velocity)
Definition: lv2synth.hpp:68