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
00239 void handle_midi(uint32_t size, unsigned char* data) {
00240 if (size != 3)
00241 return;
00242 if (data[0] == 0x90) {
00243 unsigned voice =
00244 static_cast<D*>(this)->find_free_voice(data[1], data[2]);
00245 if (voice < m_voices.size())
00246 m_voices[voice]->on(data[1], data[2]);
00247 }
00248 else if (data[0] == 0x80) {
00249 for (unsigned i = 0; i < m_voices.size(); ++i) {
00250 if (m_voices[i]->get_key() == data[1]) {
00251 m_voices[i]->off(data[2]);
00252 break;
00253 }
00254 }
00255 }
00256 }
00257
00258
00270 void pre_process(uint32_t from, uint32_t to) {
00271
00272 }
00273
00274
00285 void post_process(uint32_t from, uint32_t to) {
00286
00287 }
00288
00289
00294 void run(uint32_t sample_count) {
00295
00296
00297 for (unsigned i = 0; i < m_audio_ports.size(); ++i)
00298 std::memset(p(m_audio_ports[i]), 0,
00299 sizeof(float) * sample_count);
00300
00301
00302 if (m_voices.size() == 0)
00303 return;
00304
00305
00306 for (unsigned i = 0; i < m_voices.size(); ++i)
00307 m_voices[i]->set_port_buffers(Parent::m_ports);
00308
00309 LV2_Event_Iterator iter;
00310 if (!lv2_event_begin(&iter, p<LV2_Event_Buffer>(m_midi_input)))
00311 return;
00312
00313 uint8_t* event_data;
00314 uint32_t samples_done = 0;
00315
00316 while (samples_done < sample_count) {
00317 uint32_t to = sample_count;
00318 LV2_Event* ev = 0;
00319 if (lv2_event_is_valid(&iter)) {
00320 ev = lv2_event_get(&iter, &event_data);
00321 to = ev->frames;
00322 lv2_event_increment(&iter);
00323 }
00324 if (to > samples_done) {
00325 static_cast<D*>(this)->pre_process(samples_done, to);
00326 for (unsigned i = 0; i < m_voices.size(); ++i)
00327 m_voices[i]->render(samples_done, to);
00328 static_cast<D*>(this)->post_process(samples_done, to);
00329 samples_done = to;
00330 }
00331
00332
00333
00334
00335
00336
00337 if (ev) {
00338 if (ev->type == m_midi_type)
00339 handle_midi(ev->size, event_data);
00340 else if (ev->type == 0)
00341
00342
00343 Parent::event_unref(ev);
00344 }
00345 }
00346
00347 }
00348
00349
00360 void add_audio_outputs(uint32_t p1 = -1, uint32_t p2 = -1,
00361 uint32_t p3 = -1, uint32_t p4 = -1,
00362 uint32_t p5 = -1, uint32_t p6 = -1) {
00363 if (p1 == uint32_t(-1))
00364 return;
00365 m_audio_ports.push_back(p1);
00366 if (p2 == uint32_t(-1))
00367 return;
00368 m_audio_ports.push_back(p2);
00369 if (p3 == uint32_t(-1))
00370 return;
00371 m_audio_ports.push_back(p3);
00372 if (p4 == uint32_t(-1))
00373 return;
00374 m_audio_ports.push_back(p4);
00375 if (p5 == uint32_t(-1))
00376 return;
00377 m_audio_ports.push_back(p5);
00378 if (p6 == uint32_t(-1))
00379 return;
00380 m_audio_ports.push_back(p6);
00381 }
00382
00383
00390 void add_voices(V* v01 = 0, V* v02 = 0, V* v03 = 0, V* v04 = 0, V* v05 = 0,
00391 V* v06 = 0, V* v07 = 0, V* v08 = 0, V* v09 = 0, V* v10 = 0,
00392 V* v11 = 0, V* v12 = 0, V* v13 = 0, V* v14 = 0, V* v15 = 0,
00393 V* v16 = 0, V* v17 = 0, V* v18 = 0, V* v19 = 0, V* v20 = 0){
00394 if (v01 == 0)
00395 return;
00396 m_voices.push_back(v01);
00397 if (v02 == 0)
00398 return;
00399 m_voices.push_back(v02);
00400 if (v03 == 0)
00401 return;
00402 m_voices.push_back(v03);
00403 if (v04 == 0)
00404 return;
00405 m_voices.push_back(v04);
00406 if (v05 == 0)
00407 return;
00408 m_voices.push_back(v05);
00409 if (v06 == 0)
00410 return;
00411 m_voices.push_back(v06);
00412 if (v07 == 0)
00413 return;
00414 m_voices.push_back(v07);
00415 if (v08 == 0)
00416 return;
00417 m_voices.push_back(v08);
00418 if (v09 == 0)
00419 return;
00420 m_voices.push_back(v09);
00421 if (v10 == 0)
00422 return;
00423 m_voices.push_back(v10);
00424 if (v11 == 0)
00425 return;
00426 m_voices.push_back(v11);
00427 if (v12 == 0)
00428 return;
00429 m_voices.push_back(v12);
00430 if (v13 == 0)
00431 return;
00432 m_voices.push_back(v13);
00433 if (v14 == 0)
00434 return;
00435 m_voices.push_back(v14);
00436 if (v15 == 0)
00437 return;
00438 m_voices.push_back(v15);
00439 if (v16 == 0)
00440 return;
00441 m_voices.push_back(v16);
00442 if (v17 == 0)
00443 return;
00444 m_voices.push_back(v17);
00445 if (v18 == 0)
00446 return;
00447 m_voices.push_back(v18);
00448 if (v19 == 0)
00449 return;
00450 m_voices.push_back(v19);
00451 if (v20 == 0)
00452 return;
00453 m_voices.push_back(v20);
00454 }
00455 protected:
00456
00460 template <typename T> T*& p(uint32_t port) {
00461 return reinterpret_cast<T*&>(Parent::m_ports[port]);
00462 }
00463
00466 float*& p(uint32_t port) {
00467 return reinterpret_cast<float*&>(Parent::m_ports[port]);
00468 }
00469
00470
00473 std::vector<V*> m_voices;
00474
00477 std::vector<uint32_t> m_audio_ports;
00478
00481 uint32_t m_midi_input;
00482
00485 uint32_t m_midi_type;
00486
00487 };
00488
00489 }
00490
00491
00492 #endif