Changeset 4215
- Timestamp:
- 2012-04-20 11:52:14 (13 months ago)
- Location:
- trunk/plugins/mda.lv2
- Files:
-
- 14 edited
-
lvz/audioeffectx.h (modified) (5 diffs)
-
lvz/wrapper.cpp (modified) (4 diffs)
-
mda.lv2/DX10.ttl (modified) (3 diffs)
-
mda.lv2/EPiano.ttl (modified) (4 diffs)
-
mda.lv2/JX10.ttl (modified) (3 diffs)
-
mda.lv2/Piano.ttl (modified) (3 diffs)
-
src/mdaDX10.cpp (modified) (10 diffs)
-
src/mdaDX10.h (modified) (3 diffs)
-
src/mdaEPiano.cpp (modified) (9 diffs)
-
src/mdaEPiano.h (modified) (4 diffs)
-
src/mdaJX10.cpp (modified) (11 diffs)
-
src/mdaJX10.h (modified) (3 diffs)
-
src/mdaPiano.cpp (modified) (8 diffs)
-
src/mdaPiano.h (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/plugins/mda.lv2/lvz/audioeffectx.h
r4128 r4215 22 22 #include <stdint.h> 23 23 #include <string.h> 24 25 #include "lv2/lv2plug.in/ns/ext/atom/atom.h" 26 #include "lv2/lv2plug.in/ns/ext/urid/urid.h" 24 27 25 28 class AudioEffect; … … 76 79 : URI("NIL") 77 80 , uniqueID("NIL") 81 , eventInput(NULL) 78 82 , sampleRate(44100) 79 83 , curProgram(0) … … 85 89 } 86 90 87 virtual void process (float **inputs, float **outputs, int32_t nframes) = 0;91 virtual void process (float **inputs, float **outputs, int32_t nframes) {} 88 92 virtual void processReplacing(float **inputs, float **outputs, int32_t nframes) = 0; 93 94 void setMidiEventType(LV2_URID urid) { midiEventType = urid; } 95 void setEventInput(const LV2_Atom_Sequence* seq) { eventInput = seq; } 89 96 90 97 virtual int32_t processEvents(LvzEvents* ev) { return 0; } … … 100 107 virtual bool getProductString(char* text) = 0; 101 108 102 virtual bool canHostDo(const char* act) { return false; } 103 virtual void canMono() {} 104 virtual void canProcessReplacing() {} 105 virtual void isSynth() {} 106 virtual void wantEvents() {} 109 virtual int32_t canDo(const char* text) { return false; } 110 virtual bool canHostDo(const char* act) { return false; } 111 virtual void canMono() {} 112 virtual void canProcessReplacing() {} 113 virtual void isSynth() {} 114 virtual void wantEvents() {} 107 115 108 116 virtual void setBlockSize(int32_t size) {} … … 122 130 123 131 protected: 124 const char* URI; 125 const char* uniqueID; 126 float sampleRate; 127 int32_t curProgram; 128 int32_t numInputs; 129 int32_t numOutputs; 130 int32_t numParams; 131 int32_t numPrograms; 132 const char* URI; 133 const char* uniqueID; 134 const LV2_Atom_Sequence* eventInput; 135 LV2_URID midiEventType; 136 float sampleRate; 137 int32_t curProgram; 138 int32_t numInputs; 139 int32_t numOutputs; 140 int32_t numParams; 141 int32_t numPrograms; 132 142 }; 133 143 -
trunk/plugins/mda.lv2/lvz/wrapper.cpp
r4157 r4215 33 33 #include "audioeffectx.h" 34 34 #include "lv2.h" 35 #include "lv2/lv2plug.in/ns/ext/atom/atom.h" 36 #include "lv2/lv2plug.in/ns/ext/midi/midi.h" 37 #include "lv2/lv2plug.in/ns/ext/urid/urid.h" 35 38 #include PLUGIN_HEADER 36 39 … … 62 65 lvz_connect_port(LV2_Handle instance, uint32_t port, void* data) 63 66 { 64 LVZPlugin* plugin= (LVZPlugin*)instance;65 66 uint32_t num_params = plugin->effect->getNumParameters();67 uint32_t num_inputs = plugin->effect->getNumInputs();67 LVZPlugin* plugin = (LVZPlugin*)instance; 68 const uint32_t num_params = plugin->effect->getNumParameters(); 69 const uint32_t num_inputs = plugin->effect->getNumInputs(); 70 const uint32_t num_outputs = plugin->effect->getNumOutputs(); 68 71 69 72 if (port < num_params) { … … 71 74 } else if (port < num_params + num_inputs) { 72 75 plugin->inputs[port - num_params] = (float*)data; 73 } else {76 } else if (port < num_params + num_inputs + num_outputs) { 74 77 plugin->outputs[port - num_params - num_inputs] = (float*)data; 78 } else if (port == num_params + num_inputs + num_outputs) { 79 plugin->effect->setEventInput((LV2_Atom_Sequence*)data); 75 80 } 76 81 } … … 98 103 LVZPlugin* plugin = (LVZPlugin*)malloc(sizeof(LVZPlugin)); 99 104 plugin->effect = effect; 105 106 for (int i = 0; features[i]; ++i) { 107 if (!strcmp(features[i]->URI, LV2_URID__map)) { 108 LV2_URID_Map* map = (LV2_URID_Map*)features[i]->data; 109 plugin->effect->setMidiEventType( 110 map->map(map->handle, LV2_MIDI__MidiEvent)); 111 break; 112 } 113 } 100 114 101 115 if (num_params > 0) { -
trunk/plugins/mda.lv2/mda.lv2/DX10.ttl
r4188 r4215 1 @prefix atom: <http://lv2plug.in/ns/ext/atom#> . 1 2 @prefix doap: <http://usefulinc.com/ns/doap#> . 2 3 @prefix lv2: <http://lv2plug.in/ns/lv2core#> . … … 20 21 doap:license <http://usefulinc.com/doap/licenses/gpl> ; 21 22 lv2:optionalFeature lv2:hardRTCapable ; 23 lv2:requiredFeature <http://lv2plug.in/ns/ext/urid#map> ; 22 24 pg:mainInput mda:mainIn ; 23 25 pg:mainOutput mda:mainOut ; 24 rdfs:comment " ""Sounds similar to the later Yamaha DX synths including the heavy bass but with a warmer, cleaner tone. This plug-in is 8-voice polyphonic.""" ;26 rdfs:comment "Sounds similar to the later Yamaha DX synths including the heavy bass but with a warmer, cleaner tone. This plug-in is 8-voice polyphonic." ; 25 27 lv2:port [ 26 28 a lv2:InputPort , … … 189 191 lv2:designation pg:right ; 190 192 pg:group mda:mainOut 193 ] , [ 194 a lv2:InputPort , 195 atom:AtomPort ; 196 atom:bufferType atom:Sequence ; 197 atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ; 198 lv2:index 18 ; 199 lv2:symbol "event_in" ; 200 lv2:name "Event In" 191 201 ] . -
trunk/plugins/mda.lv2/mda.lv2/EPiano.ttl
r4214 r4215 1 @prefix atom: <http://lv2plug.in/ns/ext/atom#> . 1 2 @prefix doap: <http://usefulinc.com/ns/doap#> . 2 3 @prefix lv2: <http://lv2plug.in/ns/lv2core#> . … … 12 13 doap:license <http://usefulinc.com/doap/licenses/gpl> ; 13 14 lv2:optionalFeature lv2:hardRTCapable ; 15 lv2:requiredFeature <http://lv2plug.in/ns/ext/urid#map> ; 14 16 pg:mainInput mda:mainIn ; 15 17 pg:mainOutput mda:mainOut ; … … 90 92 lv2:ControlPort ; 91 93 lv2:index 8 ; 92 lv2:name "Polyphon y" ;93 lv2:symbol "polyphon y" ;94 lv2:default 0.5;94 lv2:name "Polyphonic" ; 95 lv2:symbol "polyphonic" ; 96 lv2:default 1.0 ; 95 97 lv2:minimum 0.0 ; 96 lv2:maximum 1.0 98 lv2:maximum 1.0 ; 99 lv2:portProperty lv2:toggled 97 100 ] , [ 98 101 a lv2:InputPort , … … 138 141 lv2:designation pg:right ; 139 142 pg:group mda:mainOut 143 ] , [ 144 a lv2:InputPort , 145 atom:AtomPort ; 146 atom:bufferType atom:Sequence ; 147 atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ; 148 lv2:index 14 ; 149 lv2:symbol "event_in" ; 150 lv2:name "Event In" 140 151 ] . -
trunk/plugins/mda.lv2/mda.lv2/JX10.ttl
r4188 r4215 1 @prefix atom: <http://lv2plug.in/ns/ext/atom#> . 1 2 @prefix doap: <http://usefulinc.com/ns/doap#> . 2 3 @prefix lv2: <http://lv2plug.in/ns/lv2core#> . … … 24 25 lv2:project mda: ; 25 26 lv2:symbol "JX10" ; 26 doap:name "MDA JX10 Synth" ;27 doap:name "MDA JX10" ; 27 28 doap:license <http://usefulinc.com/doap/licenses/gpl> ; 28 29 lv2:optionalFeature lv2:hardRTCapable ; 30 lv2:requiredFeature <http://lv2plug.in/ns/ext/urid#map> ; 29 31 pg:mainInput mda:mainIn ; 30 32 pg:mainOutput mda:mainOut ; … … 298 300 lv2:designation pg:right ; 299 301 pg:group mda:mainOut 302 ] , [ 303 a lv2:InputPort , 304 atom:AtomPort ; 305 atom:bufferType atom:Sequence ; 306 atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ; 307 lv2:index 26 ; 308 lv2:symbol "event_in" ; 309 lv2:name "Event In" 300 310 ] . -
trunk/plugins/mda.lv2/mda.lv2/Piano.ttl
r4214 r4215 1 @prefix atom: <http://lv2plug.in/ns/ext/atom#> . 1 2 @prefix doap: <http://usefulinc.com/ns/doap#> . 2 3 @prefix lv2: <http://lv2plug.in/ns/lv2core#> . … … 20 21 doap:license <http://usefulinc.com/doap/licenses/gpl> ; 21 22 lv2:optionalFeature lv2:hardRTCapable ; 23 lv2:requiredFeature <http://lv2plug.in/ns/ext/urid#map> ; 22 24 pg:mainInput mda:mainIn ; 23 25 pg:mainOutput mda:mainOut ; … … 153 155 lv2:designation pg:right ; 154 156 pg:group mda:mainOut 157 ] , [ 158 a lv2:InputPort , 159 atom:AtomPort ; 160 atom:bufferType atom:Sequence ; 161 atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ; 162 lv2:index 14 ; 163 lv2:symbol "event_in" ; 164 lv2:name "Event In" 155 165 ] . -
trunk/plugins/mda.lv2/src/mdaDX10.cpp
r4127 r4215 18 18 19 19 #include "mdaDX10.h" 20 21 #include "lv2/lv2plug.in/ns/ext/atom/util.h" 20 22 21 23 #include <stdio.h> … … 91 93 voice[i].cdec = 0.99f; //all notes off 92 94 } 93 notes[0] = EVENTS_DONE;94 95 lfo0 = dlfo = modwhl = 0.0f; 95 96 lfo1 = pbend = 1.0f; … … 241 242 242 243 243 int32_t mdaDX10::canDo(c har* text)244 int32_t mdaDX10::canDo(const char* text) 244 245 { 245 246 if(strcmp(text, "receiveLvzEvents") == 0) return 1; … … 305 306 } 306 307 307 308 void mdaDX10::process(float **inputs, float **outputs, int32_t sampleFrames) 308 void mdaDX10::processReplacing(float **inputs, float **outputs, int32_t sampleFrames) 309 309 { 310 310 float* out1 = outputs[0]; 311 311 float* out2 = outputs[1]; 312 int32_t event=0,frame=0, frames, v;312 int32_t frame=0, frames, v; 313 313 float o, x, e, mw=MW, w=rich, m=modmix; 314 314 int32_t k=K; 315 315 316 if(activevoices>0 || notes[event]<sampleFrames) //detect & bypass completely empty blocks 316 LV2_Atom_Event* ev = lv2_atom_sequence_begin(&eventInput->body); 317 bool end = lv2_atom_sequence_is_end(&eventInput->body, eventInput->atom.size, ev); 318 if(activevoices>0 || !end) //detect & bypass completely empty blocks 317 319 { 318 320 while(frame<sampleFrames) 319 321 { 320 frames = notes[event++];321 if(frames>sampleFrames) frames = sampleFrames;322 end = lv2_atom_sequence_is_end(&eventInput->body, eventInput->atom.size, ev); 323 frames = end ? sampleFrames : ev->time.frames; 322 324 frames -= frame; 323 325 frame += frames; … … 355 357 o += V->cenv * (m * V->mod1 + (x + x * x * x * (w * x * x - 1.0f - w))); 356 358 } //amp env //mod thru-mix //5th-order sine approximation 359 360 /// xx = x * x; 361 /// x + x + x * xx * (xx - 3.0f); 362 357 363 V++; 358 364 } 359 *out1++ += o;360 *out2++ += o;365 *out1++ = o; 366 *out2++ = o; 361 367 } 362 368 363 if( frame<sampleFrames) //next note on/off369 if(!end) //next note on/off 364 370 { 365 int32_t note = notes[event++]; 366 int32_t vel = notes[event++]; 367 noteOn(note, vel); 371 processEvent(ev); 372 ev = lv2_atom_sequence_next(ev); 368 373 } 369 374 } … … 380 385 } 381 386 } 382 383 K=k; MW=mw; //remember these so vibrato speed not buffer size dependant!384 notes[0] = EVENTS_DONE;385 }386 387 388 void mdaDX10::processReplacing(float **inputs, float **outputs, int32_t sampleFrames)389 {390 float* out1 = outputs[0];391 float* out2 = outputs[1];392 int32_t event=0, frame=0, frames, v;393 float o, x, e, mw=MW, w=rich, m=modmix;394 int32_t k=K;395 396 if(activevoices>0 || notes[event]<sampleFrames) //detect & bypass completely empty blocks397 {398 while(frame<sampleFrames)399 {400 frames = notes[event++];401 if(frames>sampleFrames) frames = sampleFrames;402 frames -= frame;403 frame += frames;404 405 while(--frames>=0) //would be faster with voice loop outside frame loop!406 { //but then each voice would need it's own LFO...407 VOICE *V = voice;408 o = 0.0f;409 410 if(--k<0)411 {412 lfo0 += dlfo * lfo1; //sine LFO413 lfo1 -= dlfo * lfo0;414 mw = lfo1 * (modwhl + vibrato);415 k=100;416 }417 418 for(v=0; v<NVOICES; v++) //for each voice419 {420 e = V->env;421 if(e > SILENCE) //**** this is the synth ****422 {423 V->env = e * V->cdec; //decay & release424 V->cenv += V->catt * (e - V->cenv); //attack425 426 x = V->dmod * V->mod0 - V->mod1; //could add more modulator blocks like427 V->mod1 = V->mod0; //this for a wider range of FM sounds428 V->mod0 = x;429 V->menv += V->mdec * (V->mlev - V->menv);430 431 x = V->car + V->dcar + x * V->menv + mw; //carrier phase432 while(x > 1.0f) x -= 2.0f; //wrap phase433 while(x < -1.0f) x += 2.0f;434 V->car = x;435 o += V->cenv * (m * V->mod1 + (x + x * x * x * (w * x * x - 1.0f - w)));436 } //amp env //mod thru-mix //5th-order sine approximation437 438 /// xx = x * x;439 /// x + x + x * xx * (xx - 3.0f);440 441 V++;442 }443 *out1++ = o;444 *out2++ = o;445 }446 447 if(frame<sampleFrames) //next note on/off448 {449 int32_t note = notes[event++];450 int32_t vel = notes[event++];451 noteOn(note, vel);452 }453 }454 455 activevoices = NVOICES;456 for(v=0; v<NVOICES; v++)457 {458 if(voice[v].env < SILENCE) //choke voices that have finished459 {460 voice[v].env = voice[v].cenv = 0.0f;461 activevoices--;462 }463 if(voice[v].menv < SILENCE) voice[v].menv = voice[v].mlev = 0.0f;464 }465 }466 387 else //completely empty block 467 388 { … … 473 394 } 474 395 K=k; MW=mw; //remember these so vibrato speed not buffer size dependant! 475 notes[0] = EVENTS_DONE;476 396 } 477 397 … … 529 449 530 450 531 int32_t mdaDX10::processEvents(LvzEvents* ev) 532 { 533 int32_t npos=0; 534 535 for (int32_t i=0; i<ev->numEvents; i++) 536 { 537 if((ev->events[i])->type != kLvzMidiType) continue; 538 LvzMidiEvent* event = (LvzMidiEvent*)ev->events[i]; 539 char* midiData = event->midiData; 451 int32_t mdaDX10::processEvent(const LV2_Atom_Event* ev) 452 { 453 if (ev->body.type != midiEventType) 454 return 0; 455 456 const uint8_t* midiData = (const uint8_t*)LV2_ATOM_BODY(&ev->body); 540 457 541 458 switch(midiData[0] & 0xf0) //status byte (all channels) 542 459 { 543 460 case 0x80: //note off 544 notes[npos++] = event->deltaFrames; //delta 545 notes[npos++] = midiData[1] & 0x7F; //note 546 notes[npos++] = 0; //vel 461 noteOn(midiData[1] & 0x7F, 0); 547 462 break; 548 463 549 464 case 0x90: //note on 550 notes[npos++] = event->deltaFrames; //delta 551 notes[npos++] = midiData[1] & 0x7F; //note 552 notes[npos++] = midiData[2] & 0x7F; //vel 465 noteOn(midiData[1] & 0x7F, midiData[2] & 0x7F); 553 466 break; 554 467 … … 568 481 if(sustain==0) 569 482 { 570 notes[npos++] = event->deltaFrames; 571 notes[npos++] = SUSTAIN; //end all sustained notes 572 notes[npos++] = 0; 483 noteOn(SUSTAIN, 0); 573 484 } 574 485 break; … … 597 508 } 598 509 599 if(npos>EVENTBUFFER) npos -= 3; //discard events if buffer full!!600 event++;601 }602 notes[npos] = EVENTS_DONE;603 510 return 1; 604 511 } -
trunk/plugins/mda.lv2/src/mdaDX10.h
r4127 r4215 63 63 ~mdaDX10(); 64 64 65 virtual void process(float **inputs, float **outputs, int32_t sampleframes);66 65 virtual void processReplacing(float **inputs, float **outputs, int32_t sampleframes); 67 virtual int32_t processEvents(LvzEvents* events);68 66 69 67 virtual void setProgram(int32_t program); … … 86 84 virtual bool getProductString (char* text); 87 85 virtual int32_t getVendorVersion () {return 1;} 88 virtual int32_t canDo (c har* text);86 virtual int32_t canDo (const char* text); 89 87 90 88 virtual int32_t getNumMidiInputChannels () { return 1; } 91 89 92 90 private: 91 int32_t processEvent(const LV2_Atom_Event* ev); 93 92 void update(); //my parameter update 94 93 void noteOn(int32_t note, int32_t velocity); … … 100 99 mdaDX10Program* programs; 101 100 float Fs; 102 103 #define EVENTBUFFER 120104 #define EVENTS_DONE 99999999105 int32_t notes[EVENTBUFFER + 8]; //list of delta|note|velocity for current block106 101 107 102 ///global internal variables -
trunk/plugins/mda.lv2/src/mdaEPiano.cpp
r4127 r4215 19 19 #include "mdaEPianoData.h" 20 20 #include "mdaEPiano.h" 21 22 #include "lv2/lv2plug.in/ns/ext/atom/util.h" 21 23 22 24 #include <stdio.h> … … 133 135 voice[v].dec = 0.99f; //all notes off 134 136 } 135 notes[0] = EVENTS_DONE;136 137 volume = 0.2f; 137 138 muff = 160.0f; … … 264 265 265 266 266 int32_t mdaEPiano::canDo(c har* text)267 int32_t mdaEPiano::canDo(const char* text) 267 268 { 268 269 if(strcmp(text, "receiveLvzEvents") == 0) return 1; … … 345 346 346 347 347 void mdaEPiano::process (float **inputs, float **outputs, int32_t sampleFrames)348 void mdaEPiano::processReplacing(float **inputs, float **outputs, int32_t sampleFrames) 348 349 { 349 350 float* out0 = outputs[0]; 350 351 float* out1 = outputs[1]; 351 int32_t event=0,frame=0, frames, v;352 int32_t frame=0, frames, v; 352 353 float x, l, r, od=overdrive; 353 354 int32_t i; 354 355 356 LV2_Atom_Event* ev = lv2_atom_sequence_begin(&eventInput->body); 355 357 while(frame<sampleFrames) 356 358 { 357 frames = notes[event++]; 358 if(frames>sampleFrames) frames = sampleFrames; 359 frames -= frame; 360 frame += frames; 361 362 while(--frames>=0) 363 { 364 VOICE *V = voice; 365 l = r = 0.0f; 366 367 for(v=0; v<activevoices; v++) 368 { 369 V->frac += V->delta; //integer-based linear interpolation 370 V->pos += V->frac >> 16; 371 V->frac &= 0xFFFF; 372 if(V->pos > V->end) V->pos -= V->loop; 373 i = waves[V->pos]; 374 i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000; 375 x = V->env * (*(float *)&i - 3.0f); //fast int->float 376 V->env = V->env * V->dec; //envelope 377 378 if(x>0.0f) { x -= od * x * x; if(x < -V->env) x = -V->env; } //+= 0.5f * x * x; } //overdrive 379 380 l += V->outl * x; 381 r += V->outr * x; 382 383 V++; 384 } 385 tl += tfrq * (l - tl); //treble boost 386 tr += tfrq * (r - tr); 387 r += treb * (r - tr); 388 l += treb * (l - tl); 389 390 lfo0 += dlfo * lfo1; //LFO for tremolo and autopan 391 lfo1 -= dlfo * lfo0; 392 l += l * lmod * lfo1; 393 r += r * rmod * lfo1; //worth making all these local variables? 394 395 *out0++ += l; 396 *out1++ += r; 397 } 398 399 if(frame<sampleFrames) 400 { 401 if(activevoices == 0 && programs[curProgram].param[4] > 0.5f) 402 { lfo0 = -0.7071f; lfo1 = 0.7071f; } //reset LFO phase - good idea? 403 int32_t note = notes[event++]; 404 int32_t vel = notes[event++]; 405 noteOn(note, vel); 406 } 407 } 408 if(fabs(tl)<1.0e-10) tl = 0.0f; //anti-denormal 409 if(fabs(tr)<1.0e-10) tr = 0.0f; 410 411 for(v=0; v<activevoices; v++) if(voice[v].env < SILENCE) voice[v] = voice[--activevoices]; 412 notes[0] = EVENTS_DONE; //mark events buffer as done 413 } 414 415 416 void mdaEPiano::processReplacing(float **inputs, float **outputs, int32_t sampleFrames) 417 { 418 float* out0 = outputs[0]; 419 float* out1 = outputs[1]; 420 int32_t event=0, frame=0, frames, v; 421 float x, l, r, od=overdrive; 422 int32_t i; 423 424 while(frame<sampleFrames) 425 { 426 frames = notes[event++]; 427 if(frames>sampleFrames) frames = sampleFrames; 359 bool end = lv2_atom_sequence_is_end(&eventInput->body, eventInput->atom.size, ev); 360 frames = end ? sampleFrames : ev->time.frames; 428 361 frames -= frame; 429 362 frame += frames; … … 474 407 if(activevoices == 0 && programs[curProgram].param[4] > 0.5f) 475 408 { lfo0 = -0.7071f; lfo1 = 0.7071f; } //reset LFO phase - good idea? 476 int32_t note = notes[event++]; 477 int32_t vel = notes[event++]; 478 noteOn(note, vel); 409 410 if (!end) { 411 processEvent(ev); 412 ev = lv2_atom_sequence_next(ev); 413 } 414 479 415 } 480 416 } … … 483 419 484 420 for(v=0; v<activevoices; v++) if(voice[v].env < SILENCE) voice[v] = voice[--activevoices]; 485 notes[0] = EVENTS_DONE; //mark events buffer as done486 421 } 487 422 … … 562 497 563 498 564 int32_t mdaEPiano::processEvent s(LvzEvents* ev)499 int32_t mdaEPiano::processEvent(const LV2_Atom_Event* ev) 565 500 { 566 501 float * param = programs[curProgram].param; 567 int32_t npos=0; 568 569 for (int32_t i=0; i<ev->numEvents; i++) 570 { 571 if((ev->events[i])->type != kLvzMidiType) continue; 572 LvzMidiEvent* event = (LvzMidiEvent*)ev->events[i]; 573 char* midiData = event->midiData; 502 503 if (ev->body.type != midiEventType) 504 return 0; 505 506 const uint8_t* midiData = (const uint8_t*)LV2_ATOM_BODY(&ev->body); 574 507 575 508 switch(midiData[0] & 0xf0) //status byte (all channels) 576 509 { 577 510 case 0x80: //note off 578 notes[npos++] = event->deltaFrames; //delta 579 notes[npos++] = midiData[1] & 0x7F; //note 580 notes[npos++] = 0; //vel 511 noteOn(midiData[1] & 0x7F, 0); 581 512 break; 582 513 583 514 case 0x90: //note on 584 notes[npos++] = event->deltaFrames; //delta 585 notes[npos++] = midiData[1] & 0x7F; //note 586 notes[npos++] = midiData[2] & 0x7F; //vel 515 noteOn(midiData[1] & 0x7F, midiData[2] & 0x7F); 587 516 break; 588 517 … … 609 538 if(sustain==0) 610 539 { 611 notes[npos++] = event->deltaFrames; 612 notes[npos++] = SUSTAIN; //end all sustained notes 613 notes[npos++] = 0; 540 noteOn(SUSTAIN, 0); //end all sustained notes 614 541 } 615 542 break; … … 633 560 } 634 561 635 if(npos>EVENTBUFFER) npos -= 3; //discard events if buffer full!!636 event++; //?637 }638 notes[npos] = EVENTS_DONE;639 562 return 1; 640 563 } -
trunk/plugins/mda.lv2/src/mdaEPiano.h
r4127 r4215 77 77 ~mdaEPiano(); 78 78 79 virtual void process(float **inputs, float **outputs, int32_t sampleframes);80 79 virtual void processReplacing(float **inputs, float **outputs, int32_t sampleframes); 81 virtual int32_t processEvents(LvzEvents* events);82 80 83 81 virtual void setProgram(int32_t program); … … 99 97 virtual bool getProductString (char* text); 100 98 virtual int32_t getVendorVersion () {return 1;} 101 virtual int32_t canDo (c har* text);99 virtual int32_t canDo (const char* text); 102 100 103 101 virtual int32_t getNumMidiInputChannels () { return 1; } … … 107 105 108 106 private: 107 int32_t processEvent(const LV2_Atom_Event* ev); 109 108 void update(); //my parameter update 110 109 void noteOn(int32_t note, int32_t velocity); … … 114 113 mdaEPianoProgram* programs; 115 114 float Fs, iFs; 116 117 #define EVENTBUFFER 120118 #define EVENTS_DONE 99999999119 int32_t notes[EVENTBUFFER + 8]; //list of delta|note|velocity for current block120 115 121 116 ///global internal variables -
trunk/plugins/mda.lv2/src/mdaJX10.cpp
r4127 r4215 18 18 19 19 #include "mdaJX10.h" 20 21 #include "lv2/lv2plug.in/ns/ext/atom/util.h" 20 22 21 23 #include <stdio.h> … … 155 157 voice[v].note = 0; 156 158 } 157 notes[0] = EVENTS_DONE;158 159 lfo = modwhl = filtwhl = press = fzip = 0.0f; 159 160 rezwhl = pbend = ipbend = 1.0f; … … 333 334 334 335 335 int32_t mdaJX10::canDo(c har* text)336 int32_t mdaJX10::canDo(const char* text) 336 337 { 337 338 if(!strcmp (text, "receiveLvzEvents")) return 1; … … 431 432 } 432 433 433 434 void mdaJX10::process(float **inputs, float **outputs, int32_t sampleFrames) 434 void mdaJX10::processReplacing(float **inputs, float **outputs, int32_t sampleFrames) 435 435 { 436 436 float* out1 = outputs[0]; 437 437 float* out2 = outputs[1]; 438 int32_t event=0,frame=0, frames, v;438 int32_t frame=0, frames, v; 439 439 float o, e, vib, pwm, pb=pbend, ipb=ipbend, gl=glide; 440 440 float x, y, hpf=0.997f, min=1.0f, w=0.0f, ww=noisemix; … … 448 448 vib = 1.0f + vib * (modwhl + vibrato); 449 449 450 if(activevoices>0 || notes[event]<sampleFrames) 450 LV2_Atom_Event* ev = lv2_atom_sequence_begin(&eventInput->body); 451 bool end = lv2_atom_sequence_is_end(&eventInput->body, eventInput->atom.size, ev); 452 if(activevoices>0 || !end) 451 453 { 452 454 while(frame<sampleFrames) 453 455 { 454 frames = notes[event++];455 if(frames>sampleFrames) frames = sampleFrames;456 end = lv2_atom_sequence_is_end(&eventInput->body, eventInput->atom.size, ev); 457 frames = end ? sampleFrames : ev->time.frames; 456 458 frames -= frame; 457 459 frame += frames; … … 558 560 559 561 if(V->ff > fx) V->ff = fx; //stability limit 560 562 561 563 V->f0 += V->ff * V->f1; //state-variable filter 562 564 V->f1 -= V->ff * (V->f0 + fq * V->f1 - x - V->f2); 563 V->f1 -= 0.2f * V->f1 * V->f1 * V->f1; //soft limit //was 0.08f 565 V->f1 -= 0.2f * V->f1 * V->f1 * V->f1; //soft limit 566 564 567 V->f2 = x; 565 568 … … 569 572 } 570 573 571 *out1++ += o;572 *out2++ += o;573 }574 575 if(frame<sampleFrames)576 {577 int32_t note = notes[event++];578 int32_t vel = notes[event++];579 noteOn(note, vel);580 }581 }582 583 activevoices = NVOICES;584 for(v=0; v<NVOICES; v++)585 {586 if(voice[v].env<SILENCE) //choke voices587 {588 voice[v].env = voice[v].envl = 0.0f;589 voice[v].f0 = voice[v].f1 = voice[v].f2 = 0.0f;590 activevoices--;591 }592 }593 }594 notes[0] = EVENTS_DONE; //mark events buffer as done595 fzip = fz;596 K = k;597 }598 599 600 void mdaJX10::processReplacing(float **inputs, float **outputs, int32_t sampleFrames)601 {602 float* out1 = outputs[0];603 float* out2 = outputs[1];604 int32_t event=0, frame=0, frames, v;605 float o, e, vib, pwm, pb=pbend, ipb=ipbend, gl=glide;606 float x, y, hpf=0.997f, min=1.0f, w=0.0f, ww=noisemix;607 float ff, fe=filtenv, fq=filtq * rezwhl, fx=1.97f-0.85f*fq, fz=fzip;608 int32_t k=K;609 unsigned int r;610 611 vib = (float)sin(lfo);612 ff = filtf + filtwhl + (filtlfo + press) * vib; //have to do again here as way that613 pwm = 1.0f + vib * (modwhl + pwmdep); //below triggers on k was too cheap!614 vib = 1.0f + vib * (modwhl + vibrato);615 616 if(activevoices>0 || notes[event]<sampleFrames)617 {618 while(frame<sampleFrames)619 {620 frames = notes[event++];621 if(frames>sampleFrames) frames = sampleFrames;622 frames -= frame;623 frame += frames;624 625 while(--frames>=0)626 {627 VOICE *V = voice;628 o = 0.0f;629 630 noise = (noise * 196314165) + 907633515;631 r = (noise & 0x7FFFFF) + 0x40000000; //generate noise + fast convert to float632 w = *(float *)&r;633 w = ww * (w - 3.0f);634 635 if(--k<0)636 {637 lfo += dlfo;638 if(lfo>PI) lfo -= TWOPI;639 vib = (float)sin(lfo);640 ff = filtf + filtwhl + (filtlfo + press) * vib;641 pwm = 1.0f + vib * (modwhl + pwmdep);642 vib = 1.0f + vib * (modwhl + vibrato);643 k = KMAX;644 }645 646 for(v=0; v<NVOICES; v++) //for each voice647 {648 e = V->env;649 if(e > SILENCE)650 { //Sinc-Loop Oscillator651 x = V->p + V->dp;652 if(x > min)653 {654 if(x > V->pmax)655 {656 x = V->pmax + V->pmax - x;657 V->dp = -V->dp;658 }659 V->p = x;660 x = V->sin0 * V->sinx - V->sin1; //sine osc661 V->sin1 = V->sin0;662 V->sin0 = x;663 x = x / V->p;664 }665 else666 {667 V->p = x = - x;668 V->dp = V->period * vib * pb; //set period for next cycle669 V->pmax = (float)floor(0.5f + V->dp) - 0.5f;670 V->dc = -0.5f * V->lev / V->pmax;671 V->pmax *= PI;672 V->dp = V->pmax / V->dp;673 V->sin0 = V->lev * (float)sin(x);674 V->sin1 = V->lev * (float)sin(x - V->dp);675 V->sinx = 2.0f * (float)cos(V->dp);676 if(x*x > .1f) x = V->sin0 / x; else x = V->lev; //was 0.01f;677 }678 679 y = V->p2 + V->dp2; //osc2680 if(y > min)681 {682 if(y > V->pmax2)683 {684 y = V->pmax2 + V->pmax2 - y;685 V->dp2 = -V->dp2;686 }687 V->p2 = y;688 y = V->sin02 * V->sinx2 - V->sin12;689 V->sin12 = V->sin02;690 V->sin02 = y;691 y = y / V->p2;692 }693 else694 {695 V->p2 = y = - y;696 V->dp2 = V->period * V->detune * pwm * pb;697 V->pmax2 = (float)floor(0.5f + V->dp2) - 0.5f;698 V->dc2 = -0.5f * V->lev2 / V->pmax2;699 V->pmax2 *= PI;700 V->dp2 = V->pmax2 / V->dp2;701 V->sin02 = V->lev2 * (float)sin(y);702 V->sin12 = V->lev2 * (float)sin(y - V->dp2);703 V->sinx2 = 2.0f * (float)cos(V->dp2);704 if(y*y > .1f) y = V->sin02 / y; else y = V->lev2;705 }706 V->saw = V->saw * hpf + V->dc + x - V->dc2 - y; //integrated sinc = saw707 x = V->saw + w;708 V->env += V->envd * (V->envl - V->env);709 710 if(k==KMAX) //filter freq update at LFO rate711 {712 if((V->env+V->envl)>3.0f) { V->envd=dec; V->envl=sus; } //envelopes713 V->fenv += V->fenvd * (V->fenvl - V->fenv);714 if((V->fenv+V->fenvl)>3.0f) { V->fenvd=fdec; V->fenvl=fsus; }715 716 fz += 0.005f * (ff - fz); //filter zipper noise filter717 y = V->fc * (float)exp(fz + fe * V->fenv) * ipb; //filter cutoff718 if(y<0.005f) y=0.005f;719 V->ff = y;720 721 V->period += gl * (V->target - V->period); //glide722 if(V->target < V->period) V->period += gl * (V->target - V->period);723 }724 725 if(V->ff > fx) V->ff = fx; //stability limit726 727 V->f0 += V->ff * V->f1; //state-variable filter728 V->f1 -= V->ff * (V->f0 + fq * V->f1 - x - V->f2);729 V->f1 -= 0.2f * V->f1 * V->f1 * V->f1; //soft limit730 731 V->f2 = x;732 733 o += V->env * V->f0;734 }735 V++;736 }737 738 574 *out1++ = o; 739 575 *out2++ = o; 740 576 } 741 577 742 if(frame<sampleFrames) 743 { 744 int32_t note = notes[event++]; 745 int32_t vel = notes[event++]; 746 noteOn(note, vel); 578 if(!end) 579 { 580 processEvent(ev); 581 ev = lv2_atom_sequence_next(ev); 747 582 } 748 583 } … … 767 602 } 768 603 } 769 notes[0] = EVENTS_DONE; //mark events buffer as done770 604 fzip = fz; 771 605 K = k; … … 913 747 914 748 915 int32_t mdaJX10::processEvents(LvzEvents* ev) 916 { 917 int32_t npos=0; 918 919 for (int32_t i=0; i<ev->numEvents; i++) 920 { 921 if((ev->events[i])->type != kLvzMidiType) continue; 922 LvzMidiEvent* event = (LvzMidiEvent*)ev->events[i]; 923 char* midiData = event->midiData; 749 int32_t mdaJX10::processEvent(const LV2_Atom_Event* ev) 750 { 751 if (ev->body.type != midiEventType) 752 return 0; 753 754 const uint8_t* midiData = (const uint8_t*)LV2_ATOM_BODY(&ev->body); 924 755 925 756 switch(midiData[0] & 0xf0) //status byte (all channels) 926 757 { 927 758 case 0x80: //note off 928 notes[npos++] = event->deltaFrames; //delta 929 notes[npos++] = midiData[1] & 0x7F; //note 930 notes[npos++] = 0; //vel 759 noteOn(midiData[1] & 0x7F, 0); 931 760 break; 932 761 933 762 case 0x90: //note on 934 notes[npos++] = event->deltaFrames; //delta 935 notes[npos++] = midiData[1] & 0x7F; //note 936 notes[npos++] = midiData[2] & 0x7F; //vel 763 noteOn(midiData[1] & 0x7F, midiData[2] & 0x7F); 937 764 break; 938 765 … … 964 791 if(sustain==0) 965 792 { 966 notes[npos++] = event->deltaFrames; 967 notes[npos++] = SUSTAIN; //end all sustained notes 968 notes[npos++] = 0; 793 noteOn(SUSTAIN, 0); 969 794 } 970 795 break; … … 1002 827 } 1003 828 1004 if(npos>EVENTBUFFER) npos -= 3; //discard events if buffer full!!1005 event++;1006 }1007 notes[npos] = EVENTS_DONE;1008 829 return 1; 1009 830 } -
trunk/plugins/mda.lv2/src/mdaJX10.h
r4127 r4215 95 95 ~mdaJX10(); 96 96 97 virtual void process(float **inputs, float **outputs, int32_t sampleframes);98 97 virtual void processReplacing(float **inputs, float **outputs, int32_t sampleframes); 99 virtual int32_t processEvents(LvzEvents* events);100 98 101 99 virtual void setProgram(int32_t program); … … 119 117 virtual bool getProductString (char* text); 120 118 virtual int32_t getVendorVersion () {return 1;} 121 virtual int32_t canDo (c har* text);119 virtual int32_t canDo (const char* text); 122 120 123 121 private: 122 int32_t processEvent(const LV2_Atom_Event* ev); 124 123 void update(); //my parameter update 125 124 void noteOn(int32_t note, int32_t velocity); … … 133 132 float Fs; 134 133 135 #define EVENTBUFFER 120136 #define EVENTS_DONE 99999999137 int32_t notes[EVENTBUFFER + 8]; //list of delta|note|velocity for current block138 134 #define KMAX 32 139 135 -
trunk/plugins/mda.lv2/src/mdaPiano.cpp
r4127 r4215 19 19 #include "mdaPianoData.h" 20 20 #include "mdaPiano.h" 21 22 #include "lv2/lv2plug.in/ns/ext/atom/util.h" 21 23 22 24 #include <stdio.h> … … 110 112 voice[v].dec = 0.99f; //all notes off 111 113 } 112 notes[0] = EVENTS_DONE;113 114 volume = 0.2f; 114 115 muff = 160.0f; … … 241 242 242 243 243 int32_t mdaPiano::canDo(c har* text)244 int32_t mdaPiano::canDo(const char* text) 244 245 { 245 246 if(strcmp(text, "receiveLvzEvents") == 0) return 1; … … 314 315 } 315 316 316 317 318 void mdaPiano::process(float **inputs, float **outputs, int32_t sampleFrames) 317 void mdaPiano::processReplacing(float **inputs, float **outputs, int32_t sampleFrames) 319 318 { 320 319 float* out0 = outputs[0]; 321 320 float* out1 = outputs[1]; 322 int32_t event=0,frame=0, frames, v;321 int32_t frame=0, frames, v; 323 322 float x, l, r; 324 323 int32_t i; 325 324 325 LV2_Atom_Event* ev = lv2_atom_sequence_begin(&eventInput->body); 326 326 while(frame<sampleFrames) 327 327 { 328 frames = notes[event++]; 329 if(frames>sampleFrames) frames = sampleFrames; 330 frames -= frame; 331 frame += frames; 332 333 while(--frames>=0) 334 { 335 VOICE *V = voice; 336 l = r = 0.0f; 337 338 for(v=0; v<activevoices; v++) 339 { 340 V->frac += V->delta; //integer-based linear interpolation 341 V->pos += V->frac >> 16; 342 V->frac &= 0xFFFF; 343 if(V->pos > V->end) V->pos -= V->loop; 344 i = waves[V->pos]; 345 i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000; 346 x = V->env * (*(float *)&i - 3.0f); //fast int->float 347 348 V->env = V->env * V->dec; //envelope 349 V->f0 += V->ff * (x + V->f1 - V->f0); //muffle filter 350 V->f1 = x; 351 352 l += V->outl * V->f0; 353 r += V->outr * V->f0; 354 355 V++; 356 } 357 comb[cpos] = l + r; 358 ++cpos &= cmax; 359 x = cdep * comb[cpos]; //stereo simulator 360 361 *out0++ += l + x; 362 *out1++ += r - x; 363 } 364 365 if(frame<sampleFrames) 366 { 367 int32_t note = notes[event++]; 368 int32_t vel = notes[event++]; 369 noteOn(note, vel); 370 } 371 } 372 for(v=0; v<activevoices; v++) if(voice[v].env < SILENCE) voice[v] = voice[--activevoices]; 373 notes[0] = EVENTS_DONE; //mark events buffer as done 374 } 375 376 377 void mdaPiano::processReplacing(float **inputs, float **outputs, int32_t sampleFrames) 378 { 379 float* out0 = outputs[0]; 380 float* out1 = outputs[1]; 381 int32_t event=0, frame=0, frames, v; 382 float x, l, r; 383 int32_t i; 384 385 while(frame<sampleFrames) 386 { 387 frames = notes[event++]; 388 if(frames>sampleFrames) frames = sampleFrames; 328 bool end = lv2_atom_sequence_is_end(&eventInput->body, eventInput->atom.size, ev); 329 frames = end ? sampleFrames : ev->time.frames; 389 330 frames -= frame; 390 331 frame += frames; … … 433 374 } 434 375 435 if( frame<sampleFrames)376 if(!end) 436 377 { 437 int32_t note = notes[event++]; 438 int32_t vel = notes[event++]; 439 noteOn(note, vel); 378 processEvent(ev); 379 ev = lv2_atom_sequence_next(ev); 440 380 } 441 381 } 442 382 for(v=0; v<activevoices; v++) if(voice[v].env < SILENCE) voice[v] = voice[--activevoices]; 443 notes[0] = EVENTS_DONE; //mark events buffer as done444 383 } 445 384 … … 519 458 520 459 521 int32_t mdaPiano::processEvents(LvzEvents* ev) 522 { 523 int32_t npos=0; 524 525 for (int32_t i=0; i<ev->numEvents; i++) 526 { 527 if((ev->events[i])->type != kLvzMidiType) continue; 528 LvzMidiEvent* event = (LvzMidiEvent*)ev->events[i]; 529 char* midiData = event->midiData; 460 int32_t mdaPiano::processEvent(const LV2_Atom_Event* ev) 461 { 462 if (ev->body.type != midiEventType) 463 return 0; 464 465 const uint8_t* midiData = (const uint8_t*)LV2_ATOM_BODY(&ev->body); 530 466 531 467 switch(midiData[0] & 0xf0) //status byte (all channels) 532 468 { 533 469 case 0x80: //note off 534 notes[npos++] = event->deltaFrames; //delta 535 notes[npos++] = midiData[1] & 0x7F; //note 536 notes[npos++] = 0; //vel 470 noteOn(midiData[1] & 0x7F, 0); 537 471 break; 538 472 539 473 case 0x90: //note on 540 notes[npos++] = event->deltaFrames; //delta 541 notes[npos++] = midiData[1] & 0x7F; //note 542 notes[npos++] = midiData[2] & 0x7F; //vel 474 noteOn(midiData[1] & 0x7F, midiData[2] & 0x7F); 543 475 break; 544 476 … … 560 492 if(sustain==0) 561 493 { 562 notes[npos++] = event->deltaFrames; 563 notes[npos++] = SUSTAIN; //end all sustained notes 564 notes[npos++] = 0; 494 noteOn(SUSTAIN, 0); //end all sustained notes 565 495 } 566 496 break; … … 584 514 } 585 515 586 if(npos>EVENTBUFFER) npos -= 3; //discard events if buffer full!!587 event++; //?588 }589 notes[npos] = EVENTS_DONE;590 516 return 1; 591 517 } -
trunk/plugins/mda.lv2/src/mdaPiano.h
r4127 r4215 81 81 ~mdaPiano(); 82 82 83 virtual void process(float **inputs, float **outputs, int32_t sampleframes);84 83 virtual void processReplacing(float **inputs, float **outputs, int32_t sampleframes); 85 virtual int32_t processEvents(LvzEvents* events);86 84 87 85 virtual void setProgram(int32_t program); … … 103 101 virtual bool getProductString (char* text); 104 102 virtual int32_t getVendorVersion () {return 1;} 105 virtual int32_t canDo (c har* text);103 virtual int32_t canDo (const char* text); 106 104 107 105 virtual int32_t getNumMidiInputChannels () { return 1; } … … 111 109 112 110 private: 111 int32_t processEvent(const LV2_Atom_Event* ev); 113 112 void update(); //my parameter update 114 113 void noteOn(int32_t note, int32_t velocity); … … 119 118 mdaPianoProgram* programs; 120 119 float Fs, iFs; 121 122 #define EVENTBUFFER 120123 #define EVENTS_DONE 99999999124 int32_t notes[EVENTBUFFER + 8]; //list of delta|note|velocity for current block125 120 126 121 ///global internal variables
Note: See TracChangeset
for help on using the changeset viewer.
