00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef LV2SYNTH_HPP
00024 #define LV2SYNTH_HPP
00025
00026 #include <cmath>
00027 #include <cstring>
00028 #include <vector>
00029
00030 #include <lv2plugin.hpp>
00031 #include <lv2_event_helpers.h>
00032
00033
00034 namespace LV2 {
00035
00037 static const unsigned char INVALID_KEY = 255;
00038
00039
00042 static inline float key2hz(unsigned char key) {
00043 return 8.1758 * std::pow(1.0594, key);
00044 }
00045
00046
00050 class Voice {
00051 public:
00052
00062 void on(unsigned char key, unsigned char velocity) { }
00063
00068 void off(unsigned char velocity) { }
00069
00073 unsigned char get_key() const { return LV2::INVALID_KEY; }
00074
00080 void render(uint32_t from, uint32_t to) { }
00081
00086 void set_port_buffers(std::vector<void*>& ports) { m_ports = &ports; }
00087
00088 protected:
00089
00092 template <typename T> inline T*& p(uint32_t port) {
00093 return reinterpret_cast<T*&>((*m_ports)[port]);
00094 }
00095
00098 float*& p(uint32_t port) {
00099 return reinterpret_cast<float*&>((*m_ports)[port]);
00100 }
00101
00104 std::vector<void*>* m_ports;
00105 };
00106
00107
00181 template <class V, class D,
00182 class Ext1 = End, class Ext2 = End, class Ext3 = End,
00183 class Ext4 = End, class Ext5 = End, class Ext6 = End,
00184 class Ext7 = End>
00185 class Synth : public Plugin<D, URIMap<true>,
00186 Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7> {
00187 public:
00188
00191 typedef Plugin<D, URIMap<true>,
00192 Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7>
00193 Parent;
00194
00195
00202 Synth(uint32_t ports, uint32_t midi_input)
00203 : Parent(ports),
00204 m_midi_input(midi_input) {
00205 m_midi_type =
00206 Parent::uri_to_id(LV2_EVENT_URI,
00207 "http://lv2plug.in/ns/ext/midi#MidiEvent");
00208 }
00209
00210
00213 ~Synth() {
00214 for (unsigned i = 0; i < m_voices.size(); ++i)
00215 delete m_voices[i];
00216 }
00217
00218
00228 unsigned find_free_voice(unsigned char key, unsigned char velocity) {
00229 for (unsigned i = 0; i < m_voices.size(); ++i) {
00230 if (m_voices[i]->get_key() == INVALID_KEY)
00231 return i;
00232 }
00233 return 0;
00234 }
00235
00236
00247 void handle_midi(uint32_t size, unsigned char* data) {
00248 if (size != 3)
00249 return;
00250 if (data[0] == 0x90) {
00251 unsigned voice =
00252 static_cast<D*>(this)->find_free_voice(data[1], data[2]);
00253 if (voice < m_voices.size())
00254 m_voices[voice]->on(data[1], data[2]);
00255 }
00256 else if (data[0] == 0x80) {
00257 for (unsigned i = 0; i < m_voices.size(); ++i) {
00258 if (m_voices[i]->get_key() == data[1]) {
00259 m_voices[i]->off(data[2]);
00260 break;
00261 }
00262 }
00263 }
00264 }
00265
00266
00278 void pre_process(uint32_t from, uint32_t to) {
00279
00280 }
00281
00282
00293 void post_process(uint32_t from, uint32_t to) {
00294
00295 }
00296
00297
00302 void run(uint32_t sample_count) {
00303
00304
00305 for (unsigned i = 0; i < m_audio_ports.size(); ++i)
00306 std::memset(p(m_audio_ports[i]), 0,
00307 sizeof(float) * sample_count);
00308
00309
00310 for (unsigned i = 0; i < m_voices.size(); ++i)
00311 m_voices[i]->set_port_buffers(Parent::m_ports);
00312
00313 LV2_Event_Iterator iter;
00314 lv2_event_begin(&iter, p<LV2_Event_Buffer>(m_midi_input));
00315
00316 uint8_t* event_data;
00317 uint32_t samples_done = 0;
00318
00319 while (samples_done < sample_count) {
00320 uint32_t to = sample_count;
00321 LV2_Event* ev = 0;
00322 if (lv2_event_is_valid(&iter)) {
00323 ev = lv2_event_get(&iter, &event_data);
00324 to = ev->frames;
00325 lv2_event_increment(&iter);
00326 }
00327 if (to > samples_done) {
00328 static_cast<D*>(this)->pre_process(samples_done, to);
00329 for (unsigned i = 0; i < m_voices.size(); ++i)
00330 m_voices[i]->render(samples_done, to);
00331 static_cast<D*>(this)->post_process(samples_done, to);
00332 samples_done = to;
00333 }
00334
00335
00336
00337
00338
00339 if (ev) {
00340 if (ev->type == m_midi_type)
00341 static_cast<D*>(this)->handle_midi(ev->size, event_data);
00342 }
00343 }
00344
00345 }
00346
00347
00359 void add_audio_outputs(uint32_t p1 = -1, uint32_t p2 = -1,
00360 uint32_t p3 = -1, uint32_t p4 = -1,
00361 uint32_t p5 = -1, uint32_t p6 = -1) {
00362 if (p1 == uint32_t(-1))
00363 return;
00364 m_audio_ports.push_back(p1);
00365 if (p2 == uint32_t(-1))
00366 return;
00367 m_audio_ports.push_back(p2);
00368 if (p3 == uint32_t(-1))
00369 return;
00370 m_audio_ports.push_back(p3);
00371 if (p4 == uint32_t(-1))
00372 return;
00373 m_audio_ports.push_back(p4);
00374 if (p5 == uint32_t(-1))
00375 return;
00376 m_audio_ports.push_back(p5);
00377 if (p6 == uint32_t(-1))
00378 return;
00379 m_audio_ports.push_back(p6);
00380 }
00381
00382
00392 void add_voices(V* v01 = 0, V* v02 = 0, V* v03 = 0, V* v04 = 0, V* v05 = 0,
00393 V* v06 = 0, V* v07 = 0, V* v08 = 0, V* v09 = 0, V* v10 = 0,
00394 V* v11 = 0, V* v12 = 0, V* v13 = 0, V* v14 = 0, V* v15 = 0,
00395 V* v16 = 0, V* v17 = 0, V* v18 = 0, V* v19 = 0, V* v20 = 0){
00396 if (v01 == 0)
00397 return;
00398 m_voices.push_back(v01);
00399 if (v02 == 0)
00400 return;
00401 m_voices.push_back(v02);
00402 if (v03 == 0)
00403 return;
00404 m_voices.push_back(v03);
00405 if (v04 == 0)
00406 return;
00407 m_voices.push_back(v04);
00408 if (v05 == 0)
00409 return;
00410 m_voices.push_back(v05);
00411 if (v06 == 0)
00412 return;
00413 m_voices.push_back(v06);
00414 if (v07 == 0)
00415 return;
00416 m_voices.push_back(v07);
00417 if (v08 == 0)
00418 return;
00419 m_voices.push_back(v08);
00420 if (v09 == 0)
00421 return;
00422 m_voices.push_back(v09);
00423 if (v10 == 0)
00424 return;
00425 m_voices.push_back(v10);
00426 if (v11 == 0)
00427 return;
00428 m_voices.push_back(v11);
00429 if (v12 == 0)
00430 return;
00431 m_voices.push_back(v12);
00432 if (v13 == 0)
00433 return;
00434 m_voices.push_back(v13);
00435 if (v14 == 0)
00436 return;
00437 m_voices.push_back(v14);
00438 if (v15 == 0)
00439 return;
00440 m_voices.push_back(v15);
00441 if (v16 == 0)
00442 return;
00443 m_voices.push_back(v16);
00444 if (v17 == 0)
00445 return;
00446 m_voices.push_back(v17);
00447 if (v18 == 0)
00448 return;
00449 m_voices.push_back(v18);
00450 if (v19 == 0)
00451 return;
00452 m_voices.push_back(v19);
00453 if (v20 == 0)
00454 return;
00455 m_voices.push_back(v20);
00456 }
00457 protected:
00458
00462 template <typename T> T*& p(uint32_t port) {
00463 return reinterpret_cast<T*&>(Parent::m_ports[port]);
00464 }
00465
00468 float*& p(uint32_t port) {
00469 return reinterpret_cast<float*&>(Parent::m_ports[port]);
00470 }
00471
00472
00475 std::vector<V*> m_voices;
00476
00479 std::vector<uint32_t> m_audio_ports;
00480
00483 uint32_t m_midi_input;
00484
00487 uint32_t m_midi_type;
00488
00489 };
00490
00491 }
00492
00493
00494 #endif