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
00058 void on(unsigned char key, unsigned char velocity) { }
00059
00064 void off(unsigned char velocity) { }
00065
00069 unsigned char get_key() const { return LV2::INVALID_KEY; }
00070
00076 void render(uint32_t from, uint32_t to) { }
00077
00082 void set_port_buffers(std::vector<void*>& ports) { m_ports = &ports; }
00083
00084 protected:
00085
00088 template <typename T> inline T*& p(uint32_t port) {
00089 return reinterpret_cast<T*&>((*m_ports)[port]);
00090 }
00091
00094 float*& p(uint32_t port) {
00095 return reinterpret_cast<float*&>((*m_ports)[port]);
00096 }
00097
00100 std::vector<void*>* m_ports;
00101 };
00102
00103
00177 template <class V, class D,
00178 class Ext1 = End, class Ext2 = End, class Ext3 = End,
00179 class Ext4 = End, class Ext5 = End, class Ext6 = End,
00180 class Ext7 = End>
00181 class Synth : public Plugin<D, URIMap<true>, EventRef<true>,
00182 Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7> {
00183 public:
00184
00187 typedef Plugin<D, URIMap<true>, EventRef<true>,
00188 Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7>
00189 Parent;
00190
00191
00198 Synth(uint32_t ports, uint32_t midi_input)
00199 : Parent(ports),
00200 m_midi_input(midi_input) {
00201 m_midi_type =
00202 Parent::uri_to_id(LV2_EVENT_URI,
00203 "http://lv2plug.in/ns/ext/midi#MidiEvent");
00204 }
00205
00206
00209 ~Synth() {
00210 for (unsigned i = 0; i < m_voices.size(); ++i)
00211 delete m_voices[i];
00212 }
00213
00214
00224 unsigned find_free_voice(unsigned char key, unsigned char velocity) {
00225 for (unsigned i = 0; i < m_voices.size(); ++i) {
00226 if (m_voices[i]->get_key() == INVALID_KEY)
00227 return i;
00228 }
00229 return 0;
00230 }
00231
00232
00235 void handle_midi(uint32_t size, unsigned char* data) {
00236 if (size != 3)
00237 return;
00238 if (data[0] == 0x90) {
00239 unsigned voice =
00240 static_cast<D*>(this)->find_free_voice(data[1], data[2]);
00241 if (voice < m_voices.size())
00242 m_voices[voice]->on(data[1], data[2]);
00243 }
00244 else if (data[0] == 0x80) {
00245 for (unsigned i = 0; i < m_voices.size(); ++i) {
00246 if (m_voices[i]->get_key() == data[1]) {
00247 m_voices[i]->off(data[2]);
00248 break;
00249 }
00250 }
00251 }
00252 }
00253
00254
00266 void pre_process(uint32_t from, uint32_t to) {
00267
00268 }
00269
00270
00281 void post_process(uint32_t from, uint32_t to) {
00282
00283 }
00284
00285
00290 void run(uint32_t sample_count) {
00291
00292
00293 for (unsigned i = 0; i < m_audio_ports.size(); ++i)
00294 std::memset(p(m_audio_ports[i]), 0,
00295 sizeof(float) * sample_count);
00296
00297
00298 if (m_voices.size() == 0)
00299 return;
00300
00301
00302 for (unsigned i = 0; i < m_voices.size(); ++i)
00303 m_voices[i]->set_port_buffers(Parent::m_ports);
00304
00305 LV2_Event_Iterator iter;
00306 if (!lv2_event_begin(&iter, p<LV2_Event_Buffer>(m_midi_input)))
00307 return;
00308
00309 uint8_t* event_data;
00310 uint32_t samples_done = 0;
00311
00312 while (samples_done < sample_count) {
00313 uint32_t to = sample_count;
00314 LV2_Event* ev = 0;
00315 if (lv2_event_is_valid(&iter)) {
00316 ev = lv2_event_get(&iter, &event_data);
00317 to = ev->frames;
00318 lv2_event_increment(&iter);
00319 }
00320 if (to > samples_done) {
00321 static_cast<D*>(this)->pre_process(samples_done, to);
00322 for (unsigned i = 0; i < m_voices.size(); ++i)
00323 m_voices[i]->render(samples_done, to);
00324 static_cast<D*>(this)->post_process(samples_done, to);
00325 samples_done = to;
00326 }
00327
00328
00329
00330
00331
00332
00333 if (ev) {
00334 if (ev->type == m_midi_type)
00335 handle_midi(ev->size, event_data);
00336 else if (ev->type == 0)
00337
00338
00339 Parent::event_unref(ev);
00340 }
00341 }
00342
00343 }
00344
00345
00356 void add_audio_outputs(uint32_t p1 = -1, uint32_t p2 = -1,
00357 uint32_t p3 = -1, uint32_t p4 = -1,
00358 uint32_t p5 = -1, uint32_t p6 = -1) {
00359 if (p1 == uint32_t(-1))
00360 return;
00361 m_audio_ports.push_back(p1);
00362 if (p2 == uint32_t(-1))
00363 return;
00364 m_audio_ports.push_back(p2);
00365 if (p3 == uint32_t(-1))
00366 return;
00367 m_audio_ports.push_back(p3);
00368 if (p4 == uint32_t(-1))
00369 return;
00370 m_audio_ports.push_back(p4);
00371 if (p5 == uint32_t(-1))
00372 return;
00373 m_audio_ports.push_back(p5);
00374 if (p6 == uint32_t(-1))
00375 return;
00376 m_audio_ports.push_back(p6);
00377 }
00378
00379
00386 void add_voices(V* v01 = 0, V* v02 = 0, V* v03 = 0, V* v04 = 0, V* v05 = 0,
00387 V* v06 = 0, V* v07 = 0, V* v08 = 0, V* v09 = 0, V* v10 = 0,
00388 V* v11 = 0, V* v12 = 0, V* v13 = 0, V* v14 = 0, V* v15 = 0,
00389 V* v16 = 0, V* v17 = 0, V* v18 = 0, V* v19 = 0, V* v20 = 0){
00390 if (v01 == 0)
00391 return;
00392 m_voices.push_back(v01);
00393 if (v02 == 0)
00394 return;
00395 m_voices.push_back(v02);
00396 if (v03 == 0)
00397 return;
00398 m_voices.push_back(v03);
00399 if (v04 == 0)
00400 return;
00401 m_voices.push_back(v04);
00402 if (v05 == 0)
00403 return;
00404 m_voices.push_back(v05);
00405 if (v06 == 0)
00406 return;
00407 m_voices.push_back(v06);
00408 if (v07 == 0)
00409 return;
00410 m_voices.push_back(v07);
00411 if (v08 == 0)
00412 return;
00413 m_voices.push_back(v08);
00414 if (v09 == 0)
00415 return;
00416 m_voices.push_back(v09);
00417 if (v10 == 0)
00418 return;
00419 m_voices.push_back(v10);
00420 if (v11 == 0)
00421 return;
00422 m_voices.push_back(v11);
00423 if (v12 == 0)
00424 return;
00425 m_voices.push_back(v12);
00426 if (v13 == 0)
00427 return;
00428 m_voices.push_back(v13);
00429 if (v14 == 0)
00430 return;
00431 m_voices.push_back(v14);
00432 if (v15 == 0)
00433 return;
00434 m_voices.push_back(v15);
00435 if (v16 == 0)
00436 return;
00437 m_voices.push_back(v16);
00438 if (v17 == 0)
00439 return;
00440 m_voices.push_back(v17);
00441 if (v18 == 0)
00442 return;
00443 m_voices.push_back(v18);
00444 if (v19 == 0)
00445 return;
00446 m_voices.push_back(v19);
00447 if (v20 == 0)
00448 return;
00449 m_voices.push_back(v20);
00450 }
00451 protected:
00452
00456 template <typename T> T*& p(uint32_t port) {
00457 return reinterpret_cast<T*&>(Parent::m_ports[port]);
00458 }
00459
00462 float*& p(uint32_t port) {
00463 return reinterpret_cast<float*&>(Parent::m_ports[port]);
00464 }
00465
00466
00469 std::vector<V*> m_voices;
00470
00473 std::vector<uint32_t> m_audio_ports;
00474
00477 uint32_t m_midi_input;
00478
00481 uint32_t m_midi_type;
00482
00483 };
00484
00485 }
00486
00487
00488 #endif