//----------------------------------------------------------------------------------------- void MidiNotesToCC::setParameter(VstInt32 index, float value){ MidiNotesToCCProgram* ap = &programs[curProgram]; switch(index){ case kNoteHi : if (value<fNoteLo) setParameterAutomated(kNoteLo,value); fNoteHi = ap->fNoteHi = value; break; case kNoteLo : if (value>fNoteHi) setParameterAutomated(kNoteHi,value); fNoteLo = ap->fNoteLo = value; break; case kVeloHi : if (value<fVeloLo) setParameterAutomated(kVeloLo,value); fVeloHi = ap->fVeloHi = value; break; case kVeloLo : if (value>fVeloHi) setParameterAutomated(kVeloHi,value); fVeloLo = ap->fVeloLo = value; break; case kChin : fChin = ap->fChin = value; break; case kNCC : fNCC = ap->fNCC = value; break; case kNCCoff : fNCCoff = ap->fNCCoff = value; break; case kNCCHi : fNCCHi = ap->fNCCHi = value; break; case kNCCLo : fNCCLo = ap->fNCCLo = value; break; case kVCC : fVCC = ap->fVCC = value; break; case kVCCoff : fVCCoff = ap->fVCCoff = value; break; case kVCCHi : fVCCHi = ap->fVCCHi = value; break; case kVCCLo : fVCCLo = ap->fVCCLo = value; break; case kChout : fChout = ap->fChout = value; break; case kThru : fThru = ap->fThru = value; break; default : break; } }
//----------------------------------------------------------------------------------------- void ForceToRange::setParameter (VstInt32 index, float value) { if (index < numParams) { ForceToRangeProgram* ap = &programs[curProgram]; param[index] = ap->param[index] = value; if (index==kHighNote) { if (value<param[kLowNote]) setParameterAutomated(kLowNote,value); } else if (index==kLowNote) { if (value>param[kHighNote]) setParameterAutomated(kHighNote,value); } } }
//----------------------------------------------------------------------------------------- void MidiCCStepper::setParameter(VstInt32 index, float value){ MidiCCStepperProgram* ap = &programs[curProgram]; param[index] = ap->param[index] = value; switch(index) { case kLowCC: if (value>param[kHighCC]) setParameterAutomated(kHighCC,value); break; case kHighCC: if (value<param[kLowCC]) setParameterAutomated(kLowCC,value); break; case kTimeQ: //beatdiv = "how many fit in a beat" if (param[index]==0.0f) beatdiv = 32.0f; //128th else if (param[index]<0.05f) beatdiv = 24.f; //64th triplet else if (param[index]<0.1f) beatdiv = 21.33333333f; //dotted 128th else if (param[index]<0.15f) beatdiv = 16.f; //64th else if (param[index]<0.2f) beatdiv = 12.f; //32nd triplet else if (param[index]<0.25f) beatdiv = 10.66666667f; //dotted 64th else if (param[index]<0.3f) beatdiv = 8.f; //32nd else if (param[index]<0.35f) beatdiv = 6.f; //16th triplet else if (param[index]<0.4f) beatdiv = 5.333333333f; //dotted 32nd else if (param[index]<0.45) beatdiv = 4.f; //16th else if (param[index]<0.5f) beatdiv = 3.f; //8th triplet else if (param[index]<0.55f) beatdiv = 2.666666667f; //dotted 16th else if (param[index]<0.6f) beatdiv = 2.f; //8th else if (param[index]<0.65f) beatdiv = 1.5f; //quarter triplet else if (param[index]<0.7f) beatdiv = 1.333333333f; //dotted 8th else if (param[index]<0.75f) beatdiv = 1.f; //quarter else if (param[index]<0.8f) beatdiv = 0.75f; //half triplet else if (param[index]<0.85f) beatdiv = 0.666666667f; //dotted quarter else if (param[index]<0.9f) beatdiv = 0.5; //half else if (param[index]<0.95f) beatdiv = 0.375f; //whole triplet else if (param[index]<1.0f) beatdiv = 0.333333333f; //dotted half else beatdiv = 0.25f; //whole break; //case kBeatOffset: // if (param[kSync]<0.5f) // leftOverSamples = roundToInt((float)samplesPerStep*(param[kBeatOffset]/beatdiv)); // break; default: break; } }
// The user has changed some control's value void ZynWise::ParamChanged(int index, double value) { if (index < 0) return; if (index < kParamsCount) // notify the host setParameterAutomated(index, (float)value); else { _gui->GetView()->OnUpdate(index, value); } }
//------------------------------------------------------------------------ void Midi16CCRouter::setProgram (VstInt32 program) { Midi16CCRouterProgram* ap = &programs[program]; curProgram = program; if (automated) { for (int i=0;i<kNumParams;i++) { setParameterAutomated (i, ap->param[i]); } updateDisplay(); automated=false; } else { for (int i=0;i<kNumParams;i++) { setParameter (i, ap->param[i]); } } }
void MidiChs::Reset() { setParameterAutomated (kChannel1, CHANNEL_TO_FLOAT(0) ); setParameterAutomated (kChannel2, CHANNEL_TO_FLOAT(1) ); setParameterAutomated (kChannel3, CHANNEL_TO_FLOAT(2) ); setParameterAutomated (kChannel4, CHANNEL_TO_FLOAT(3) ); setParameterAutomated (kChannel5, CHANNEL_TO_FLOAT(4) ); setParameterAutomated (kChannel6, CHANNEL_TO_FLOAT(5) ); setParameterAutomated (kChannel7, CHANNEL_TO_FLOAT(6) ); setParameterAutomated (kChannel8, CHANNEL_TO_FLOAT(7) ); setParameterAutomated (kChannel9, CHANNEL_TO_FLOAT(8) ); setParameterAutomated (kChannel10, CHANNEL_TO_FLOAT(9) ); setParameterAutomated (kChannel11, CHANNEL_TO_FLOAT(10) ); setParameterAutomated (kChannel12, CHANNEL_TO_FLOAT(11) ); setParameterAutomated (kChannel13, CHANNEL_TO_FLOAT(12) ); setParameterAutomated (kChannel14, CHANNEL_TO_FLOAT(13) ); setParameterAutomated (kChannel15, CHANNEL_TO_FLOAT(14) ); setParameterAutomated (kChannel16, CHANNEL_TO_FLOAT(15) ); setParameterAutomated (kClear, 0.4f); setParameterAutomated (kReset, 0.4f); updateDisplay(); }
void MidiChs::Clear() { setParameterAutomated (kChannel1, 0 ); setParameterAutomated (kChannel2, 0 ); setParameterAutomated (kChannel3, 0 ); setParameterAutomated (kChannel4, 0 ); setParameterAutomated (kChannel5, 0 ); setParameterAutomated (kChannel6, 0 ); setParameterAutomated (kChannel7, 0 ); setParameterAutomated (kChannel8, 0 ); setParameterAutomated (kChannel9, 0 ); setParameterAutomated (kChannel10, 0 ); setParameterAutomated (kChannel11, 0 ); setParameterAutomated (kChannel12, 0 ); setParameterAutomated (kChannel13, 0 ); setParameterAutomated (kChannel14, 0 ); setParameterAutomated (kChannel15, 0 ); setParameterAutomated (kChannel16, 0 ); setParameterAutomated (kReset, 0.4f); setParameterAutomated (kClear, 0.4f); updateDisplay(); }
void MidiSostenuto::processMidiEvents(VstMidiEventVec *inputs, VstMidiEventVec *outputs, VstInt32 sampleFrames) { short outchannel = FLOAT_TO_CHANNEL015(fParam05); int n; discard=0; // use "Pedal Position" parameter as the pedal CCvalue_current = FLOAT_TO_MIDI(fParam04); if (CCvalue_current >= PEDAL_THRESHOLD && CCvalue_prev < PEDAL_THRESHOLD) { sostenuto = 1; for (n=0; n<128; n++) { sustained_notes[n] = held_notes[n]; } } else if (CCvalue_current < PEDAL_THRESHOLD && CCvalue_prev >= PEDAL_THRESHOLD && sostenuto == 1) { sostenuto = 0; for (n=0; n<128; n++) { if (sustained_notes[n] == 1) { sustained_notes[n] = 0; if (held_notes[n] != 1) { //don't turn it off if it's being held manually VstMidiEvent noteoffplease = inputs[0][0]; noteoffplease.midiData[0] = MIDI_NOTEOFF + outchannel; noteoffplease.midiData[1] = n; noteoffplease.midiData[2] = 0; outputs[0].push_back(noteoffplease); } } } } CCvalue_prev = CCvalue_current; // process incoming events for (unsigned int i=0; i<inputs[0].size(); i++) { //copying event "i" from input (with all its fields) VstMidiEvent tomod = inputs[0][i]; short status = tomod.midiData[0] & 0xf0; // scraping channel short channel = tomod.midiData[0] & 0x0f; // isolating channel short data1 = tomod.midiData[1] & 0x7f; short data2 = tomod.midiData[2] & 0x7f; short listenCC = FLOAT_TO_MIDI(fParam01); short lownote = FLOAT_TO_MIDI(fParam02); short highnote = FLOAT_TO_MIDI(fParam03); if (channel == outchannel) { //only look at the selected channel if (status == MIDI_CONTROLCHANGE && data1 == MIDI_ALL_NOTES_OFF) { //handle midi panic setParameter(kParam04, MIDI_TO_FLOAT(0)); sostenuto = 0; for (n=0; n<128; n++) { if (sustained_notes[n] == 1) { sustained_notes[n] = 0; VstMidiEvent noteoffplease = inputs[0][i]; noteoffplease.midiData[0] = MIDI_NOTEOFF + outchannel; noteoffplease.midiData[1] = n; noteoffplease.midiData[2] = 0; outputs[0].push_back(noteoffplease); } } } if (status == MIDI_NOTEON && data2 > 0) { if (data1 >= lownote && data1 <= highnote) { if (sostenuto == 1) { if (sustained_notes[data1] == 1) { tomod.midiData[0] = MIDI_NOTEOFF + outchannel; noteon_queue[data1] = 1; noteon_queue_velocity[data1] = data2; } } held_notes[data1] = 1; } } else if ((status == MIDI_NOTEOFF) || (status == MIDI_NOTEON && data2 == 0)) { held_notes[data1] = 0; if (sustained_notes[data1] == 1) { discard = 1; } } else if (status == MIDI_CONTROLCHANGE && data1 == listenCC) { setParameterAutomated(kParam04, MIDI_TO_FLOAT(data2)); //energyXT2 used to move the slider with the CC. anybody else? discard = 1; //don't send the CC through if (data2 >= PEDAL_THRESHOLD && sostenuto == 0) { sostenuto = 1; for (n=0; n<128; n++) { sustained_notes[n] = held_notes[n]; } } else if (data2 < PEDAL_THRESHOLD && sostenuto == 1) { sostenuto = 0; for (n=0; n<128; n++) { if (sustained_notes[n] == 1) { sustained_notes[n] = 0; if (held_notes[n] != 1) { //don't turn it off if it's being held manually VstMidiEvent noteoffplease = inputs[0][i]; noteoffplease.midiData[0] = MIDI_NOTEOFF + outchannel; noteoffplease.midiData[1] = n; noteoffplease.midiData[2] = 0; outputs[0].push_back(noteoffplease); } } } } } } //pushing back our copied midi event from input, modified or not! if (discard != 1) outputs[0].push_back(tomod); //else discard = 0; //create queued events for (n=0; n<128; n++) { if (noteon_queue[n] == 1) { VstMidiEvent noteonplease = inputs[0][i]; noteonplease.midiData[0] = MIDI_NOTEON + outchannel; noteonplease.midiData[1] = n; noteonplease.midiData[2] = (char)noteon_queue_velocity[n]; outputs[0].push_back(noteonplease); noteon_queue[n] = 0; } } } }
void MidiKeySplit4::processMidiEvents(VstMidiEventVec *inputs, VstMidiEventVec *outputs, VstInt32 sampleFrames) { const char ch = FLOAT_TO_CHANNEL015(param[kInChannel]); signed char ch1 = FLOAT_TO_CHANNEL(param[kOutChannel1]); signed char ch2 = FLOAT_TO_CHANNEL(param[kOutChannel2]); signed char ch3 = FLOAT_TO_CHANNEL(param[kOutChannel3]); signed char ch4 = FLOAT_TO_CHANNEL(param[kOutChannel4]); const char split1 = FLOAT_TO_MIDI_X(param[kSplit1]); const char split2 = FLOAT_TO_MIDI_X(param[kSplit2]); const char split3 = FLOAT_TO_MIDI_X(param[kSplit3]); const char transp1 = roundToInt(96.f*param[kTransp1])-48; const char transp2 = roundToInt(96.f*param[kTransp2])-48; const char transp3 = roundToInt(96.f*param[kTransp3])-48; const char transp4 = roundToInt(96.f*param[kTransp4])-48; // process incoming events for (unsigned int i=0;i<inputs[0].size();i++) { //copying event "i" from input (with all its fields) VstMidiEvent tomod = inputs[0][i]; int status = tomod.midiData[0] & 0xf0; // scraping channel int channel = tomod.midiData[0] & 0x0f; // isolating channel int data1 = tomod.midiData[1] & 0x7f; int data2 = tomod.midiData[2] & 0x7f; if (status==MIDI_NOTEON && data2==0) status=MIDI_NOTEOFF; if (ch1==-1) ch1=channel; if (ch2==-1) ch2=channel; if (ch3==-1) ch3=channel; if (ch4==-1) ch4=channel; if (channel==ch) { if (status==MIDI_NOTEON) { if (split1==learn) { setParameterAutomated(kSplit1,MIDI_TO_FLOAT_X(data1)); } if (split2==learn) { setParameterAutomated(kSplit2,MIDI_TO_FLOAT_X(data1)); } if (split3==learn) { setParameterAutomated(kSplit3,MIDI_TO_FLOAT_X(data1)); } if (data1<split1) { transposed[data1] = transp1; tomod.midiData[0] = status | ch1; tomod.midiData[1] = midiLimit(data1+transp1); } else if (data1<split2) { transposed[data1] = transp2; tomod.midiData[0] = status | ch2; tomod.midiData[1] = midiLimit(data1+transp2); } else if (data1<split3) { transposed[data1] = transp3; tomod.midiData[0] = status | ch3; tomod.midiData[1] = midiLimit(data1+transp3); } else { transposed[data1] = transp4; tomod.midiData[0] = status | ch4; tomod.midiData[1] = midiLimit(data1+transp4); } } else if (status==MIDI_NOTEOFF) { if (data1<split1) { tomod.midiData[0] = status | ch1; tomod.midiData[1] = midiLimit(data1+transposed[data1]); transposed[data1]=-999; } else if (data1<split2) { tomod.midiData[0] = status | ch2; tomod.midiData[1] = midiLimit(data1+transposed[data1]); transposed[data1]=-999; } else if (data1<split3) { tomod.midiData[0] = status | ch3; tomod.midiData[1] = midiLimit(data1+transposed[data1]); transposed[data1]=-999; } else { tomod.midiData[0] = status | ch4; tomod.midiData[1] = midiLimit(data1+transposed[data1]); transposed[data1]=-999; } } if (status==MIDI_POLYKEYPRESSURE) { if (data1<split1) { tomod.midiData[0] = status | ch1; tomod.midiData[1] = midiLimit(data1+transp1); } else if (data1<split2) { tomod.midiData[0] = status | ch2; tomod.midiData[1] = midiLimit(data1+transp2); } else if (data1<split3) { tomod.midiData[0] = status | ch3; tomod.midiData[1] = midiLimit(data1+transp3); } else { tomod.midiData[0] = status | ch4; tomod.midiData[1] = midiLimit(data1+transp4); } } } outputs[0].push_back(tomod); } }
void MidiNoteGroups::processMidiEvents(VstMidiEventVec *inputs, VstMidiEventVec *outputs, VstInt32 samples) { //process incoming events------------------------------------------------------- for (unsigned int i=0;i<inputs[0].size();i++) { //copying event "i" from input (with all its fields) VstMidiEvent tomod = inputs[0][i]; const int channel = tomod.midiData[0] & 0x0f; // isolating channel (0-15) const int data1 = tomod.midiData[1] & 0x7f; const int data2 = tomod.midiData[2] & 0x7f; const int status = (tomod.midiData[0] & 0xf0)==MIDI_NOTEON && data2==0 ? MIDI_NOTEOFF : tomod.midiData[0] & 0xf0; // scraping channel int listenchannel = FLOAT_TO_CHANNEL015(param[kChannel]); bool discard = param[kThru]<0.5f; Slot slot[kNumSlots]; for (int s=0;s<kNumSlots;s++) { slot[s].note = FLOAT_TO_MIDI3(param[kNote+s*3]); slot[s].playgroup = FLOAT_TO_GROUP(param[kPlay+s*3]); slot[s].chokegroup = FLOAT_TO_GROUP(param[kChoke+s*3]); } if (channel == listenchannel) { if (status == MIDI_NOTEON) { for (int i=0;i<kNumSlots;i++) { if (slot[i].note==learn) { discard=true; setParameterAutomated(kNote+i*3,MIDI_TO_FLOAT3(data1)); } if (data1 == slot[i].note) { discard=false; if (slot[i].chokegroup>-1) { //end other notes in choke group for (int s=0;s<kNumSlots;s++) { if (slot[s].chokegroup==slot[i].chokegroup) { if (notesPlaying[slot[s].note]) { VstMidiEvent m = tomod; m.midiData[0] = MIDI_NOTEOFF | channel; m.midiData[1] = slot[s].note; m.midiData[2] = 0; outputs[0].push_back(m); notesPlaying[slot[s].note]=false; } } } } if (slot[i].playgroup>-1) { //play other notes in play group for (int s=0;s<kNumSlots;s++) { if (slot[s].playgroup==slot[i].playgroup) { if (!notesPlaying[slot[s].note]) { VstMidiEvent m = tomod; m.midiData[0] = MIDI_NOTEON | channel; m.midiData[1] = slot[s].note; m.midiData[2] = data2; outputs[0].push_back(m); notesPlaying[slot[s].note]=true; } } } } } } if (notesPlaying[data1]) discard=true; if (!discard) notesPlaying[data1]=true; } else if (status == MIDI_NOTEOFF) { for (int i=0;i<kNumSlots;i++) { if (data1 == slot[i].note) { discard=false; if (slot[i].playgroup>-1) { //end other notes in play group for (int s=0;s<kNumSlots;s++) { if (slot[s].playgroup==slot[i].playgroup) { if (notesPlaying[slot[s].note]) { VstMidiEvent m = tomod; m.midiData[0] = MIDI_NOTEOFF | channel; m.midiData[1] = slot[s].note; m.midiData[2] = 0; outputs[0].push_back(m); notesPlaying[slot[s].note]=false; } } } } } } if (!notesPlaying[data1]) discard=true; if (!discard) notesPlaying[data1]=false; } else if (status == MIDI_PROGRAMCHANGE) { //end playing notes before changing program for (int i=0;i<128;i++) { if (notesPlaying[i]) { VstMidiEvent m = tomod; m.midiData[0] = MIDI_NOTEOFF | channel; m.midiData[1] = i; m.midiData[2] = 0; notesPlaying[i]=false; } } if (param[kProgCh]>=0.5f) setProgram(data1); } } if (!discard) outputs[0].push_back(tomod); }//for() inputs loop wasplaying=isplaying; }
void MidiForceToKey::processMidiEvents(VstMidiEventVec *inputs, VstMidiEventVec *outputs, VstInt32 sampleFrames) { const int tchannel = FLOAT_TO_CHANNEL(fChannel); const int nchannel = FLOAT_TO_CHANNEL(fNChannel); int transposey = roundToInt(fTranspose*100.f)-50; bool noteswitch[12] = {n0>=0.5f,n1>=0.5f,n2>=0.5f,n3>=0.5f,n4>=0.5f,n5>=0.5f, n6>=0.5f,n7>=0.5f,n8>=0.5f,n9>=0.5f,n10>=0.5f,n11>=0.5f}; for (unsigned int i=0;i<inputs[0].size();i++) { VstMidiEvent tomod = inputs[0][i]; const int status = tomod.midiData[0] & 0xf0; // scraping channel const int channel = tomod.midiData[0] & 0x0f; // isolating channel (0-15) const int data1 = tomod.midiData[1] & 0x7f; //int data2 = tomod.midiData[2] & 0x7f; bool discard = false; if (status==MIDI_PROGRAMCHANGE) { if (data1<kNumPrograms && fUsePC>=0.5f) { setProgram(data1); updateDisplay(); } } //set key notes based on "note channel" if (channel == nchannel) { discard = true; if (isNoteOn(tomod)) { int n = data1%12; if (fNChMode<0.5f && !noteswitch[n]) { noteswitch[n] = true; setParameterAutomated(k0+n, 1.f); } else { noteswitch[n] = !noteswitch[n]; setParameterAutomated(k0+n, noteswitch[n] ? 1.f : 0.f); } } else if (isNoteOff(tomod) && fNChMode<0.5f) { int n = data1%12; noteswitch[n] = false; setParameterAutomated(k0+n, 0.f); } } else { if (isNoteOn(tomod)) { if (!noteswitch[data1%12]) { dbg("wrong note " << data1); int transpose = 0; int j = -1; switch (mode) { //nearest note, down when tied (same as ndc) case nearest: discard = true; while (j<12) { if (noteswitch[(data1+j)%12]) { transpose = j; discard = false; break; } if (j<0) j = -j; else j = -j - 1; } break; //always up case alwaysup: j = 1; discard = true; while (j<12) { if (noteswitch[(data1+j)%12]) { transpose = j; discard = false; break; } j++; } break; //always down case alwaysdown: discard = true; while (j<12) { if (noteswitch[(data1+j)%12]) { transpose = j; discard = false; break; } j--; } break; //block wrong notes case block: dbg("block note"); discard = true; transposed[data1][channel]=-999; break; case off: default: break; } tomod.midiData[1] = data1 + transpose; } //transpose based on notes on "transpose channel" if (channel==tchannel) { dbg("tchannel"); discard=true; int root=FLOAT_TO_MIDI(fRoot); int m = 0; int counter=0; if (tomod.midiData[1] > root) { while (counter<(tomod.midiData[1]-root)) { m++; if (noteswitch[(root+m)%12]) counter++; if (tomod.midiData[1] - m == root) break; } } else if (tomod.midiData[1] < root) { while (counter>(tomod.midiData[1]-root)) { m++; if (noteswitch[(root-m)%12]) counter--; if (tomod.midiData[1] + m == root) break; } } transposey = counter; setParameterAutomated(kTranspose, ((float)(transposey+50))*0.01f); } } } if (!discard) { dbg("keep event"); if (isNoteOn(tomod) || status==MIDI_POLYKEYPRESSURE) { if (transposey > 0) { //move the note up to the right scale degree int counter=0; int m=0; while (counter<transposey) { m++; if (noteswitch[(tomod.midiData[1]+m)%12]) counter++; if ((tomod.midiData[1]+m) == 127) break; } tomod.midiData[1] += m; } else if (transposey < 0) { //move the note down the scale int counter=0; int m=0; while (counter>transposey) { m++; if (noteswitch[(tomod.midiData[1]-m)%12]) counter--; if ((tomod.midiData[1]-m) == 0) break; } tomod.midiData[1] -= m; } if (isNoteOn(tomod)) transposed[data1][channel] = tomod.midiData[1]; } else if (isNoteOff(tomod)) { dbg("noteoff " << data1 << " transposed " << transposed[data1][channel]); if (channel == tchannel) discard = true; // always transpose noteoff by the same amount as the noteon was transposed if (transposed[data1][channel]==-999) discard = true; else tomod.midiData[1] = transposed[data1][channel]; transposed[data1][channel] = data1; } if (!discard) outputs[0].push_back(tomod); } } }