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>, EventRef<true>,
00186 Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7> {
00187 public:
00188
00191 typedef Plugin<D, URIMap<true>, EventRef<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
00340 if (ev) {
00341 if (ev->type == m_midi_type)
00342 static_cast<D*>(this)->handle_midi(ev->size, event_data);
00343 else if (ev->type == 0)
00344
00345
00346 Parent::event_unref(ev);
00347 }
00348 }
00349
00350 }
00351
00352
00364 void add_audio_outputs(uint32_t p1 = -1, uint32_t p2 = -1,
00365 uint32_t p3 = -1, uint32_t p4 = -1,
00366 uint32_t p5 = -1, uint32_t p6 = -1) {
00367 if (p1 == uint32_t(-1))
00368 return;
00369 m_audio_ports.push_back(p1);
00370 if (p2 == uint32_t(-1))
00371 return;
00372 m_audio_ports.push_back(p2);
00373 if (p3 == uint32_t(-1))
00374 return;
00375 m_audio_ports.push_back(p3);
00376 if (p4 == uint32_t(-1))
00377 return;
00378 m_audio_ports.push_back(p4);
00379 if (p5 == uint32_t(-1))
00380 return;
00381 m_audio_ports.push_back(p5);
00382 if (p6 == uint32_t(-1))
00383 return;
00384 m_audio_ports.push_back(p6);
00385 }
00386
00387
00397 void add_voices(V* v01 = 0, V* v02 = 0, V* v03 = 0, V* v04 = 0, V* v05 = 0,
00398 V* v06 = 0, V* v07 = 0, V* v08 = 0, V* v09 = 0, V* v10 = 0,
00399 V* v11 = 0, V* v12 = 0, V* v13 = 0, V* v14 = 0, V* v15 = 0,
00400 V* v16 = 0, V* v17 = 0, V* v18 = 0, V* v19 = 0, V* v20 = 0){
00401 if (v01 == 0)
00402 return;
00403 m_voices.push_back(v01);
00404 if (v02 == 0)
00405 return;
00406 m_voices.push_back(v02);
00407 if (v03 == 0)
00408 return;
00409 m_voices.push_back(v03);
00410 if (v04 == 0)
00411 return;
00412 m_voices.push_back(v04);
00413 if (v05 == 0)
00414 return;
00415 m_voices.push_back(v05);
00416 if (v06 == 0)
00417 return;
00418 m_voices.push_back(v06);
00419 if (v07 == 0)
00420 return;
00421 m_voices.push_back(v07);
00422 if (v08 == 0)
00423 return;
00424 m_voices.push_back(v08);
00425 if (v09 == 0)
00426 return;
00427 m_voices.push_back(v09);
00428 if (v10 == 0)
00429 return;
00430 m_voices.push_back(v10);
00431 if (v11 == 0)
00432 return;
00433 m_voices.push_back(v11);
00434 if (v12 == 0)
00435 return;
00436 m_voices.push_back(v12);
00437 if (v13 == 0)
00438 return;
00439 m_voices.push_back(v13);
00440 if (v14 == 0)
00441 return;
00442 m_voices.push_back(v14);
00443 if (v15 == 0)
00444 return;
00445 m_voices.push_back(v15);
00446 if (v16 == 0)
00447 return;
00448 m_voices.push_back(v16);
00449 if (v17 == 0)
00450 return;
00451 m_voices.push_back(v17);
00452 if (v18 == 0)
00453 return;
00454 m_voices.push_back(v18);
00455 if (v19 == 0)
00456 return;
00457 m_voices.push_back(v19);
00458 if (v20 == 0)
00459 return;
00460 m_voices.push_back(v20);
00461 }
00462 protected:
00463
00467 template <typename T> T*& p(uint32_t port) {
00468 return reinterpret_cast<T*&>(Parent::m_ports[port]);
00469 }
00470
00473 float*& p(uint32_t port) {
00474 return reinterpret_cast<float*&>(Parent::m_ports[port]);
00475 }
00476
00477
00480 std::vector<V*> m_voices;
00481
00484 std::vector<uint32_t> m_audio_ports;
00485
00488 uint32_t m_midi_input;
00489
00492 uint32_t m_midi_type;
00493
00494 };
00495
00496 }
00497
00498
00499 #endif