ArrayArrayArrayArrayArrayArrayArrayArrayArray
Statistics: Posted by woodslanding — 03 Nov 2017, 06:38
CODE:
NOTE OFF 90 0 c:16 NOTE OFF 91 0 c:16 NOTE OFF 92 0 c:16 NOTE OFF 93 0 c:16 NOTE OFF 94 0 c:16 NOTE OFF 95 0 c:16 NOTE OFF 96 0 c:16 NOTE OFF 97 0 c:16 NOTE OFF 98 0 c:16 NOTE OFF 99 0 c:16 NOTE OFF 100 0 c:16 NOTE OFF 101 0 c:16 NOTE OFF 102 0 c:16 NOTE OFF 103 0 c:16 NOTE OFF 104 0 c:16 NOTE OFF 105 0 c:16 NOTE OFF 106 0 c:16 NOTE OFF 107 0 c:16 NOTE OFF 108 0 c:16 NOTE OFF 109 0 c:16 NOTE OFF 110 0 c:16 NOTE OFF 111 0 c:16 NOTE OFF 112 0 c:16 NOTE OFF 113 0 c:16 NOTE OFF 114 0 c:16 NOTE OFF 115 0 c:16 NOTE OFF 116 0 c:16 NOTE OFF 117 0 c:16 NOTE OFF 118 0 c:16 NOTE OFF 119 0 c:16 NOTE OFF 120 0 c:16 NOTE OFF 121 0 c:16 NOTE OFF 122 0 c:16 NOTE OFF 123 0 c:16 NOTE OFF 124 0 c:16 NOTE OFF 125 0 c:16 NOTE OFF 126 0 c:16 NOTE OFF 127 0 c:16 CTRL CHANGE 64 0 c:16Error : E901 patch process : Process of MIDI In (rack: 3) patch: gui.patCODE:
/////////////////////////////////////////////////////////////////////////////// MIDI_OMNI value is causing error--// Error : E901 patch process : Process of MIDI In (following rack patch)// /////////////////////////////////////////////////////////////////////////////const MIDI_OMNI = 0;const MIDI_OFF = 17;const CH_ENABLED = 1;const CH_DISABLED = 0;const CH_NOTESOLOED = 2; //a note solo instrument will mute other instruments on its channel over its key rangeconst CH_COMPROMISED = 3;//when all or part of the noterange is muted by a notesolo inst on another trackVAR midiIN, midiOUT : Tparameter;// from NS var transposeIN: Tparameter;var lowNoteIN : Tparameter; var hiNoteIN : Tparameter;var chanIN : Tparameter;var statusOUT : Tparameter;var vstChIN : Tparameter;// from mixervar handsIN : Tparameter; var holdIN : Tparameter;var trackIN : Tparameter; var enabledIN : Tparameter; // from inst var transToCtlIN : Tparameter;var resetClkIN : Tparameter;var resetVelIN : Tparameter;//arraysvar nSolosIN : Tparameter; var noSusIN : Tparameter;var nsLowNotesIN : Tparameter;var nsHiNotesIN : Tparameter; var resetClkOUT : Tparameter; var clearIN : Tparameter; VAR transpositions : ARRAY OF integer;VAR noteONs : ARRAY OF boolean; VAR midi : tMidi; VAR outCount, transpose,transCtl, trackCount, trackNum,status : integer;VAR newTranspose,hands,hold,resetClk,resetting: boolean; var lowNote,hiNote,nSoloLow,nSoloHi, inputCh, vstChan, resetVel: integer; var nSolo, clearNotes, enabled,noSus,statusChanged: boolean;PROCEDURE Init;var i : integer; BEGIN //from NS midiIN := CreateParam('midi in', ptMidi); SetIsOutput(midiIN, FALSE); //18 = OMNI, 17 = Disable Midi note Processing (for normal fx) chanIN := CreateParam('midi chan', ptDatafield); SetIsOutput(chanIN, FALSE); lowNoteIN := CreateParam('low note', ptDataField); SetIsOutput(lowNoteIN, FALSE); hiNoteIN := CreateParam('hi note', ptDataField); SetIsOutput(hiNoteIN, FALSE);//from mixer transposeIN := CreateParam('transpose', ptDataField);SetIsOutput(transposeIN, FALSE); handsIN := CreateParam('hands on',ptSwitch); SetIsOutput(handsIN, false); holdIN := CreateParam('hold on',ptSwitch); SetIsOutput(holdIN, false); //from inst transToCtlIN := CreateParam('transToCtl',ptDatafield); SetIsOutput(transToCtlIN, false); //ns array is an array [1..trackcount] of midi channels. 0 means either the chan is disabled, or it is not a ns channel nSolosIN := CreateParam('nsSolo arr',ptArray); SetIsOutput(nSolosIN, false); nsLowNotesIN := CreateParam('ns low arr',ptArray); SetIsOutput(nsLowNotesIN, false); nsHiNotesIN := CreateParam('ns high arr',ptArray); SetIsOutput(nsHiNotesIN, false); // what ch the vst inst wants to see. If INPUT CH is OMNI or OFF, this doesn't matter vstChIN := CreateParam('vst chan', ptDatafield); SetIsOutput(vstChIN, FALSE); clearIN := CreateParam('clear notes',ptSwitch); SetIsOutput(clearIN, false); resetClkIN := CreateParam('vel clock reset', ptDatafield); SetIsOutput(resetClkIN, FALSE); resetVelIN := CreateParam('reset vel thresh', ptDatafield); SetIsOutput(resetVelIN, FALSE); trackIN := CreateParam('track num', ptDatafield); SetIsOutput(trackIN, FALSE); enabledIN := CreateParam('enable', ptDatafield); SetIsOutput(enabledIN, FALSE); noSusIN := CreateParam('no sus', ptDatafield); SetIsOutput(noSusIN, FALSE); resetClkOUT := CreateParam('reset clock', ptDatafield); SetIsInput(resetClkOUT, FALSE); midiOUT := CreateParam('midi out', ptMidi); SetIsInput(midiOUT, FALSE); statusOUT := CreateParam('status', ptDatafield); SetIsInput(statusOUT, FALSE); SetArrayLength(transpositions, 128); SetArrayLength(noteONs, 128); for i := 0 to 127 DO BEGIN transpositions[i] := 0; noteOns[i] := FALSE; END; clearNotes := FALSE; newTranspose := FALSE; statusChanged := FALSE; setLength(resetClkOUT,0); strace('INIT FINISHED--MIDIINPUTPROC');END; // Initprocedure makeHands;var note : integer; begin hands := trunc(getValue(handsIN)); if hands then begin note := midi.data1; if note > 60 then midi.data1 := note - 12 else midi.data1 := note + 12; end; end;procedure callback(n: integer);BEGIN //strace('MIDIINPUTPROC CALLBACK: n = ' + inttostr(n)); IF (n = 0) THEN //ignore ELSE IF (n = transposeIN) THEN newTranspose := TRUE ELSE IF (n = trackIN) THEN trackNum := trunc(getValue(trackIN)) ELSE IF (n = transToCtlIN) THEN transCtl := trunc(getValue(transToCtlIN)) ELSE IF (n = resetClkIN) THEN resetClk := trunc(getValue(resetClkIN)) = 1 ELSE IF (n = resetVelIN) THEN resetVel := trunc(getValue(resetVelIN)) ELSE IF (n = noSusIN) THEN noSus := (trunc(getValue(noSusIN)) > 0) ELSE IF (n = holdIN) THEN BEGIN hold := (trunc(getValue(holdIN)) = 1); //strace('hold setting clear notes if it is off'); //if we just turned off hold, clear notes IF NOT hold then clearNotes := TRUE; END ELSE IF (n = enabledIN) THEN BEGIN hold := (trunc(getValue(holdIN)) = 1); enabled := trunc(getValue(enabledIN)) = 1; //strace('enabled setting clear notes if not enabled and not hold'); if NOT enabled and NOT hold then clearNotes := TRUE; statusChanged := true; END //some other inst has changed, so we need to check status ELSE IF (n = nsHiNotesIN) OR (n= nsLowNotesIN) OR (n = nSolosIN) THEN statusChanged := true ELSE IF (n = resetClkOUT) OR (n = midiOUT) OR (n = statusOUT) THEN //why,it's an output?????? ELSE BEGIN IF (n = handsIN) THEN hands := trunc(getValue(handsIN)) ELSE IF (n = vstChIN) THEN vstChan := trunc(getValue(vstChIN)) ELSE IF (n = lowNoteIN) THEN lowNote := trunc(getValue(lowNoteIN)) ELSE IF (n = hiNoteIN) THEN hiNote := trunc(getValue(hiNoteIN)) ELSE IF (n = chanIN) THEN inputCh := trunc(getValue(chanIN)); statusChanged := true; clearNotes := TRUE; //strace('setting clearNotes to true via hands, outch, lownote hinote, or chan'); END; END; procedure processIdle;var compromised : boolean;var i : integer;BEGIN if (statusChanged) then BEGIN //maybe we can stop short notes when ch is re-enabled.... clearNotes := TRUE; compromised := false; status := CH_ENABLED; //maybe these aren't always initialized???? vstChan := trunc(getValue(vstChIN)); inputCh := trunc(getValue(chanIN)); enabled := trunc(getValue(enabledIN)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); trackNum := trunc(getValue(trackIN)); if not enabled THEN status := CH_DISABLED ELSE BEGIN //check our own status //strace('CHECKING STATUS-----------------------------------------'); trackCount := getLength(nSolosIN); //figure key range based on NS nSolo := (getDataArrayValue(nSolosIN,trackNum - 1) = inputCh); IF nSolo THEN BEGIN nSoloHI := trunc(getDataArrayValue(nsHiNotesIN, trackNum - 1)); nSoloLow := trunc(getDataArrayValue(nsLowNotesIN, trackNum - 1)); IF nSoloHI < hiNote THEN hiNote := nSoloHI; IF nSoloLow > lowNote THEN lowNote := nSoloLow; END ELSE BEGIN // reset the keyboard range... //strace('resetting keyboard range for channel ' + inttostr(trackNum)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); END; //No notesoloing for FX (ch 17) IF (inputCH = MIDI_OFF) THEN BEGIN IF enabled THEN status := CH_ENABLED ELSE status := CH_DISABLED; END //cannot be note solo in omni mode! ELSE IF (inputCH <> MIDI_OMNI) and nSolo THEN BEGIN //we are a note solo inst //strace('note solo ON for track number ' + intToStr(trackNum)); status := CH_NOTESOLOED; END ELSE BEGIN // compute status and nsInfo from arrays nSoloHI := 0; nSoloLow := 127 for i := 0 to trackCount - 1 do BEGIN if (inputCH <> MIDI_OMNI) and (getDataArrayValue(nSolosIN,i) = inputCH) then BEGIN //we are note solo compromised. //strace('note solo affecting track number ' + intToStr(trackNum)); compromised := true; if (getDataArrayValue(nsHiNotesIN,i) > nSoloHI) then nSoloHI := trunc(getDataArrayValue(nsHiNotesIN,i)); if (getDataArrayValue(nsLowNotesIN,i) < nSoloLow) then nSoloLow := trunc(getDataArrayValue(nsLowNotesIN,i)); END; END; //strace('notesoloLow = ' + intToStr(nSoloLow)); //strace('notesoloHi = ' + intToStr(nSoloHi)); if compromised then status := CH_COMPROMISED ELSE status := CH_ENABLED; END; END; //strace('Status Set------------------------'); setValue(statusOUT,status); END; statusChanged := false;END; procedure writeToMidiArray;begin SetMidiArrayValue(midiOUT, outcount, midi); strace('added midi message num ' + inttostr(outCount)); outCount := outCount + 1; end;procedure sendNoteOffs(); var minCH,maxCH,ch,i : integer;BEGIN //strace('clearing notes'); //for omni sources, send noteoffs on every channel... //otherwise just send to the chan VST is receiving on //strace('vst channel = ' + inttostr(vstChan)); IF (inputCh = MIDI_OMNI) then BEGIN minCH := 1; maxCH := 16; //strace('minCH' = ' + inttostr(minCH)); END ELSE BEGIN minCH = vstChan; maxCH := vstChan; END; //strace('minCH = ' + inttostr(minCH)); if (minCH = 0) then minCH := 1; //avoid 0 value if ch num hasn't been sent yet FOR ch := minCH to maxCH DO BEGIN //strace('in note off subroutine, ch = ' + inttostr(ch)); for i := 0 to 127 DO BEGIN // send note off s if noteONs[i] := TRUE THEN BEGIN midi.channel := ch; midi.msg := 128; midi.data1 := i; midi.data2 := 0; strace('note off for ' + inttostr(i)); writeToMidiArray; noteONs[i] := FALSE; END; END; // send sus pedal off! midi.channel := ch; midi.msg := 176; midi.data1 := 64; midi.data2 := 0; writeToMidiArray; end; clearNotes := FALSE; //(strace('finished with note offs'));end; procedure processMIDI;var vel,note,chan,midiCount,i: integer;BEGIN midiCount := GetLength(midiIN); FOR i := 0 TO (midiCount - 1) DO BEGIN GetMidiArrayValue(midiIN, i, midi); note := midi.data1; vel := midi.data2; chan := midi.channel; IF (inputCh <> MIDI_OMNI) then midi.channel := vstChan; //if midiCH is 0 leave unchanged //pass PB and sus ped messages (if enabled) through... IF (midi.msg = 224) OR ((midi.msg = 172) AND (noSus = false)) THEN BEGIN //strace('message = ' + inttoStr(midi.msg)); writeToMidiArray; END //TODO: how does this work with PB and SUS on multi ch sources? //ignore midi data from other channels. ELSE IF (inputCH <> MIDI_OMNI) AND (chan <> inputCH) THEN ELSE IF (note < lowNote) or (note > hiNote) THEN //ignore notes outside range. True for any status. Includes NS limiting //ignore note solo range on NS channel ELSE IF (status = CH_COMPROMISED) and (nSoloLow <= note) and (note <= nSoloHI) THEN //strace('tracknum = ' + inttostr(trackNum) +', nsolo lo = ' + inttostr(nSoloLow) + ', nSoloHI = ' + inttostr(nSoloHi) + ',note = ' + intToStr(note)); ELSE //process these notes BEGIN IF ((midi.msg = 144) AND (midi.data2 > 0)) THEN BEGIN // NoteOn if hands then makeHands; if resetClk and (vel > resetVel) then begin //strace('resetting------------------------------------- '); setLength(resetClkOUT,1); setValue(resetClkOUT,1); resetting := true; end; if (transCtl = 0) then begin transpositions[midi.data1] := transpose; // Store transpose value used for NoteOn noteOns[midi.data1] := TRUE; midi.data1 := midi.data1 + transpose; end; END ELSE IF ( (midi.msg = 128) OR ((midi.msg = 144) AND (midi.data2 = 0))) THEN BEGIN // NoteOff if hands then makeHands; if (transCtl = 0) then //??? what is this?? why not on NoteOns??? begin // Retrieve stored transpose and add to NoteOff midi.data1 := midi.data1 + transpositions[midi.data1]; noteOns[midi.data1] := FALSE; end; END; //ELSE IF (midi.msg = 172) and (midi.data1 = 64) writeToMidiArray; END; END;END // processprocedure process; var ccTrans: integer;var hasMidi: boolean;var minCH,maxCH,ch,i : integer; BEGIN outCount := 0; inputCh := trunc(getValue(chanIN)); if resetting = true then begin resetting := false; //turn reset back off setValue(resetClkOUT, 0); //null event for off end hasMidi := (GetLength(midiIN) > 0); vstChan := trunc(getValue(vstChIN)); // filter everything but notes, PB and sus for this script! //Hold keeps new notes from being triggered IF hasMidi and (hold = false) and enabled THEN processMIDI; IF clearNotes then sendNoteOffs; IF newTranspose then begin //strace('in NEW TRANSPOSE'); IF (transCtl = 0) then transpose := round(getValue(transposeIN)) ELSE BEGIN transpose := 0; // create midi cc out for drum tuning (cc value is transCtl) ccTrans := (round((transpose * 1.76) + 64)); //strace('____________CC TRANS = ' + intToStr(ccTrans)); midi.msg := 176; midi.channel := 1; midi.data1 := transCtl; midi.data2 := round(ccTrans); writeToMidiArray; END; newTranspose := FALSE; END; SetLength(midiOUT,outCount); //ELSE SetLength(midiOUT, 0) // outCount should just be 0 when appropriate END;Statistics: Posted by woodslanding — 03 Nov 2017, 02:42
Statistics: Posted by woodslanding — 01 Nov 2017, 22:55
Statistics: Posted by sephult — 01 Nov 2017, 16:14
CODE:
/////////////////////////////////////////////////////////////////////////////// VST CH of 0 is causing error// Limit vst ch to 1 thru 16. Use INPUT CH = 0 to stop channelization of messages!/////////////////////////////////////////////////////////////////////////////const STATUS_ENABLED = 1;const STATUS_DISABLED = 0;const STATUS_NOTESOLOED = 2; //a note solo instrument will mute other instruments on its channel over its key rangeconst STATUS_COMPROMISED = 3;//when all or part of the noterange is muted by a notesolo inst on another trackVAR midiIN, midiOUT : Tparameter;// from NS var transposeIN: Tparameter;var lowNoteIN : Tparameter; var hiNoteIN : Tparameter;var chanIN : Tparameter;var statusOUT : Tparameter;var vstChIN : Tparameter;// from mixervar handsIN : Tparameter; var holdIN : Tparameter;var trackIN : Tparameter; var enabledIN : Tparameter; // from inst var transToCtlIN : Tparameter;var resetClkIN : Tparameter;var resetVelIN : Tparameter;//arraysvar nSolosIN : Tparameter; var noSusIN : Tparameter;var nsLowNotesIN : Tparameter;var nsHiNotesIN : Tparameter; var resetClkOUT : Tparameter; var clearIN : Tparameter; VAR transpositions : ARRAY OF integer;VAR noteONs : ARRAY OF boolean; VAR midi : tMidi; VAR midiCount, transpose,transCtl, trackCount, trackNum,status : integer;VAR newTranspose,hands,hold,resetClk,resetting: boolean; var lowNote,hiNote,nSoloLow,nSoloHi, inputCh, vstChan, vel, resetVel: integer; var nSolo, clearNotes, enabled,noSus,statusChanged: boolean;PROCEDURE Init;var i : integer; BEGIN //from NS midiIN := CreateParam('midi in', ptMidi); SetIsOutput(midiIN, FALSE); //0 = OMNI, 17 = Disable Midi note Processing (for normal fx) chanIN := CreateParam('midi chan', ptDatafield); SetIsOutput(chanIN, FALSE); lowNoteIN := CreateParam('low note', ptDataField); SetIsOutput(lowNoteIN, FALSE); hiNoteIN := CreateParam('hi note', ptDataField); SetIsOutput(hiNoteIN, FALSE);//from mixer transposeIN := CreateParam('transpose', ptDataField);SetIsOutput(transposeIN, FALSE); handsIN := CreateParam('hands on',ptSwitch); SetIsOutput(handsIN, false); holdIN := CreateParam('hold on',ptSwitch); SetIsOutput(holdIN, false); //from inst transToCtlIN := CreateParam('transToCtl',ptDatafield); SetIsOutput(transToCtlIN, false); //ns array is an array [1..trackcount] of midi channels. 0 means either the chan is disabled, or it is not a ns channel nSolosIN := CreateParam('nsSolo arr',ptArray); SetIsOutput(nSolosIN, false); nsLowNotesIN := CreateParam('ns low arr',ptArray); SetIsOutput(nsLowNotesIN, false); nsHiNotesIN := CreateParam('ns high arr',ptArray); SetIsOutput(nsHiNotesIN, false); // what ch the vst inst wants to see. If INPUT CH is 0 or 17, this doesn't matter! vstChIN := CreateParam('vst chan', ptDatafield); SetIsOutput(vstChIN, FALSE); clearIN := CreateParam('clear notes',ptSwitch); SetIsOutput(clearIN, false); resetClkIN := CreateParam('vel clock reset', ptDatafield); SetIsOutput(resetClkIN, FALSE); resetVelIN := CreateParam('reset vel thresh', ptDatafield); SetIsOutput(resetVelIN, FALSE); trackIN := CreateParam('track num', ptDatafield); SetIsOutput(trackIN, FALSE); enabledIN := CreateParam('enable', ptDatafield); SetIsOutput(enabledIN, FALSE); noSusIN := CreateParam('no sus', ptDatafield); SetIsOutput(noSusIN, FALSE); resetClkOUT := CreateParam('reset clock', ptDatafield); SetIsInput(resetClkOUT, FALSE); midiOUT := CreateParam('midi out', ptMidi); SetIsInput(midiOUT, FALSE); statusOUT := CreateParam('status', ptDatafield); SetIsInput(statusOUT, FALSE); SetArrayLength(transpositions, 128); SetArrayLength(noteONs, 128); for i := 0 to 127 DO BEGIN transpositions[i] := 0; noteOns[i] := FALSE; END; clearNotes := FALSE; newTranspose := FALSE; statusChanged := FALSE; setLength(resetClkOUT,0); //strace('INIT FINISHED--MIDIINPUTPROC');END; // Initprocedure makeHands;var note : integer;begin hands := trunc(getValue(handsIN)); if hands then begin note := midi.data1; if note > 60 then midi.data1 := note - 12 else midi.data1 := note + 12; end; end;procedure callback(n: integer);BEGIN strace('MIDIINPUTPROC CALLBACK: n = ' + inttostr(n)); IF (n = 0) THEN //ignore ELSE IF (n = transposeIN) THEN newTranspose := TRUE ELSE IF (n = trackIN) THEN trackNum := trunc(getValue(trackIN)) ELSE IF (n = transToCtlIN) THEN transCtl := trunc(getValue(transToCtlIN)) ELSE IF (n = resetClkIN) THEN resetClk := trunc(getValue(resetClkIN)) = 1 ELSE IF (n = resetVelIN) THEN resetVel := trunc(getValue(resetVelIN)) ELSE IF (n = noSusIN) THEN noSus := trunc(getValue(noSusIN)) > 0 ELSE IF (n = holdIN) THEN BEGIN hold := trunc(getValue(holdIN)) = 1; //strace('hold setting clear notes if it is off'); //if we just turned off hold, clear notes IF NOT hold then clearNotes := TRUE; END ELSE IF (n = enabledIN) THEN BEGIN enabled := trunc(getValue(enabledIN)) = 1; //strace('enabled setting clear notes if not enabled and not hold'); if NOT enabled and NOT hold then clearNotes := TRUE; statusChanged := true; END //some other inst has changed, so we need to check status ELSE IF (n = nsHiNotesIN) OR (n= nsLowNotesIN) OR (n = nSolosIN) THEN statusChanged := true ELSE IF (n = resetClkOUT) OR (n = midiOUT) OR (n = statusOUT) THEN //why,it's an output?????? ELSE BEGIN IF (n = handsIN) THEN hands := trunc(getValue(handsIN)) ELSE IF (n = vstChIN) THEN vstChan := trunc(getValue(vstChIN)) ELSE IF (n = lowNoteIN) THEN lowNote := trunc(getValue(lowNoteIN)) ELSE IF (n = hiNoteIN) THEN hiNote := trunc(getValue(hiNoteIN)) ELSE IF (n = chanIN) THEN inputCh := trunc(getValue(chanIN)); statusChanged := true; clearNotes := TRUE; //strace('setting clearNotes to true via hands, outch, lownote hinote, or chan'); END;END; procedure processIdle;var compromised : boolean;var i : integer;BEGIN if (statusChanged) then BEGIN compromised := false; status := STATUS_ENABLED; //maybe these aren't always initialized???? vstChan := trunc(getValue(vstChIN)); inputCh := trunc(getValue(chanIN)); enabled := trunc(getValue(enabledIN)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); trackNum := trunc(getValue(trackIN)); if not enabled THEN status := STATUS_DISABLED ELSE BEGIN //check our own status strace('CHECKING STATUS-----------------------------------------'); trackCount := getLength(nSolosIN); //figure key range based on NS nSolo := getDataArrayValue(nSolosIN,trackNum - 1) = inputCh; IF nSolo THEN BEGIN nSoloHI := trunc(getDataArrayValue(nsHiNotesIN, trackNum - 1)); nSoloLow := trunc(getDataArrayValue(nsLowNotesIN, trackNum - 1)); IF nSoloHI < hiNote THEN hiNote := nSoloHI; IF nSoloLow > lowNote THEN lowNote := nSoloLow; END ELSE BEGIN // reset the keyboard range... //strace('resetting keyboard range for channel ' + inttostr(trackNum)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); END; //No notesoloing for FX (ch 17) IF (inputCH = 17) THEN BEGIN IF enabled THEN status := STATUS_ENABLED ELSE status := STATUS_DISABLED; END //cannot be note solo in omni mode! ELSE IF (inputCH > 0) and nSolo THEN BEGIN //we are a note solo inst //strace('note solo ON for track number ' + intToStr(trackNum)); status := STATUS_NOTESOLOED; END ELSE BEGIN // compute status and nsInfo from arrays nSoloHI := 0; nSoloLow := 127 for i := 0 to trackCount - 1 do BEGIN if (inputCH > 0) and (getDataArrayValue(nSolosIN,i) = inputCH) then BEGIN //we are note solo compromised. strace('note solo affecting track number ' + intToStr(trackNum)); compromised := true; if (getDataArrayValue(nsHiNotesIN,i) > nSoloHI) then nSoloHI := trunc(getDataArrayValue(nsHiNotesIN,i)); if (getDataArrayValue(nsLowNotesIN,i) < nSoloLow) then nSoloLow := trunc(getDataArrayValue(nsLowNotesIN,i)); END; END; strace('notesoloLow = ' + intToStr(nSoloLow)); strace('notesoloHi = ' + intToStr(nSoloHi)); if compromised then status := STATUS_COMPROMISED ELSE status := STATUS_ENABLED; END; END; strace('MADE IT THIS FAR------------------------'); setValue(statusOUT,status) END; statusChanged := false;END; // processprocedure process;var outCount,note,chan: integer; var ccTrans,countOffset: integer;var newMidi: tMidi; var hasMidi: boolean;var minCH,maxCH,ch,i : integer; BEGIN //if input is 17[disabled], bypass midi processing entirely IF (inputCH = 17) THEN SetLength(midiOUT, 0) ELSE BEGIN //should filter all but notes, sustain and pb prev to script midiCount := GetLength(midiIN); hasMidi := midiCount > 0; outCount := 0; if resetting = true then begin resetting := false; //turn reset back off setValue(resetClkOUT, 0); //null event for off end IF clearNotes then BEGIN //strace('clearing notes'); //for omni sources, send noteoffs on every channel... //otherwise just send to the chan VST is receiving on IF (inputCh = 0) then BEGIN minCH := 1; maxCH := 16; END ELSE BEGIN minCH = vstChan; maxCH := vstChan; END; FOR ch := minCH to maxCH DO BEGIN for i := 0 to 127 DO BEGIN // send note off s if noteONs[i] := TRUE THEN BEGIN midi.channel := ch; midi.msg := 128; midi.data1 := i; midi.data2 := 0; setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; noteONs[i] := FALSE; END; END; // send sus pedal off! midi.channel := ch; midi.msg := 176; midi.data1 := 64; midi.data2 := 0; end setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; setLength(midiOUT, outCount); clearNotes := FALSE; //if we are clearing, we ignore other midi input for this cycle.... END ELSE BEGIN if newTranspose then begin //strace('in NEW TRANSPOSE'); IF (transCtl = 0) then transpose := round(getValue(transposeIN)) ELSE BEGIN transpose := 0; // create midi cc out for drum tuning (cc value is transCtl) ccTrans := (round((transpose * 1.76) + 64)); //strace('____________CC TRANS = ' + intToStr(ccTrans)); newMidi.msg := 176; newMidi.channel := 1; newMidi.data1 := transCtl; newMidi.data2 := round(ccTrans); SetMidiArrayValue(midiOUT, outCount, newMidi); outCount := outCount + 1; END; newTranspose := FALSE; end; // filter everything but notes for this script! //Hold keeps new notes from being triggered IF hasMidi and (hold = false) and enabled THEN BEGIN countOffset := outCount; FOR i := 0 TO (midiCount - 1) DO BEGIN GetMidiArrayValue(midiIN, i, midi); note := midi.data1; vel := midi.data2; chan := midi.channel; IF (inputCh > 0) then midi.channel := vstChan; //if midiCH is 0 leave unchanged IF (midi.msg = 224) OR ((midi.msg = 172) AND (noSus = false)) THEN BEGIN //strace('message = ' + inttoStr(midi.msg)); SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END //TODO: how does this work with PB and SUS on multi ch sources? ELSE IF (inputCH > 0) AND (chan <> inputCH) THEN //ignore notes from other channels. 0 is omni. ELSE IF (note < lowNote) or (note > hiNote) THEN //ignore notes outside range. True for any status. Includes NS limiting ELSE IF (status = 3) and (nSoloLow <= note) and (note <= nSoloHI) THEN //ignore note solo range on NS channel //strace('tracknum = ' + inttostr(trackNum) +', nsolo lo = ' + inttostr(nSoloLow) + ', nSoloHI = ' + inttostr(nSoloHi) + ',note = ' + intToStr(note)); ELSE BEGIN IF ((midi.msg = 144) AND (midi.data2 > 0)) THEN BEGIN // NoteOn if hands then makeHands; if resetClk and (vel > resetVel) then begin //strace('resetting------------------------------------- '); setLength(resetClkOUT,1); setValue(resetClkOUT,1); resetting := true; end; transpositions[midi.data1] := transpose; // Store transpose value used for NoteOn noteOns[midi.data1] := TRUE; midi.data1 := midi.data1 + transpose; END ELSE IF ( (midi.msg = 128) OR ((midi.msg = 144) AND (midi.data2 = 0))) THEN BEGIN // NoteOff if hands then makeHands; if (transCtl = 0) then begin // Retrieve stored transpose and add to NoteOff midi.data1 := midi.data1 + transpositions[midi.data1]; noteOns[midi.data1] := FALSE; end; END; //ELSE IF (midi.msg = 172) and (midi.data1 = 64) SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END; END; setLength(midiOUT, outCount); END ELSE BEGIN SetLength(midiOUT, 0); END; END; END;END;Statistics: Posted by woodslanding — 01 Nov 2017, 07:32
CODE:
/////////////////////////////////////////////////////////////////////////////// VST CH of 0 is causing error// Limit vst ch to 1 thru 16. Use INPUT CH = 0 to stop channelization of messages!/////////////////////////////////////////////////////////////////////////////const STATUS_ENABLED = 1;const STATUS_DISABLED = 0;const STATUS_NOTESOLOED = 2; //a note solo instrument will mute other instruments on its channel over its key rangeconst STATUS_COMPROMISED = 3;//when all or part of the noterange is muted by a notesolo inst on another trackVAR midiIN, midiOUT : Tparameter;// from NS var transposeIN: Tparameter;var lowNoteIN : Tparameter; var hiNoteIN : Tparameter;var chanIN : Tparameter;var statusOUT : Tparameter;var vstChIN : Tparameter;// from mixervar handsIN : Tparameter; var holdIN : Tparameter;var trackIN : Tparameter; var enabledIN : Tparameter; // from inst var transToCtlIN : Tparameter;var resetClkIN : Tparameter;var resetVelIN : Tparameter;//arraysvar nSolosIN : Tparameter; var noSusIN : Tparameter;var nsLowNotesIN : Tparameter;var nsHiNotesIN : Tparameter; var resetClkOUT : Tparameter; var clearIN : Tparameter; VAR transpositions : ARRAY OF integer;VAR noteONs : ARRAY OF boolean; VAR midi : tMidi; VAR midiCount, transpose,transCtl,i, trackCount, trackNum,status : integer;VAR newTranspose,hands,hold,resetClk,resetting: boolean; var lowNote,hiNote,nSoloLow,nSoloHi, inputCh, vstChan, vel, resetVel: integer; var nSolo, clearNotes, enabled,noSus: boolean;PROCEDURE Init; BEGIN//from NS midiIN := CreateParam('midi in', ptMidi); SetIsOutput(midiIN, FALSE); //0 = OMNI, 17 = Disable Midi note Processing (for normal fx) chanIN := CreateParam('midi chan', ptDatafield); SetIsOutput(chanIN, FALSE); lowNoteIN := CreateParam('low note', ptDataField); SetIsOutput(lowNoteIN, FALSE); hiNoteIN := CreateParam('hi note', ptDataField); SetIsOutput(hiNoteIN, FALSE);//from mixer transposeIN := CreateParam('transpose', ptDataField);SetIsOutput(transposeIN, FALSE); handsIN := CreateParam('hands on',ptSwitch); SetIsOutput(handsIN, false); holdIN := CreateParam('hold on',ptSwitch); SetIsOutput(holdIN, false); //from inst transToCtlIN := CreateParam('transToCtl',ptDatafield); SetIsOutput(transToCtlIN, false); //ns array is an array [1..trackcount] of midi channels. 0 means either the chan is disabled, or it is not a ns channel nSolosIN := CreateParam('nsSolo arr',ptArray); SetIsOutput(nSolosIN, false); nsLowNotesIN := CreateParam('ns low arr',ptArray); SetIsOutput(nsLowNotesIN, false); nsHiNotesIN := CreateParam('ns high arr',ptArray); SetIsOutput(nsHiNotesIN, false); // what ch the vst inst wants to see. If INPUT CH is 0 or 17, this doesn't matter! vstChIN := CreateParam('vst chan', ptDatafield); SetIsOutput(vstChIN, FALSE); clearIN := CreateParam('clear notes',ptSwitch); SetIsOutput(clearIN, false); resetClkIN := CreateParam('vel clock reset', ptDatafield); SetIsOutput(resetClkIN, FALSE); resetVelIN := CreateParam('reset vel thresh', ptDatafield); SetIsOutput(resetVelIN, FALSE); trackIN := CreateParam('track num', ptDatafield); SetIsOutput(trackIN, FALSE); enabledIN := CreateParam('enable', ptDatafield); SetIsOutput(enabledIN, FALSE); noSusIN := CreateParam('no sus', ptDatafield); SetIsOutput(noSusIN, FALSE); resetClkOUT := CreateParam('reset clock', ptDatafield); SetIsInput(resetClkOUT, FALSE); midiOUT := CreateParam('midi out', ptMidi); SetIsInput(midiOUT, FALSE); statusOUT := CreateParam('status', ptDatafield); SetIsInput(statusOUT, FALSE); SetArrayLength(transpositions, 128); SetArrayLength(noteONs, 128); for i := 0 to 127 DO BEGIN transpositions[i] := 0; noteOns[i] := FALSE; END; clearNotes := FALSE; newTranspose := FALSE; setLength(resetClkOUT,0); //strace('INIT FINISHED--MIDIINPUTPROC');END; // Initprocedure makeHands;var note : integer;begin hands := trunc(getValue(handsIN)); if hands then begin note := midi.data1; if note > 60 then midi.data1 := note - 12 else midi.data1 := note + 12; end; end;procedure setStatus;var compromised : boolean;BEGIN //status: 0-off; 1-on; 2-noteSolo; 3-muted by noteSolo; compromised := false; status := STATUS_ENABLED; //maybe these aren't always initialized???? vstChan := trunc(getValue(vstChIN)); inputCh := trunc(getValue(chanIN)); enabled := trunc(getValue(enabledIN); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); if not enabled THEN status := STATUS_DISABLED ELSE BEGIN //check our own status strace('CHECKING STATUS-----------------------------------------'); trackCount := getLength(nSolosIN); //figure key range based on NS nSolo := getDataArrayValue(nSolosIN,trackNum - 1) = inputCh; IF nSolo THEN BEGIN nSoloHI := trunc(getDataArrayValue(nsHiNotesIN, trackNum - 1)); nSoloLow := trunc(getDataArrayValue(nsLowNotesIN, trackNum - 1)); IF nSoloHI < hiNote THEN hiNote := nSoloHI; IF nSoloLow > lowNote THEN lowNote := nSoloLow; END ELSE BEGIN // reset the keyboard range... //strace('resetting keyboard range for channel ' + inttostr(trackNum)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); END; //No notesoloing for FX (ch 17) IF (inputCH = 17) THEN BEGIN IF enabled THEN status := STATUS_ENABLED ELSE status := STATUS_DISABLED; END //cannot be note solo in omni mode! ELSE IF (inputCH > 0) and nSolo THEN BEGIN //we are a note solo inst //strace('note solo ON for track number ' + intToStr(trackNum)); status := STATUS_NOTESOLOED; END ELSE BEGIN // compute status and nsInfo from arrays nSoloHI := 0; nSoloLow := 127 for i := 0 to trackCount - 1 do BEGIN if (inputCH > 0) and (getDataArrayValue(nSolosIN,i) = inputCH) then BEGIN //we are note solo compromised. //strace('note solo affecting track number ' + intToStr(trackNum)); compromised := true; if (getDataArrayValue(nsHiNotesIN,i) > nSoloHI) then nSoloHI := trunc(getDataArrayValue(nsHiNotesIN,i)); if (getDataArrayValue(nsLowNotesIN,i) < nSoloLow) then nSoloLow := trunc(getDataArrayValue(nsLowNotesIN,i)); END; END; //strace('notesoloLow = ' + intToStr(nSoloLow)); //strace('notesoloHi = ' + intToStr(nSoloHi)); if compromised then status := STATUS_COMPROMISED ELSE status := STATUS_ENABLED; END; END; setValue(statusOUT,status)END;procedure callback(n: integer);BEGIN strace('MIDIINPUTPROC CALLBACK: n = ' + inttostr(n)); BEGIN hold := trunc(getValue(holdIN)) = 1; //strace('hold setting clear notes if it is off'); //if we just turned of hold, clear notes IF NOT hold then clearNotes := TRUE; END IF (n = 0) THEN //ignore ELSE IF (n = transposeIN) THEN newTranspose := TRUE ELSE IF (n = trackIN) THEN trackNum := trunc(getValue(trackIN)) ELSE IF (n = transToCtlIN) THEN transCtl := trunc(getValue(transToCtlIN)) ELSE IF (n = resetClkIN) THEN resetClk := trunc(getValue(resetClkIN)) = 1 ELSE IF (n = resetVelIN) THEN resetVel := trunc(getValue(resetVelIN)) ELSE IF (n = noSusIN) THEN noSus := trunc(getValue(noSusIN)) > 0 ELSE IF (n = holdIN) THEN ELSE IF (n = enabledIN) THEN BEGIN enabled := trunc(getValue(enabledIN)) = 1; //strace('enabled setting clear notes if not enabled and not hold'); if NOT enabled and NOT hold then clearNotes := TRUE; setStatus; END //some other inst has changed, so we need to check status ELSE IF (n = nsHiNotesIN) OR (n= nsLowNotesIN) OR (n = nSolosIN) THEN setStatus ELSE IF (n = resetClkOUT) OR (n = midiOUT) OR (n = statusOUT) THEN //why,it's an output?????? ELSE BEGIN IF (n = handsIN) THEN hands := trunc(getValue(handsIN)) ELSE IF (n = vstChIN) THEN vstChan := trunc(getValue(vstChIN)) ELSE IF (n = lowNoteIN) THEN lowNote := trunc(getValue(lowNoteIN)) ELSE IF (n = hiNoteIN) THEN hiNote := trunc(getValue(hiNoteIN)) ELSE IF (n = chanIN) THEN inputCh := trunc(getValue(chanIN)); setStatus; clearNotes := TRUE; //strace('setting clearNotes to true via hands, outch, lownote hinote, or chan'); ENDEND; // processprocedure process;var outCount,note,chan: integer; var ccTrans,countOffset: integer;var newMidi: tMidi; var hasMidi: boolean;var minCH,maxCH,ch : integer; BEGIN //if input is 17[disabled], bypass midi processing entirely IF (inputCH = 17) THEN SetLength(midiOUT, 0) ELSE BEGIN //should filter all but notes, sustain and pb prev to script midiCount := GetLength(midiIN); hasMidi := midiCount > 0; outCount := 0; if resetting = true then begin resetting := false; //turn reset back off setValue(resetClkOUT, 0); //null event for off end IF clearNotes then BEGIN //strace('clearing notes'); //for omni sources, send noteoffs on every channel... //otherwise just send to the chan VST is receiving on IF (inputCh = 0) then BEGIN minCH := 1; maxCH := 16; END ELSE BEGIN minCH = vstChan; maxCH := vstChan; END; FOR ch := minCH to maxCH DO BEGIN for i := 0 to 127 DO BEGIN // send note off s if noteONs[i] := TRUE THEN BEGIN midi.channel := ch; midi.msg := 128; midi.data1 := i; midi.data2 := 0; setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; noteONs[i] := FALSE; END; END; // send sus pedal off! midi.channel := ch; midi.msg := 176; midi.data1 := 64; midi.data2 := 0; end setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; setLength(midiOUT, outCount); clearNotes := FALSE; //if we are clearing, we ignore other midi input for this cycle.... END ELSE BEGIN if newTranspose then begin //strace('in NEW TRANSPOSE'); IF (transCtl = 0) then transpose := round(getValue(transposeIN)) ELSE BEGIN transpose := 0; // create midi cc out for drum tuning (cc value is transCtl) ccTrans := (round((transpose * 1.76) + 64)); //strace('____________CC TRANS = ' + intToStr(ccTrans)); newMidi.msg := 176; newMidi.channel := 1; newMidi.data1 := transCtl; newMidi.data2 := round(ccTrans); SetMidiArrayValue(midiOUT, outCount, newMidi); outCount := outCount + 1; END; newTranspose := FALSE; end; // filter everything but notes for this script! //Hold keeps new notes from being triggered IF hasMidi and (hold = false) and enabled THEN BEGIN countOffset := outCount; FOR i := 0 TO (midiCount - 1) DO BEGIN GetMidiArrayValue(midiIN, i, midi); note := midi.data1; vel := midi.data2; chan := midi.channel; IF (inputCh > 0) then midi.channel := vstChan; //if midiCH is 0 leave unchanged IF (midi.msg = 224) OR ((midi.msg = 172) AND (noSus = false)) THEN BEGIN //strace('message = ' + inttoStr(midi.msg)); SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END //TODO: how does this work with PB and SUS on multi ch sources? ELSE IF (inputCH > 0) AND (chan <> inputCH) THEN //ignore notes from other channels. 0 is omni. ELSE IF (note < lowNote) or (note > hiNote) THEN //ignore notes outside range. True for any status. Includes NS limiting ELSE IF (status = 3) and (nSoloLow <= note) and (note <= nSoloHI) THEN //ignore note solo range on NS channel //strace('tracknum = ' + inttostr(trackNum) +', nsolo lo = ' + inttostr(nSoloLow) + ', nSoloHI = ' + inttostr(nSoloHi) + ',note = ' + intToStr(note)); ELSE BEGIN IF ((midi.msg = 144) AND (midi.data2 > 0)) THEN BEGIN // NoteOn if hands then makeHands; if resetClk and (vel > resetVel) then begin //strace('resetting------------------------------------- '); setLength(resetClkOUT,1); setValue(resetClkOUT,1); resetting := true; end; transpositions[midi.data1] := transpose; // Store transpose value used for NoteOn noteOns[midi.data1] := TRUE; midi.data1 := midi.data1 + transpose; END ELSE IF ( (midi.msg = 128) OR ((midi.msg = 144) AND (midi.data2 = 0))) THEN BEGIN // NoteOff if hands then makeHands; if (transCtl = 0) then begin // Retrieve stored transpose and add to NoteOff midi.data1 := midi.data1 + transpositions[midi.data1]; noteOns[midi.data1] := FALSE; end; END; //ELSE IF (midi.msg = 172) and (midi.data1 = 64) SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END; END; setLength(midiOUT, outCount); END ELSE BEGIN SetLength(midiOUT, 0); END; END; END;END;Statistics: Posted by woodslanding — 01 Nov 2017, 06:50
CODE:
/////////////////////////////////////////////////////////////////////////////// vstChIN parameter value of 0 is causing error// Error : E901 patch process : Process of MIDI In (rack: 3) patch: gui.pat //next patch down/////////////////////////////////////////////////////////////////////////////VAR midiIN, midiOUT : Tparameter;// from NS var transposeIN: Tparameter;var lowNoteIN : Tparameter; var hiNoteIN : Tparameter;var chanIN : Tparameter;var statusOUT : Tparameter;var vstChIN : Tparameter;// from mixervar handsIN : Tparameter; var holdIN : Tparameter;var trackIN : Tparameter; var enabledIN : Tparameter; // from inst var transToCtlIN : Tparameter;var resetClkIN : Tparameter;var resetVelIN : Tparameter;//arraysvar nSolosIN : Tparameter; var noSusIN : Tparameter;var nsLowNotesIN : Tparameter;var nsHiNotesIN : Tparameter; var resetClkOUT : Tparameter; var clearIN : Tparameter; VAR transpositions : ARRAY OF integer;VAR noteONs : ARRAY OF boolean;VAR midi : tMidi; VAR midiCount, transpose,transCtl,i, trackCount, trackNum,status : integer;VAR newTranspose,hands,hold,resetClk,resetting: boolean; var lowNote,hiNote,nSoloLow,nSoloHi, inputCh, vstChan, vel, resetVel: integer; var nSolo, clearNotes, enabled,noSus: boolean;PROCEDURE Init; BEGIN//from NS midiIN := CreateParam('midi in', ptMidi); SetIsOutput(midiIN, FALSE); chanIN := CreateParam('midi chan', ptDatafield); SetIsOutput(chanIN, FALSE); lowNoteIN := CreateParam('low note', ptDataField); SetIsOutput(lowNoteIN, FALSE); hiNoteIN := CreateParam('hi note', ptDataField); SetIsOutput(hiNoteIN, FALSE);//from mixer transposeIN := CreateParam('transpose', ptDataField);SetIsOutput(transposeIN, FALSE); handsIN := CreateParam('hands on',ptSwitch); SetIsOutput(handsIN, false); holdIN := CreateParam('hold on',ptSwitch); SetIsOutput(holdIN, false); //from inst transToCtlIN := CreateParam('transToCtl',ptDatafield); SetIsOutput(transToCtlIN, false); //ns array is an array [1..trackcount] of midi channels. 0 means either the chan is disabled, or it is not a ns channel nSolosIN := CreateParam('nsSolo arr',ptArray); SetIsOutput(nSolosIN, false); nsLowNotesIN := CreateParam('ns low arr',ptArray); SetIsOutput(nsLowNotesIN, false); nsHiNotesIN := CreateParam('ns high arr',ptArray); SetIsOutput(nsHiNotesIN, false); // what ch the inst wants. 0 for multichan... CAUSING ERROR!!!!! vstChIN := CreateParam('vst chan', ptDatafield); SetIsOutput(vstChIN, FALSE); clearIN := CreateParam('clear notes',ptSwitch); SetIsOutput(clearIN, false); resetClkIN := CreateParam('vel clock reset', ptDatafield); SetIsOutput(resetClkIN, FALSE); resetVelIN := CreateParam('reset vel thresh', ptDatafield); SetIsOutput(resetVelIN, FALSE); trackIN := CreateParam('track num', ptDatafield); SetIsOutput(trackIN, FALSE); enabledIN := CreateParam('enable', ptDatafield); SetIsOutput(enabledIN, FALSE); noSusIN := CreateParam('no sus', ptDatafield); SetIsOutput(noSusIN, FALSE); resetClkOUT := CreateParam('reset clock', ptDatafield); SetIsInput(resetClkOUT, FALSE); midiOUT := CreateParam('midi out', ptMidi); SetIsInput(midiOUT, FALSE); statusOUT := CreateParam('status', ptDatafield); SetIsInput(statusOUT, FALSE); SetArrayLength(transpositions, 128); SetArrayLength(noteONs, 128); for i := 0 to 127 DO BEGIN transpositions[i] := 0; noteOns[i] := FALSE; END; clearNotes := FALSE; newTranspose := FALSE; setLength(resetClkOUT,0);END; // Initprocedure makeHands;var note : integer;begin if hands then begin note := midi.data1; if note > 60 then midi.data1 := note - 12 else midi.data1 := note + 12; end; end;procedure setStatus;var compromised : boolean;BEGIN compromised := false; if not enabled THEN status := 0 ELSE BEGIN //check our own status trackCount := getLength(nSolosIN); //figure key range based on NS nSolo := getDataArrayValue(nSolosIN,trackNum - 1) = inputCh; IF nSolo THEN BEGIN nSoloHI := trunc(getDataArrayValue(nsHiNotesIN, trackNum - 1)); nSoloLow := trunc(getDataArrayValue(nsLowNotesIN, trackNum - 1)); IF nSoloHI < hiNote THEN hiNote := nSoloHI; IF nSoloLow > lowNote THEN lowNote := nSoloLow; END ELSE BEGIN // reset the keyboard range... //strace('resetting keyboard range for channel ' + inttostr(trackNum)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); END; //No notesoloing for FX (ch 17) IF (inputCH = 17) THEN BEGIN IF enabled THEN status := 1 ELSE status := 0; END //cannot be note solo in omni mode! ELSE IF (inputCH > 0) and nSolo THEN BEGIN //we are a note solo inst //strace('note solo ON for track number ' + intToStr(trackNum)); status := 2; END ELSE BEGIN // compute status and nsInfo from arrays nSoloHI := 0; nSoloLow := 127 for i := 0 to trackCount - 1 do BEGIN if (inputCH > 0) and (getDataArrayValue(nSolosIN,i) = inputCH) then BEGIN //we are note solo compromised. //strace('note solo affecting track number ' + intToStr(trackNum)); compromised := true; if (getDataArrayValue(nsHiNotesIN,i) > nSoloHI) then nSoloHI := trunc(getDataArrayValue(nsHiNotesIN,i)); if (getDataArrayValue(nsLowNotesIN,i) < nSoloLow) then nSoloLow := trunc(getDataArrayValue(nsLowNotesIN,i)); END; END; //strace('notesoloLow = ' + intToStr(nSoloLow)); //strace('notesoloHi = ' + intToStr(nSoloHi)); if compromised then status := 3 ELSE status := 1; END; END; setValue(statusOUT,status)END;procedure callback(n: integer);BEGIN //strace('n = ' + inttostr(n)); IF (n = 0) THEN //ignore ELSE IF (n = transposeIN) THEN newTranspose := TRUE ELSE IF (n = trackIN) THEN trackNum := trunc(getValue(trackIN)) ELSE IF (n = transToCtlIN) THEN transCtl := trunc(getValue(transToCtlIN)) ELSE IF (n = resetClkIN) THEN resetClk := trunc(getValue(resetClkIN)) = 1 ELSE IF (n = resetVelIN) THEN resetVel := trunc(getValue(resetVelIN)) ELSE IF (n = noSusIN) THEN noSus := trunc(getValue(noSusIN)) > 0 ELSE IF (n = holdIN) THEN BEGIN hold := trunc(getValue(holdIN)) = 1; //strace('hold setting clear notes if it is off'); //if we just turned of hold, clear notes IF NOT hold then clearNotes := TRUE; END ELSE IF (n = enabledIN) THEN BEGIN enabled := trunc(getValue(enabledIN)) = 1; //strace('enabled setting clear notes if not enabled and not hold'); if NOT enabled and NOT hold then clearNotes := TRUE; setStatus; END //some other inst has changed, so we need to check status ELSE IF (n = nsHiNotesIN) OR (n= nsLowNotesIN) OR (n = nSolosIN) THEN setStatus ELSE IF (n = resetClkOUT) OR (n = midiOUT) OR (n = statusOUT) THEN //why,it's an output?????? ELSE BEGIN IF (n = handsIN) THEN hands := trunc(getValue(handsIN)) ELSE IF (n = vstChIN) THEN vstChan := trunc(getValue(vstChIN)) ELSE IF (n = lowNoteIN) THEN lowNote := trunc(getValue(lowNoteIN)) ELSE IF (n = hiNoteIN) THEN hiNote := trunc(getValue(hiNoteIN)) ELSE IF (n = chanIN) THEN inputCh := trunc(getValue(chanIN)); setStatus; clearNotes := TRUE; //strace('setting clearNotes to true via hands, outch, lownote hinote, or chan'); ENDEND; // processprocedure process;var outCount,note,chan: integer; var ccTrans,countOffset: integer;var newMidi: tMidi; var hasMidi: boolean;var minCH,maxCH,ch : integer; BEGIN IF (vstChan = 17) THEN SetLength(midiOUT, 0) // no midi processing at all ELSE BEGIN //should filter all but notes, sustain and pb prev to script midiCount := GetLength(midiIN); hasMidi := midiCount > 0; outCount := 0; if resetting = true then begin resetting := false; //turn reset back off setValue(resetClkOUT, 0); //null event for off end IF clearNotes and (vstChan < 17) then BEGIN //strace('clearing notes'); //for omni sources, send noteoffs on every channel... IF vstChan = 0 then BEGIN minCH := 1; maxCH := 16; END ELSE BEGIN minCH = vstChan; maxCH := vstChan; END; FOR ch := minCH to maxCH DO BEGIN for i := 0 to 127 DO BEGIN // send note off s if noteONs[i] := TRUE THEN BEGIN midi.channel := ch; midi.msg := 128; midi.data1 := i; midi.data2 := 0; setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; noteONs[i] := FALSE; END; END; // send sus pedal off! midi.channel := ch; midi.msg := 176; midi.data1 := 64; midi.data2 := 0; end setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; setLength(midiOUT, outCount); clearNotes := FALSE; //if we are clearing, we ignore other midi input for this cycle.... END ELSE BEGIN if newTranspose and (vstChan < 17) then begin strace('in NEW TRANSPOSE'); IF (transCtl = 0) then transpose := round(getValue(transposeIN)) ELSE BEGIN transpose := 0; // create midi cc out for drum tuning (cc value is transCtl) ccTrans := (round((transpose * 1.76) + 64)); //strace('____________CC TRANS = ' + intToStr(ccTrans)); newMidi.msg := 176; newMidi.channel := 1; newMidi.data1 := transCtl; newMidi.data2 := round(ccTrans); SetMidiArrayValue(midiOUT, outCount, newMidi); outCount := outCount + 1; END; newTranspose := FALSE; end; // filter everything but notes for this script! //Hold keeps new notes from being triggered IF hasMidi and (hold = false) and enabled and (vstChan < 17) THEN BEGIN countOffset := outCount; FOR i := 0 TO (midiCount - 1) DO BEGIN GetMidiArrayValue(midiIN, i, midi); note := midi.data1; vel := midi.data2; chan := midi.channel; IF (inputCh > 0) then midi.channel := vstChan; //if midiCH is 0 leave unchanged IF (midi.msg = 224) OR ((midi.msg = 172) AND (noSus = false)) THEN BEGIN //strace('message = ' + inttoStr(midi.msg)); SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END //TODO: how does this work with PB and SUS on multi ch sources? ELSE IF (inputCH > 0) AND (chan <> inputCH) THEN //ignore notes from other channels. 0 is omni. ELSE IF (note < lowNote) or (note > hiNote) THEN //ignore notes outside range. True for any status. Includes NS limiting ELSE IF (status = 3) and (nSoloLow <= note) and (note <= nSoloHI) THEN //ignore note solo range on NS channel //strace('tracknum = ' + inttostr(trackNum) +', nsolo lo = ' + inttostr(nSoloLow) + ', nSoloHI = ' + inttostr(nSoloHi) + ',note = ' + intToStr(note)); ELSE BEGIN IF ((midi.msg = 144) AND (midi.data2 > 0)) THEN BEGIN // NoteOn if hands then makeHands; if resetClk and (vel > resetVel) then begin //strace('resetting------------------------------------- '); setLength(resetClkOUT,1); setValue(resetClkOUT,1); resetting := true; end; transpositions[midi.data1] := transpose; // Store transpose value used for NoteOn noteOns[midi.data1] := TRUE; midi.data1 := midi.data1 + transpose; END ELSE IF ( (midi.msg = 128) OR ((midi.msg = 144) AND (midi.data2 = 0))) THEN BEGIN // NoteOff if hands then makeHands; if (transCtl = 0) then begin midi.data1 := midi.data1 + transpositions[midi.data1]; // Retrieve stored transpose and add to NoteOff noteOns[midi.data1] := FALSE; end; END; //ELSE IF (midi.msg = 172) and (midi.data1 = 64) SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END; END; setLength(midiOUT, outCount); END ELSE BEGIN SetLength(midiOUT, 0); END; END; END;END;Statistics: Posted by woodslanding — 31 Oct 2017, 16:52
Statistics: Posted by woodslanding — 03 Nov 2017, 06:38
CODE:
NOTE OFF 90 0 c:16 NOTE OFF 91 0 c:16 NOTE OFF 92 0 c:16 NOTE OFF 93 0 c:16 NOTE OFF 94 0 c:16 NOTE OFF 95 0 c:16 NOTE OFF 96 0 c:16 NOTE OFF 97 0 c:16 NOTE OFF 98 0 c:16 NOTE OFF 99 0 c:16 NOTE OFF 100 0 c:16 NOTE OFF 101 0 c:16 NOTE OFF 102 0 c:16 NOTE OFF 103 0 c:16 NOTE OFF 104 0 c:16 NOTE OFF 105 0 c:16 NOTE OFF 106 0 c:16 NOTE OFF 107 0 c:16 NOTE OFF 108 0 c:16 NOTE OFF 109 0 c:16 NOTE OFF 110 0 c:16 NOTE OFF 111 0 c:16 NOTE OFF 112 0 c:16 NOTE OFF 113 0 c:16 NOTE OFF 114 0 c:16 NOTE OFF 115 0 c:16 NOTE OFF 116 0 c:16 NOTE OFF 117 0 c:16 NOTE OFF 118 0 c:16 NOTE OFF 119 0 c:16 NOTE OFF 120 0 c:16 NOTE OFF 121 0 c:16 NOTE OFF 122 0 c:16 NOTE OFF 123 0 c:16 NOTE OFF 124 0 c:16 NOTE OFF 125 0 c:16 NOTE OFF 126 0 c:16 NOTE OFF 127 0 c:16 CTRL CHANGE 64 0 c:16Error : E901 patch process : Process of MIDI In (rack: 3) patch: gui.patCODE:
/////////////////////////////////////////////////////////////////////////////// MIDI_OMNI value is causing error--// Error : E901 patch process : Process of MIDI In (following rack patch)// /////////////////////////////////////////////////////////////////////////////const MIDI_OMNI = 0;const MIDI_OFF = 17;const CH_ENABLED = 1;const CH_DISABLED = 0;const CH_NOTESOLOED = 2; //a note solo instrument will mute other instruments on its channel over its key rangeconst CH_COMPROMISED = 3;//when all or part of the noterange is muted by a notesolo inst on another trackVAR midiIN, midiOUT : Tparameter;// from NS var transposeIN: Tparameter;var lowNoteIN : Tparameter; var hiNoteIN : Tparameter;var chanIN : Tparameter;var statusOUT : Tparameter;var vstChIN : Tparameter;// from mixervar handsIN : Tparameter; var holdIN : Tparameter;var trackIN : Tparameter; var enabledIN : Tparameter; // from inst var transToCtlIN : Tparameter;var resetClkIN : Tparameter;var resetVelIN : Tparameter;//arraysvar nSolosIN : Tparameter; var noSusIN : Tparameter;var nsLowNotesIN : Tparameter;var nsHiNotesIN : Tparameter; var resetClkOUT : Tparameter; var clearIN : Tparameter; VAR transpositions : ARRAY OF integer;VAR noteONs : ARRAY OF boolean; VAR midi : tMidi; VAR outCount, transpose,transCtl, trackCount, trackNum,status : integer;VAR newTranspose,hands,hold,resetClk,resetting: boolean; var lowNote,hiNote,nSoloLow,nSoloHi, inputCh, vstChan, resetVel: integer; var nSolo, clearNotes, enabled,noSus,statusChanged: boolean;PROCEDURE Init;var i : integer; BEGIN //from NS midiIN := CreateParam('midi in', ptMidi); SetIsOutput(midiIN, FALSE); //18 = OMNI, 17 = Disable Midi note Processing (for normal fx) chanIN := CreateParam('midi chan', ptDatafield); SetIsOutput(chanIN, FALSE); lowNoteIN := CreateParam('low note', ptDataField); SetIsOutput(lowNoteIN, FALSE); hiNoteIN := CreateParam('hi note', ptDataField); SetIsOutput(hiNoteIN, FALSE);//from mixer transposeIN := CreateParam('transpose', ptDataField);SetIsOutput(transposeIN, FALSE); handsIN := CreateParam('hands on',ptSwitch); SetIsOutput(handsIN, false); holdIN := CreateParam('hold on',ptSwitch); SetIsOutput(holdIN, false); //from inst transToCtlIN := CreateParam('transToCtl',ptDatafield); SetIsOutput(transToCtlIN, false); //ns array is an array [1..trackcount] of midi channels. 0 means either the chan is disabled, or it is not a ns channel nSolosIN := CreateParam('nsSolo arr',ptArray); SetIsOutput(nSolosIN, false); nsLowNotesIN := CreateParam('ns low arr',ptArray); SetIsOutput(nsLowNotesIN, false); nsHiNotesIN := CreateParam('ns high arr',ptArray); SetIsOutput(nsHiNotesIN, false); // what ch the vst inst wants to see. If INPUT CH is OMNI or OFF, this doesn't matter vstChIN := CreateParam('vst chan', ptDatafield); SetIsOutput(vstChIN, FALSE); clearIN := CreateParam('clear notes',ptSwitch); SetIsOutput(clearIN, false); resetClkIN := CreateParam('vel clock reset', ptDatafield); SetIsOutput(resetClkIN, FALSE); resetVelIN := CreateParam('reset vel thresh', ptDatafield); SetIsOutput(resetVelIN, FALSE); trackIN := CreateParam('track num', ptDatafield); SetIsOutput(trackIN, FALSE); enabledIN := CreateParam('enable', ptDatafield); SetIsOutput(enabledIN, FALSE); noSusIN := CreateParam('no sus', ptDatafield); SetIsOutput(noSusIN, FALSE); resetClkOUT := CreateParam('reset clock', ptDatafield); SetIsInput(resetClkOUT, FALSE); midiOUT := CreateParam('midi out', ptMidi); SetIsInput(midiOUT, FALSE); statusOUT := CreateParam('status', ptDatafield); SetIsInput(statusOUT, FALSE); SetArrayLength(transpositions, 128); SetArrayLength(noteONs, 128); for i := 0 to 127 DO BEGIN transpositions[i] := 0; noteOns[i] := FALSE; END; clearNotes := FALSE; newTranspose := FALSE; statusChanged := FALSE; setLength(resetClkOUT,0); strace('INIT FINISHED--MIDIINPUTPROC');END; // Initprocedure makeHands;var note : integer; begin hands := trunc(getValue(handsIN)); if hands then begin note := midi.data1; if note > 60 then midi.data1 := note - 12 else midi.data1 := note + 12; end; end;procedure callback(n: integer);BEGIN //strace('MIDIINPUTPROC CALLBACK: n = ' + inttostr(n)); IF (n = 0) THEN //ignore ELSE IF (n = transposeIN) THEN newTranspose := TRUE ELSE IF (n = trackIN) THEN trackNum := trunc(getValue(trackIN)) ELSE IF (n = transToCtlIN) THEN transCtl := trunc(getValue(transToCtlIN)) ELSE IF (n = resetClkIN) THEN resetClk := trunc(getValue(resetClkIN)) = 1 ELSE IF (n = resetVelIN) THEN resetVel := trunc(getValue(resetVelIN)) ELSE IF (n = noSusIN) THEN noSus := (trunc(getValue(noSusIN)) > 0) ELSE IF (n = holdIN) THEN BEGIN hold := (trunc(getValue(holdIN)) = 1); //strace('hold setting clear notes if it is off'); //if we just turned off hold, clear notes IF NOT hold then clearNotes := TRUE; END ELSE IF (n = enabledIN) THEN BEGIN hold := (trunc(getValue(holdIN)) = 1); enabled := trunc(getValue(enabledIN)) = 1; //strace('enabled setting clear notes if not enabled and not hold'); if NOT enabled and NOT hold then clearNotes := TRUE; statusChanged := true; END //some other inst has changed, so we need to check status ELSE IF (n = nsHiNotesIN) OR (n= nsLowNotesIN) OR (n = nSolosIN) THEN statusChanged := true ELSE IF (n = resetClkOUT) OR (n = midiOUT) OR (n = statusOUT) THEN //why,it's an output?????? ELSE BEGIN IF (n = handsIN) THEN hands := trunc(getValue(handsIN)) ELSE IF (n = vstChIN) THEN vstChan := trunc(getValue(vstChIN)) ELSE IF (n = lowNoteIN) THEN lowNote := trunc(getValue(lowNoteIN)) ELSE IF (n = hiNoteIN) THEN hiNote := trunc(getValue(hiNoteIN)) ELSE IF (n = chanIN) THEN inputCh := trunc(getValue(chanIN)); statusChanged := true; clearNotes := TRUE; //strace('setting clearNotes to true via hands, outch, lownote hinote, or chan'); END; END; procedure processIdle;var compromised : boolean;var i : integer;BEGIN if (statusChanged) then BEGIN //maybe we can stop short notes when ch is re-enabled.... clearNotes := TRUE; compromised := false; status := CH_ENABLED; //maybe these aren't always initialized???? vstChan := trunc(getValue(vstChIN)); inputCh := trunc(getValue(chanIN)); enabled := trunc(getValue(enabledIN)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); trackNum := trunc(getValue(trackIN)); if not enabled THEN status := CH_DISABLED ELSE BEGIN //check our own status //strace('CHECKING STATUS-----------------------------------------'); trackCount := getLength(nSolosIN); //figure key range based on NS nSolo := (getDataArrayValue(nSolosIN,trackNum - 1) = inputCh); IF nSolo THEN BEGIN nSoloHI := trunc(getDataArrayValue(nsHiNotesIN, trackNum - 1)); nSoloLow := trunc(getDataArrayValue(nsLowNotesIN, trackNum - 1)); IF nSoloHI < hiNote THEN hiNote := nSoloHI; IF nSoloLow > lowNote THEN lowNote := nSoloLow; END ELSE BEGIN // reset the keyboard range... //strace('resetting keyboard range for channel ' + inttostr(trackNum)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); END; //No notesoloing for FX (ch 17) IF (inputCH = MIDI_OFF) THEN BEGIN IF enabled THEN status := CH_ENABLED ELSE status := CH_DISABLED; END //cannot be note solo in omni mode! ELSE IF (inputCH <> MIDI_OMNI) and nSolo THEN BEGIN //we are a note solo inst //strace('note solo ON for track number ' + intToStr(trackNum)); status := CH_NOTESOLOED; END ELSE BEGIN // compute status and nsInfo from arrays nSoloHI := 0; nSoloLow := 127 for i := 0 to trackCount - 1 do BEGIN if (inputCH <> MIDI_OMNI) and (getDataArrayValue(nSolosIN,i) = inputCH) then BEGIN //we are note solo compromised. //strace('note solo affecting track number ' + intToStr(trackNum)); compromised := true; if (getDataArrayValue(nsHiNotesIN,i) > nSoloHI) then nSoloHI := trunc(getDataArrayValue(nsHiNotesIN,i)); if (getDataArrayValue(nsLowNotesIN,i) < nSoloLow) then nSoloLow := trunc(getDataArrayValue(nsLowNotesIN,i)); END; END; //strace('notesoloLow = ' + intToStr(nSoloLow)); //strace('notesoloHi = ' + intToStr(nSoloHi)); if compromised then status := CH_COMPROMISED ELSE status := CH_ENABLED; END; END; //strace('Status Set------------------------'); setValue(statusOUT,status); END; statusChanged := false;END; procedure writeToMidiArray;begin SetMidiArrayValue(midiOUT, outcount, midi); strace('added midi message num ' + inttostr(outCount)); outCount := outCount + 1; end;procedure sendNoteOffs(); var minCH,maxCH,ch,i : integer;BEGIN //strace('clearing notes'); //for omni sources, send noteoffs on every channel... //otherwise just send to the chan VST is receiving on //strace('vst channel = ' + inttostr(vstChan)); IF (inputCh = MIDI_OMNI) then BEGIN minCH := 1; maxCH := 16; //strace('minCH' = ' + inttostr(minCH)); END ELSE BEGIN minCH = vstChan; maxCH := vstChan; END; //strace('minCH = ' + inttostr(minCH)); if (minCH = 0) then minCH := 1; //avoid 0 value if ch num hasn't been sent yet FOR ch := minCH to maxCH DO BEGIN //strace('in note off subroutine, ch = ' + inttostr(ch)); for i := 0 to 127 DO BEGIN // send note off s if noteONs[i] := TRUE THEN BEGIN midi.channel := ch; midi.msg := 128; midi.data1 := i; midi.data2 := 0; strace('note off for ' + inttostr(i)); writeToMidiArray; noteONs[i] := FALSE; END; END; // send sus pedal off! midi.channel := ch; midi.msg := 176; midi.data1 := 64; midi.data2 := 0; writeToMidiArray; end; clearNotes := FALSE; //(strace('finished with note offs'));end; procedure processMIDI;var vel,note,chan,midiCount,i: integer;BEGIN midiCount := GetLength(midiIN); FOR i := 0 TO (midiCount - 1) DO BEGIN GetMidiArrayValue(midiIN, i, midi); note := midi.data1; vel := midi.data2; chan := midi.channel; IF (inputCh <> MIDI_OMNI) then midi.channel := vstChan; //if midiCH is 0 leave unchanged //pass PB and sus ped messages (if enabled) through... IF (midi.msg = 224) OR ((midi.msg = 172) AND (noSus = false)) THEN BEGIN //strace('message = ' + inttoStr(midi.msg)); writeToMidiArray; END //TODO: how does this work with PB and SUS on multi ch sources? //ignore midi data from other channels. ELSE IF (inputCH <> MIDI_OMNI) AND (chan <> inputCH) THEN ELSE IF (note < lowNote) or (note > hiNote) THEN //ignore notes outside range. True for any status. Includes NS limiting //ignore note solo range on NS channel ELSE IF (status = CH_COMPROMISED) and (nSoloLow <= note) and (note <= nSoloHI) THEN //strace('tracknum = ' + inttostr(trackNum) +', nsolo lo = ' + inttostr(nSoloLow) + ', nSoloHI = ' + inttostr(nSoloHi) + ',note = ' + intToStr(note)); ELSE //process these notes BEGIN IF ((midi.msg = 144) AND (midi.data2 > 0)) THEN BEGIN // NoteOn if hands then makeHands; if resetClk and (vel > resetVel) then begin //strace('resetting------------------------------------- '); setLength(resetClkOUT,1); setValue(resetClkOUT,1); resetting := true; end; if (transCtl = 0) then begin transpositions[midi.data1] := transpose; // Store transpose value used for NoteOn noteOns[midi.data1] := TRUE; midi.data1 := midi.data1 + transpose; end; END ELSE IF ( (midi.msg = 128) OR ((midi.msg = 144) AND (midi.data2 = 0))) THEN BEGIN // NoteOff if hands then makeHands; if (transCtl = 0) then //??? what is this?? why not on NoteOns??? begin // Retrieve stored transpose and add to NoteOff midi.data1 := midi.data1 + transpositions[midi.data1]; noteOns[midi.data1] := FALSE; end; END; //ELSE IF (midi.msg = 172) and (midi.data1 = 64) writeToMidiArray; END; END;END // processprocedure process; var ccTrans: integer;var hasMidi: boolean;var minCH,maxCH,ch,i : integer; BEGIN outCount := 0; inputCh := trunc(getValue(chanIN)); if resetting = true then begin resetting := false; //turn reset back off setValue(resetClkOUT, 0); //null event for off end hasMidi := (GetLength(midiIN) > 0); vstChan := trunc(getValue(vstChIN)); // filter everything but notes, PB and sus for this script! //Hold keeps new notes from being triggered IF hasMidi and (hold = false) and enabled THEN processMIDI; IF clearNotes then sendNoteOffs; IF newTranspose then begin //strace('in NEW TRANSPOSE'); IF (transCtl = 0) then transpose := round(getValue(transposeIN)) ELSE BEGIN transpose := 0; // create midi cc out for drum tuning (cc value is transCtl) ccTrans := (round((transpose * 1.76) + 64)); //strace('____________CC TRANS = ' + intToStr(ccTrans)); midi.msg := 176; midi.channel := 1; midi.data1 := transCtl; midi.data2 := round(ccTrans); writeToMidiArray; END; newTranspose := FALSE; END; SetLength(midiOUT,outCount); //ELSE SetLength(midiOUT, 0) // outCount should just be 0 when appropriate END;Statistics: Posted by woodslanding — 03 Nov 2017, 02:42
Statistics: Posted by woodslanding — 01 Nov 2017, 22:55
Statistics: Posted by sephult — 01 Nov 2017, 16:14
CODE:
/////////////////////////////////////////////////////////////////////////////// VST CH of 0 is causing error// Limit vst ch to 1 thru 16. Use INPUT CH = 0 to stop channelization of messages!/////////////////////////////////////////////////////////////////////////////const STATUS_ENABLED = 1;const STATUS_DISABLED = 0;const STATUS_NOTESOLOED = 2; //a note solo instrument will mute other instruments on its channel over its key rangeconst STATUS_COMPROMISED = 3;//when all or part of the noterange is muted by a notesolo inst on another trackVAR midiIN, midiOUT : Tparameter;// from NS var transposeIN: Tparameter;var lowNoteIN : Tparameter; var hiNoteIN : Tparameter;var chanIN : Tparameter;var statusOUT : Tparameter;var vstChIN : Tparameter;// from mixervar handsIN : Tparameter; var holdIN : Tparameter;var trackIN : Tparameter; var enabledIN : Tparameter; // from inst var transToCtlIN : Tparameter;var resetClkIN : Tparameter;var resetVelIN : Tparameter;//arraysvar nSolosIN : Tparameter; var noSusIN : Tparameter;var nsLowNotesIN : Tparameter;var nsHiNotesIN : Tparameter; var resetClkOUT : Tparameter; var clearIN : Tparameter; VAR transpositions : ARRAY OF integer;VAR noteONs : ARRAY OF boolean; VAR midi : tMidi; VAR midiCount, transpose,transCtl, trackCount, trackNum,status : integer;VAR newTranspose,hands,hold,resetClk,resetting: boolean; var lowNote,hiNote,nSoloLow,nSoloHi, inputCh, vstChan, vel, resetVel: integer; var nSolo, clearNotes, enabled,noSus,statusChanged: boolean;PROCEDURE Init;var i : integer; BEGIN //from NS midiIN := CreateParam('midi in', ptMidi); SetIsOutput(midiIN, FALSE); //0 = OMNI, 17 = Disable Midi note Processing (for normal fx) chanIN := CreateParam('midi chan', ptDatafield); SetIsOutput(chanIN, FALSE); lowNoteIN := CreateParam('low note', ptDataField); SetIsOutput(lowNoteIN, FALSE); hiNoteIN := CreateParam('hi note', ptDataField); SetIsOutput(hiNoteIN, FALSE);//from mixer transposeIN := CreateParam('transpose', ptDataField);SetIsOutput(transposeIN, FALSE); handsIN := CreateParam('hands on',ptSwitch); SetIsOutput(handsIN, false); holdIN := CreateParam('hold on',ptSwitch); SetIsOutput(holdIN, false); //from inst transToCtlIN := CreateParam('transToCtl',ptDatafield); SetIsOutput(transToCtlIN, false); //ns array is an array [1..trackcount] of midi channels. 0 means either the chan is disabled, or it is not a ns channel nSolosIN := CreateParam('nsSolo arr',ptArray); SetIsOutput(nSolosIN, false); nsLowNotesIN := CreateParam('ns low arr',ptArray); SetIsOutput(nsLowNotesIN, false); nsHiNotesIN := CreateParam('ns high arr',ptArray); SetIsOutput(nsHiNotesIN, false); // what ch the vst inst wants to see. If INPUT CH is 0 or 17, this doesn't matter! vstChIN := CreateParam('vst chan', ptDatafield); SetIsOutput(vstChIN, FALSE); clearIN := CreateParam('clear notes',ptSwitch); SetIsOutput(clearIN, false); resetClkIN := CreateParam('vel clock reset', ptDatafield); SetIsOutput(resetClkIN, FALSE); resetVelIN := CreateParam('reset vel thresh', ptDatafield); SetIsOutput(resetVelIN, FALSE); trackIN := CreateParam('track num', ptDatafield); SetIsOutput(trackIN, FALSE); enabledIN := CreateParam('enable', ptDatafield); SetIsOutput(enabledIN, FALSE); noSusIN := CreateParam('no sus', ptDatafield); SetIsOutput(noSusIN, FALSE); resetClkOUT := CreateParam('reset clock', ptDatafield); SetIsInput(resetClkOUT, FALSE); midiOUT := CreateParam('midi out', ptMidi); SetIsInput(midiOUT, FALSE); statusOUT := CreateParam('status', ptDatafield); SetIsInput(statusOUT, FALSE); SetArrayLength(transpositions, 128); SetArrayLength(noteONs, 128); for i := 0 to 127 DO BEGIN transpositions[i] := 0; noteOns[i] := FALSE; END; clearNotes := FALSE; newTranspose := FALSE; statusChanged := FALSE; setLength(resetClkOUT,0); //strace('INIT FINISHED--MIDIINPUTPROC');END; // Initprocedure makeHands;var note : integer;begin hands := trunc(getValue(handsIN)); if hands then begin note := midi.data1; if note > 60 then midi.data1 := note - 12 else midi.data1 := note + 12; end; end;procedure callback(n: integer);BEGIN strace('MIDIINPUTPROC CALLBACK: n = ' + inttostr(n)); IF (n = 0) THEN //ignore ELSE IF (n = transposeIN) THEN newTranspose := TRUE ELSE IF (n = trackIN) THEN trackNum := trunc(getValue(trackIN)) ELSE IF (n = transToCtlIN) THEN transCtl := trunc(getValue(transToCtlIN)) ELSE IF (n = resetClkIN) THEN resetClk := trunc(getValue(resetClkIN)) = 1 ELSE IF (n = resetVelIN) THEN resetVel := trunc(getValue(resetVelIN)) ELSE IF (n = noSusIN) THEN noSus := trunc(getValue(noSusIN)) > 0 ELSE IF (n = holdIN) THEN BEGIN hold := trunc(getValue(holdIN)) = 1; //strace('hold setting clear notes if it is off'); //if we just turned off hold, clear notes IF NOT hold then clearNotes := TRUE; END ELSE IF (n = enabledIN) THEN BEGIN enabled := trunc(getValue(enabledIN)) = 1; //strace('enabled setting clear notes if not enabled and not hold'); if NOT enabled and NOT hold then clearNotes := TRUE; statusChanged := true; END //some other inst has changed, so we need to check status ELSE IF (n = nsHiNotesIN) OR (n= nsLowNotesIN) OR (n = nSolosIN) THEN statusChanged := true ELSE IF (n = resetClkOUT) OR (n = midiOUT) OR (n = statusOUT) THEN //why,it's an output?????? ELSE BEGIN IF (n = handsIN) THEN hands := trunc(getValue(handsIN)) ELSE IF (n = vstChIN) THEN vstChan := trunc(getValue(vstChIN)) ELSE IF (n = lowNoteIN) THEN lowNote := trunc(getValue(lowNoteIN)) ELSE IF (n = hiNoteIN) THEN hiNote := trunc(getValue(hiNoteIN)) ELSE IF (n = chanIN) THEN inputCh := trunc(getValue(chanIN)); statusChanged := true; clearNotes := TRUE; //strace('setting clearNotes to true via hands, outch, lownote hinote, or chan'); END;END; procedure processIdle;var compromised : boolean;var i : integer;BEGIN if (statusChanged) then BEGIN compromised := false; status := STATUS_ENABLED; //maybe these aren't always initialized???? vstChan := trunc(getValue(vstChIN)); inputCh := trunc(getValue(chanIN)); enabled := trunc(getValue(enabledIN)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); trackNum := trunc(getValue(trackIN)); if not enabled THEN status := STATUS_DISABLED ELSE BEGIN //check our own status strace('CHECKING STATUS-----------------------------------------'); trackCount := getLength(nSolosIN); //figure key range based on NS nSolo := getDataArrayValue(nSolosIN,trackNum - 1) = inputCh; IF nSolo THEN BEGIN nSoloHI := trunc(getDataArrayValue(nsHiNotesIN, trackNum - 1)); nSoloLow := trunc(getDataArrayValue(nsLowNotesIN, trackNum - 1)); IF nSoloHI < hiNote THEN hiNote := nSoloHI; IF nSoloLow > lowNote THEN lowNote := nSoloLow; END ELSE BEGIN // reset the keyboard range... //strace('resetting keyboard range for channel ' + inttostr(trackNum)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); END; //No notesoloing for FX (ch 17) IF (inputCH = 17) THEN BEGIN IF enabled THEN status := STATUS_ENABLED ELSE status := STATUS_DISABLED; END //cannot be note solo in omni mode! ELSE IF (inputCH > 0) and nSolo THEN BEGIN //we are a note solo inst //strace('note solo ON for track number ' + intToStr(trackNum)); status := STATUS_NOTESOLOED; END ELSE BEGIN // compute status and nsInfo from arrays nSoloHI := 0; nSoloLow := 127 for i := 0 to trackCount - 1 do BEGIN if (inputCH > 0) and (getDataArrayValue(nSolosIN,i) = inputCH) then BEGIN //we are note solo compromised. strace('note solo affecting track number ' + intToStr(trackNum)); compromised := true; if (getDataArrayValue(nsHiNotesIN,i) > nSoloHI) then nSoloHI := trunc(getDataArrayValue(nsHiNotesIN,i)); if (getDataArrayValue(nsLowNotesIN,i) < nSoloLow) then nSoloLow := trunc(getDataArrayValue(nsLowNotesIN,i)); END; END; strace('notesoloLow = ' + intToStr(nSoloLow)); strace('notesoloHi = ' + intToStr(nSoloHi)); if compromised then status := STATUS_COMPROMISED ELSE status := STATUS_ENABLED; END; END; strace('MADE IT THIS FAR------------------------'); setValue(statusOUT,status) END; statusChanged := false;END; // processprocedure process;var outCount,note,chan: integer; var ccTrans,countOffset: integer;var newMidi: tMidi; var hasMidi: boolean;var minCH,maxCH,ch,i : integer; BEGIN //if input is 17[disabled], bypass midi processing entirely IF (inputCH = 17) THEN SetLength(midiOUT, 0) ELSE BEGIN //should filter all but notes, sustain and pb prev to script midiCount := GetLength(midiIN); hasMidi := midiCount > 0; outCount := 0; if resetting = true then begin resetting := false; //turn reset back off setValue(resetClkOUT, 0); //null event for off end IF clearNotes then BEGIN //strace('clearing notes'); //for omni sources, send noteoffs on every channel... //otherwise just send to the chan VST is receiving on IF (inputCh = 0) then BEGIN minCH := 1; maxCH := 16; END ELSE BEGIN minCH = vstChan; maxCH := vstChan; END; FOR ch := minCH to maxCH DO BEGIN for i := 0 to 127 DO BEGIN // send note off s if noteONs[i] := TRUE THEN BEGIN midi.channel := ch; midi.msg := 128; midi.data1 := i; midi.data2 := 0; setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; noteONs[i] := FALSE; END; END; // send sus pedal off! midi.channel := ch; midi.msg := 176; midi.data1 := 64; midi.data2 := 0; end setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; setLength(midiOUT, outCount); clearNotes := FALSE; //if we are clearing, we ignore other midi input for this cycle.... END ELSE BEGIN if newTranspose then begin //strace('in NEW TRANSPOSE'); IF (transCtl = 0) then transpose := round(getValue(transposeIN)) ELSE BEGIN transpose := 0; // create midi cc out for drum tuning (cc value is transCtl) ccTrans := (round((transpose * 1.76) + 64)); //strace('____________CC TRANS = ' + intToStr(ccTrans)); newMidi.msg := 176; newMidi.channel := 1; newMidi.data1 := transCtl; newMidi.data2 := round(ccTrans); SetMidiArrayValue(midiOUT, outCount, newMidi); outCount := outCount + 1; END; newTranspose := FALSE; end; // filter everything but notes for this script! //Hold keeps new notes from being triggered IF hasMidi and (hold = false) and enabled THEN BEGIN countOffset := outCount; FOR i := 0 TO (midiCount - 1) DO BEGIN GetMidiArrayValue(midiIN, i, midi); note := midi.data1; vel := midi.data2; chan := midi.channel; IF (inputCh > 0) then midi.channel := vstChan; //if midiCH is 0 leave unchanged IF (midi.msg = 224) OR ((midi.msg = 172) AND (noSus = false)) THEN BEGIN //strace('message = ' + inttoStr(midi.msg)); SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END //TODO: how does this work with PB and SUS on multi ch sources? ELSE IF (inputCH > 0) AND (chan <> inputCH) THEN //ignore notes from other channels. 0 is omni. ELSE IF (note < lowNote) or (note > hiNote) THEN //ignore notes outside range. True for any status. Includes NS limiting ELSE IF (status = 3) and (nSoloLow <= note) and (note <= nSoloHI) THEN //ignore note solo range on NS channel //strace('tracknum = ' + inttostr(trackNum) +', nsolo lo = ' + inttostr(nSoloLow) + ', nSoloHI = ' + inttostr(nSoloHi) + ',note = ' + intToStr(note)); ELSE BEGIN IF ((midi.msg = 144) AND (midi.data2 > 0)) THEN BEGIN // NoteOn if hands then makeHands; if resetClk and (vel > resetVel) then begin //strace('resetting------------------------------------- '); setLength(resetClkOUT,1); setValue(resetClkOUT,1); resetting := true; end; transpositions[midi.data1] := transpose; // Store transpose value used for NoteOn noteOns[midi.data1] := TRUE; midi.data1 := midi.data1 + transpose; END ELSE IF ( (midi.msg = 128) OR ((midi.msg = 144) AND (midi.data2 = 0))) THEN BEGIN // NoteOff if hands then makeHands; if (transCtl = 0) then begin // Retrieve stored transpose and add to NoteOff midi.data1 := midi.data1 + transpositions[midi.data1]; noteOns[midi.data1] := FALSE; end; END; //ELSE IF (midi.msg = 172) and (midi.data1 = 64) SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END; END; setLength(midiOUT, outCount); END ELSE BEGIN SetLength(midiOUT, 0); END; END; END;END;Statistics: Posted by woodslanding — 01 Nov 2017, 07:32
CODE:
/////////////////////////////////////////////////////////////////////////////// VST CH of 0 is causing error// Limit vst ch to 1 thru 16. Use INPUT CH = 0 to stop channelization of messages!/////////////////////////////////////////////////////////////////////////////const STATUS_ENABLED = 1;const STATUS_DISABLED = 0;const STATUS_NOTESOLOED = 2; //a note solo instrument will mute other instruments on its channel over its key rangeconst STATUS_COMPROMISED = 3;//when all or part of the noterange is muted by a notesolo inst on another trackVAR midiIN, midiOUT : Tparameter;// from NS var transposeIN: Tparameter;var lowNoteIN : Tparameter; var hiNoteIN : Tparameter;var chanIN : Tparameter;var statusOUT : Tparameter;var vstChIN : Tparameter;// from mixervar handsIN : Tparameter; var holdIN : Tparameter;var trackIN : Tparameter; var enabledIN : Tparameter; // from inst var transToCtlIN : Tparameter;var resetClkIN : Tparameter;var resetVelIN : Tparameter;//arraysvar nSolosIN : Tparameter; var noSusIN : Tparameter;var nsLowNotesIN : Tparameter;var nsHiNotesIN : Tparameter; var resetClkOUT : Tparameter; var clearIN : Tparameter; VAR transpositions : ARRAY OF integer;VAR noteONs : ARRAY OF boolean; VAR midi : tMidi; VAR midiCount, transpose,transCtl,i, trackCount, trackNum,status : integer;VAR newTranspose,hands,hold,resetClk,resetting: boolean; var lowNote,hiNote,nSoloLow,nSoloHi, inputCh, vstChan, vel, resetVel: integer; var nSolo, clearNotes, enabled,noSus: boolean;PROCEDURE Init; BEGIN//from NS midiIN := CreateParam('midi in', ptMidi); SetIsOutput(midiIN, FALSE); //0 = OMNI, 17 = Disable Midi note Processing (for normal fx) chanIN := CreateParam('midi chan', ptDatafield); SetIsOutput(chanIN, FALSE); lowNoteIN := CreateParam('low note', ptDataField); SetIsOutput(lowNoteIN, FALSE); hiNoteIN := CreateParam('hi note', ptDataField); SetIsOutput(hiNoteIN, FALSE);//from mixer transposeIN := CreateParam('transpose', ptDataField);SetIsOutput(transposeIN, FALSE); handsIN := CreateParam('hands on',ptSwitch); SetIsOutput(handsIN, false); holdIN := CreateParam('hold on',ptSwitch); SetIsOutput(holdIN, false); //from inst transToCtlIN := CreateParam('transToCtl',ptDatafield); SetIsOutput(transToCtlIN, false); //ns array is an array [1..trackcount] of midi channels. 0 means either the chan is disabled, or it is not a ns channel nSolosIN := CreateParam('nsSolo arr',ptArray); SetIsOutput(nSolosIN, false); nsLowNotesIN := CreateParam('ns low arr',ptArray); SetIsOutput(nsLowNotesIN, false); nsHiNotesIN := CreateParam('ns high arr',ptArray); SetIsOutput(nsHiNotesIN, false); // what ch the vst inst wants to see. If INPUT CH is 0 or 17, this doesn't matter! vstChIN := CreateParam('vst chan', ptDatafield); SetIsOutput(vstChIN, FALSE); clearIN := CreateParam('clear notes',ptSwitch); SetIsOutput(clearIN, false); resetClkIN := CreateParam('vel clock reset', ptDatafield); SetIsOutput(resetClkIN, FALSE); resetVelIN := CreateParam('reset vel thresh', ptDatafield); SetIsOutput(resetVelIN, FALSE); trackIN := CreateParam('track num', ptDatafield); SetIsOutput(trackIN, FALSE); enabledIN := CreateParam('enable', ptDatafield); SetIsOutput(enabledIN, FALSE); noSusIN := CreateParam('no sus', ptDatafield); SetIsOutput(noSusIN, FALSE); resetClkOUT := CreateParam('reset clock', ptDatafield); SetIsInput(resetClkOUT, FALSE); midiOUT := CreateParam('midi out', ptMidi); SetIsInput(midiOUT, FALSE); statusOUT := CreateParam('status', ptDatafield); SetIsInput(statusOUT, FALSE); SetArrayLength(transpositions, 128); SetArrayLength(noteONs, 128); for i := 0 to 127 DO BEGIN transpositions[i] := 0; noteOns[i] := FALSE; END; clearNotes := FALSE; newTranspose := FALSE; setLength(resetClkOUT,0); //strace('INIT FINISHED--MIDIINPUTPROC');END; // Initprocedure makeHands;var note : integer;begin hands := trunc(getValue(handsIN)); if hands then begin note := midi.data1; if note > 60 then midi.data1 := note - 12 else midi.data1 := note + 12; end; end;procedure setStatus;var compromised : boolean;BEGIN //status: 0-off; 1-on; 2-noteSolo; 3-muted by noteSolo; compromised := false; status := STATUS_ENABLED; //maybe these aren't always initialized???? vstChan := trunc(getValue(vstChIN)); inputCh := trunc(getValue(chanIN)); enabled := trunc(getValue(enabledIN); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); if not enabled THEN status := STATUS_DISABLED ELSE BEGIN //check our own status strace('CHECKING STATUS-----------------------------------------'); trackCount := getLength(nSolosIN); //figure key range based on NS nSolo := getDataArrayValue(nSolosIN,trackNum - 1) = inputCh; IF nSolo THEN BEGIN nSoloHI := trunc(getDataArrayValue(nsHiNotesIN, trackNum - 1)); nSoloLow := trunc(getDataArrayValue(nsLowNotesIN, trackNum - 1)); IF nSoloHI < hiNote THEN hiNote := nSoloHI; IF nSoloLow > lowNote THEN lowNote := nSoloLow; END ELSE BEGIN // reset the keyboard range... //strace('resetting keyboard range for channel ' + inttostr(trackNum)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); END; //No notesoloing for FX (ch 17) IF (inputCH = 17) THEN BEGIN IF enabled THEN status := STATUS_ENABLED ELSE status := STATUS_DISABLED; END //cannot be note solo in omni mode! ELSE IF (inputCH > 0) and nSolo THEN BEGIN //we are a note solo inst //strace('note solo ON for track number ' + intToStr(trackNum)); status := STATUS_NOTESOLOED; END ELSE BEGIN // compute status and nsInfo from arrays nSoloHI := 0; nSoloLow := 127 for i := 0 to trackCount - 1 do BEGIN if (inputCH > 0) and (getDataArrayValue(nSolosIN,i) = inputCH) then BEGIN //we are note solo compromised. //strace('note solo affecting track number ' + intToStr(trackNum)); compromised := true; if (getDataArrayValue(nsHiNotesIN,i) > nSoloHI) then nSoloHI := trunc(getDataArrayValue(nsHiNotesIN,i)); if (getDataArrayValue(nsLowNotesIN,i) < nSoloLow) then nSoloLow := trunc(getDataArrayValue(nsLowNotesIN,i)); END; END; //strace('notesoloLow = ' + intToStr(nSoloLow)); //strace('notesoloHi = ' + intToStr(nSoloHi)); if compromised then status := STATUS_COMPROMISED ELSE status := STATUS_ENABLED; END; END; setValue(statusOUT,status)END;procedure callback(n: integer);BEGIN strace('MIDIINPUTPROC CALLBACK: n = ' + inttostr(n)); BEGIN hold := trunc(getValue(holdIN)) = 1; //strace('hold setting clear notes if it is off'); //if we just turned of hold, clear notes IF NOT hold then clearNotes := TRUE; END IF (n = 0) THEN //ignore ELSE IF (n = transposeIN) THEN newTranspose := TRUE ELSE IF (n = trackIN) THEN trackNum := trunc(getValue(trackIN)) ELSE IF (n = transToCtlIN) THEN transCtl := trunc(getValue(transToCtlIN)) ELSE IF (n = resetClkIN) THEN resetClk := trunc(getValue(resetClkIN)) = 1 ELSE IF (n = resetVelIN) THEN resetVel := trunc(getValue(resetVelIN)) ELSE IF (n = noSusIN) THEN noSus := trunc(getValue(noSusIN)) > 0 ELSE IF (n = holdIN) THEN ELSE IF (n = enabledIN) THEN BEGIN enabled := trunc(getValue(enabledIN)) = 1; //strace('enabled setting clear notes if not enabled and not hold'); if NOT enabled and NOT hold then clearNotes := TRUE; setStatus; END //some other inst has changed, so we need to check status ELSE IF (n = nsHiNotesIN) OR (n= nsLowNotesIN) OR (n = nSolosIN) THEN setStatus ELSE IF (n = resetClkOUT) OR (n = midiOUT) OR (n = statusOUT) THEN //why,it's an output?????? ELSE BEGIN IF (n = handsIN) THEN hands := trunc(getValue(handsIN)) ELSE IF (n = vstChIN) THEN vstChan := trunc(getValue(vstChIN)) ELSE IF (n = lowNoteIN) THEN lowNote := trunc(getValue(lowNoteIN)) ELSE IF (n = hiNoteIN) THEN hiNote := trunc(getValue(hiNoteIN)) ELSE IF (n = chanIN) THEN inputCh := trunc(getValue(chanIN)); setStatus; clearNotes := TRUE; //strace('setting clearNotes to true via hands, outch, lownote hinote, or chan'); ENDEND; // processprocedure process;var outCount,note,chan: integer; var ccTrans,countOffset: integer;var newMidi: tMidi; var hasMidi: boolean;var minCH,maxCH,ch : integer; BEGIN //if input is 17[disabled], bypass midi processing entirely IF (inputCH = 17) THEN SetLength(midiOUT, 0) ELSE BEGIN //should filter all but notes, sustain and pb prev to script midiCount := GetLength(midiIN); hasMidi := midiCount > 0; outCount := 0; if resetting = true then begin resetting := false; //turn reset back off setValue(resetClkOUT, 0); //null event for off end IF clearNotes then BEGIN //strace('clearing notes'); //for omni sources, send noteoffs on every channel... //otherwise just send to the chan VST is receiving on IF (inputCh = 0) then BEGIN minCH := 1; maxCH := 16; END ELSE BEGIN minCH = vstChan; maxCH := vstChan; END; FOR ch := minCH to maxCH DO BEGIN for i := 0 to 127 DO BEGIN // send note off s if noteONs[i] := TRUE THEN BEGIN midi.channel := ch; midi.msg := 128; midi.data1 := i; midi.data2 := 0; setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; noteONs[i] := FALSE; END; END; // send sus pedal off! midi.channel := ch; midi.msg := 176; midi.data1 := 64; midi.data2 := 0; end setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; setLength(midiOUT, outCount); clearNotes := FALSE; //if we are clearing, we ignore other midi input for this cycle.... END ELSE BEGIN if newTranspose then begin //strace('in NEW TRANSPOSE'); IF (transCtl = 0) then transpose := round(getValue(transposeIN)) ELSE BEGIN transpose := 0; // create midi cc out for drum tuning (cc value is transCtl) ccTrans := (round((transpose * 1.76) + 64)); //strace('____________CC TRANS = ' + intToStr(ccTrans)); newMidi.msg := 176; newMidi.channel := 1; newMidi.data1 := transCtl; newMidi.data2 := round(ccTrans); SetMidiArrayValue(midiOUT, outCount, newMidi); outCount := outCount + 1; END; newTranspose := FALSE; end; // filter everything but notes for this script! //Hold keeps new notes from being triggered IF hasMidi and (hold = false) and enabled THEN BEGIN countOffset := outCount; FOR i := 0 TO (midiCount - 1) DO BEGIN GetMidiArrayValue(midiIN, i, midi); note := midi.data1; vel := midi.data2; chan := midi.channel; IF (inputCh > 0) then midi.channel := vstChan; //if midiCH is 0 leave unchanged IF (midi.msg = 224) OR ((midi.msg = 172) AND (noSus = false)) THEN BEGIN //strace('message = ' + inttoStr(midi.msg)); SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END //TODO: how does this work with PB and SUS on multi ch sources? ELSE IF (inputCH > 0) AND (chan <> inputCH) THEN //ignore notes from other channels. 0 is omni. ELSE IF (note < lowNote) or (note > hiNote) THEN //ignore notes outside range. True for any status. Includes NS limiting ELSE IF (status = 3) and (nSoloLow <= note) and (note <= nSoloHI) THEN //ignore note solo range on NS channel //strace('tracknum = ' + inttostr(trackNum) +', nsolo lo = ' + inttostr(nSoloLow) + ', nSoloHI = ' + inttostr(nSoloHi) + ',note = ' + intToStr(note)); ELSE BEGIN IF ((midi.msg = 144) AND (midi.data2 > 0)) THEN BEGIN // NoteOn if hands then makeHands; if resetClk and (vel > resetVel) then begin //strace('resetting------------------------------------- '); setLength(resetClkOUT,1); setValue(resetClkOUT,1); resetting := true; end; transpositions[midi.data1] := transpose; // Store transpose value used for NoteOn noteOns[midi.data1] := TRUE; midi.data1 := midi.data1 + transpose; END ELSE IF ( (midi.msg = 128) OR ((midi.msg = 144) AND (midi.data2 = 0))) THEN BEGIN // NoteOff if hands then makeHands; if (transCtl = 0) then begin // Retrieve stored transpose and add to NoteOff midi.data1 := midi.data1 + transpositions[midi.data1]; noteOns[midi.data1] := FALSE; end; END; //ELSE IF (midi.msg = 172) and (midi.data1 = 64) SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END; END; setLength(midiOUT, outCount); END ELSE BEGIN SetLength(midiOUT, 0); END; END; END;END;Statistics: Posted by woodslanding — 01 Nov 2017, 06:50
CODE:
/////////////////////////////////////////////////////////////////////////////// vstChIN parameter value of 0 is causing error// Error : E901 patch process : Process of MIDI In (rack: 3) patch: gui.pat //next patch down/////////////////////////////////////////////////////////////////////////////VAR midiIN, midiOUT : Tparameter;// from NS var transposeIN: Tparameter;var lowNoteIN : Tparameter; var hiNoteIN : Tparameter;var chanIN : Tparameter;var statusOUT : Tparameter;var vstChIN : Tparameter;// from mixervar handsIN : Tparameter; var holdIN : Tparameter;var trackIN : Tparameter; var enabledIN : Tparameter; // from inst var transToCtlIN : Tparameter;var resetClkIN : Tparameter;var resetVelIN : Tparameter;//arraysvar nSolosIN : Tparameter; var noSusIN : Tparameter;var nsLowNotesIN : Tparameter;var nsHiNotesIN : Tparameter; var resetClkOUT : Tparameter; var clearIN : Tparameter; VAR transpositions : ARRAY OF integer;VAR noteONs : ARRAY OF boolean;VAR midi : tMidi; VAR midiCount, transpose,transCtl,i, trackCount, trackNum,status : integer;VAR newTranspose,hands,hold,resetClk,resetting: boolean; var lowNote,hiNote,nSoloLow,nSoloHi, inputCh, vstChan, vel, resetVel: integer; var nSolo, clearNotes, enabled,noSus: boolean;PROCEDURE Init; BEGIN//from NS midiIN := CreateParam('midi in', ptMidi); SetIsOutput(midiIN, FALSE); chanIN := CreateParam('midi chan', ptDatafield); SetIsOutput(chanIN, FALSE); lowNoteIN := CreateParam('low note', ptDataField); SetIsOutput(lowNoteIN, FALSE); hiNoteIN := CreateParam('hi note', ptDataField); SetIsOutput(hiNoteIN, FALSE);//from mixer transposeIN := CreateParam('transpose', ptDataField);SetIsOutput(transposeIN, FALSE); handsIN := CreateParam('hands on',ptSwitch); SetIsOutput(handsIN, false); holdIN := CreateParam('hold on',ptSwitch); SetIsOutput(holdIN, false); //from inst transToCtlIN := CreateParam('transToCtl',ptDatafield); SetIsOutput(transToCtlIN, false); //ns array is an array [1..trackcount] of midi channels. 0 means either the chan is disabled, or it is not a ns channel nSolosIN := CreateParam('nsSolo arr',ptArray); SetIsOutput(nSolosIN, false); nsLowNotesIN := CreateParam('ns low arr',ptArray); SetIsOutput(nsLowNotesIN, false); nsHiNotesIN := CreateParam('ns high arr',ptArray); SetIsOutput(nsHiNotesIN, false); // what ch the inst wants. 0 for multichan... CAUSING ERROR!!!!! vstChIN := CreateParam('vst chan', ptDatafield); SetIsOutput(vstChIN, FALSE); clearIN := CreateParam('clear notes',ptSwitch); SetIsOutput(clearIN, false); resetClkIN := CreateParam('vel clock reset', ptDatafield); SetIsOutput(resetClkIN, FALSE); resetVelIN := CreateParam('reset vel thresh', ptDatafield); SetIsOutput(resetVelIN, FALSE); trackIN := CreateParam('track num', ptDatafield); SetIsOutput(trackIN, FALSE); enabledIN := CreateParam('enable', ptDatafield); SetIsOutput(enabledIN, FALSE); noSusIN := CreateParam('no sus', ptDatafield); SetIsOutput(noSusIN, FALSE); resetClkOUT := CreateParam('reset clock', ptDatafield); SetIsInput(resetClkOUT, FALSE); midiOUT := CreateParam('midi out', ptMidi); SetIsInput(midiOUT, FALSE); statusOUT := CreateParam('status', ptDatafield); SetIsInput(statusOUT, FALSE); SetArrayLength(transpositions, 128); SetArrayLength(noteONs, 128); for i := 0 to 127 DO BEGIN transpositions[i] := 0; noteOns[i] := FALSE; END; clearNotes := FALSE; newTranspose := FALSE; setLength(resetClkOUT,0);END; // Initprocedure makeHands;var note : integer;begin if hands then begin note := midi.data1; if note > 60 then midi.data1 := note - 12 else midi.data1 := note + 12; end; end;procedure setStatus;var compromised : boolean;BEGIN compromised := false; if not enabled THEN status := 0 ELSE BEGIN //check our own status trackCount := getLength(nSolosIN); //figure key range based on NS nSolo := getDataArrayValue(nSolosIN,trackNum - 1) = inputCh; IF nSolo THEN BEGIN nSoloHI := trunc(getDataArrayValue(nsHiNotesIN, trackNum - 1)); nSoloLow := trunc(getDataArrayValue(nsLowNotesIN, trackNum - 1)); IF nSoloHI < hiNote THEN hiNote := nSoloHI; IF nSoloLow > lowNote THEN lowNote := nSoloLow; END ELSE BEGIN // reset the keyboard range... //strace('resetting keyboard range for channel ' + inttostr(trackNum)); hiNote := trunc(getValue(hiNoteIN)); lowNote := trunc(getValue(lowNoteIN)); END; //No notesoloing for FX (ch 17) IF (inputCH = 17) THEN BEGIN IF enabled THEN status := 1 ELSE status := 0; END //cannot be note solo in omni mode! ELSE IF (inputCH > 0) and nSolo THEN BEGIN //we are a note solo inst //strace('note solo ON for track number ' + intToStr(trackNum)); status := 2; END ELSE BEGIN // compute status and nsInfo from arrays nSoloHI := 0; nSoloLow := 127 for i := 0 to trackCount - 1 do BEGIN if (inputCH > 0) and (getDataArrayValue(nSolosIN,i) = inputCH) then BEGIN //we are note solo compromised. //strace('note solo affecting track number ' + intToStr(trackNum)); compromised := true; if (getDataArrayValue(nsHiNotesIN,i) > nSoloHI) then nSoloHI := trunc(getDataArrayValue(nsHiNotesIN,i)); if (getDataArrayValue(nsLowNotesIN,i) < nSoloLow) then nSoloLow := trunc(getDataArrayValue(nsLowNotesIN,i)); END; END; //strace('notesoloLow = ' + intToStr(nSoloLow)); //strace('notesoloHi = ' + intToStr(nSoloHi)); if compromised then status := 3 ELSE status := 1; END; END; setValue(statusOUT,status)END;procedure callback(n: integer);BEGIN //strace('n = ' + inttostr(n)); IF (n = 0) THEN //ignore ELSE IF (n = transposeIN) THEN newTranspose := TRUE ELSE IF (n = trackIN) THEN trackNum := trunc(getValue(trackIN)) ELSE IF (n = transToCtlIN) THEN transCtl := trunc(getValue(transToCtlIN)) ELSE IF (n = resetClkIN) THEN resetClk := trunc(getValue(resetClkIN)) = 1 ELSE IF (n = resetVelIN) THEN resetVel := trunc(getValue(resetVelIN)) ELSE IF (n = noSusIN) THEN noSus := trunc(getValue(noSusIN)) > 0 ELSE IF (n = holdIN) THEN BEGIN hold := trunc(getValue(holdIN)) = 1; //strace('hold setting clear notes if it is off'); //if we just turned of hold, clear notes IF NOT hold then clearNotes := TRUE; END ELSE IF (n = enabledIN) THEN BEGIN enabled := trunc(getValue(enabledIN)) = 1; //strace('enabled setting clear notes if not enabled and not hold'); if NOT enabled and NOT hold then clearNotes := TRUE; setStatus; END //some other inst has changed, so we need to check status ELSE IF (n = nsHiNotesIN) OR (n= nsLowNotesIN) OR (n = nSolosIN) THEN setStatus ELSE IF (n = resetClkOUT) OR (n = midiOUT) OR (n = statusOUT) THEN //why,it's an output?????? ELSE BEGIN IF (n = handsIN) THEN hands := trunc(getValue(handsIN)) ELSE IF (n = vstChIN) THEN vstChan := trunc(getValue(vstChIN)) ELSE IF (n = lowNoteIN) THEN lowNote := trunc(getValue(lowNoteIN)) ELSE IF (n = hiNoteIN) THEN hiNote := trunc(getValue(hiNoteIN)) ELSE IF (n = chanIN) THEN inputCh := trunc(getValue(chanIN)); setStatus; clearNotes := TRUE; //strace('setting clearNotes to true via hands, outch, lownote hinote, or chan'); ENDEND; // processprocedure process;var outCount,note,chan: integer; var ccTrans,countOffset: integer;var newMidi: tMidi; var hasMidi: boolean;var minCH,maxCH,ch : integer; BEGIN IF (vstChan = 17) THEN SetLength(midiOUT, 0) // no midi processing at all ELSE BEGIN //should filter all but notes, sustain and pb prev to script midiCount := GetLength(midiIN); hasMidi := midiCount > 0; outCount := 0; if resetting = true then begin resetting := false; //turn reset back off setValue(resetClkOUT, 0); //null event for off end IF clearNotes and (vstChan < 17) then BEGIN //strace('clearing notes'); //for omni sources, send noteoffs on every channel... IF vstChan = 0 then BEGIN minCH := 1; maxCH := 16; END ELSE BEGIN minCH = vstChan; maxCH := vstChan; END; FOR ch := minCH to maxCH DO BEGIN for i := 0 to 127 DO BEGIN // send note off s if noteONs[i] := TRUE THEN BEGIN midi.channel := ch; midi.msg := 128; midi.data1 := i; midi.data2 := 0; setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; noteONs[i] := FALSE; END; END; // send sus pedal off! midi.channel := ch; midi.msg := 176; midi.data1 := 64; midi.data2 := 0; end setMidiArrayValue(midiOUT, outCount, midi); outCount := outCount + 1; setLength(midiOUT, outCount); clearNotes := FALSE; //if we are clearing, we ignore other midi input for this cycle.... END ELSE BEGIN if newTranspose and (vstChan < 17) then begin strace('in NEW TRANSPOSE'); IF (transCtl = 0) then transpose := round(getValue(transposeIN)) ELSE BEGIN transpose := 0; // create midi cc out for drum tuning (cc value is transCtl) ccTrans := (round((transpose * 1.76) + 64)); //strace('____________CC TRANS = ' + intToStr(ccTrans)); newMidi.msg := 176; newMidi.channel := 1; newMidi.data1 := transCtl; newMidi.data2 := round(ccTrans); SetMidiArrayValue(midiOUT, outCount, newMidi); outCount := outCount + 1; END; newTranspose := FALSE; end; // filter everything but notes for this script! //Hold keeps new notes from being triggered IF hasMidi and (hold = false) and enabled and (vstChan < 17) THEN BEGIN countOffset := outCount; FOR i := 0 TO (midiCount - 1) DO BEGIN GetMidiArrayValue(midiIN, i, midi); note := midi.data1; vel := midi.data2; chan := midi.channel; IF (inputCh > 0) then midi.channel := vstChan; //if midiCH is 0 leave unchanged IF (midi.msg = 224) OR ((midi.msg = 172) AND (noSus = false)) THEN BEGIN //strace('message = ' + inttoStr(midi.msg)); SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END //TODO: how does this work with PB and SUS on multi ch sources? ELSE IF (inputCH > 0) AND (chan <> inputCH) THEN //ignore notes from other channels. 0 is omni. ELSE IF (note < lowNote) or (note > hiNote) THEN //ignore notes outside range. True for any status. Includes NS limiting ELSE IF (status = 3) and (nSoloLow <= note) and (note <= nSoloHI) THEN //ignore note solo range on NS channel //strace('tracknum = ' + inttostr(trackNum) +', nsolo lo = ' + inttostr(nSoloLow) + ', nSoloHI = ' + inttostr(nSoloHi) + ',note = ' + intToStr(note)); ELSE BEGIN IF ((midi.msg = 144) AND (midi.data2 > 0)) THEN BEGIN // NoteOn if hands then makeHands; if resetClk and (vel > resetVel) then begin //strace('resetting------------------------------------- '); setLength(resetClkOUT,1); setValue(resetClkOUT,1); resetting := true; end; transpositions[midi.data1] := transpose; // Store transpose value used for NoteOn noteOns[midi.data1] := TRUE; midi.data1 := midi.data1 + transpose; END ELSE IF ( (midi.msg = 128) OR ((midi.msg = 144) AND (midi.data2 = 0))) THEN BEGIN // NoteOff if hands then makeHands; if (transCtl = 0) then begin midi.data1 := midi.data1 + transpositions[midi.data1]; // Retrieve stored transpose and add to NoteOff noteOns[midi.data1] := FALSE; end; END; //ELSE IF (midi.msg = 172) and (midi.data1 = 64) SetMidiArrayValue(midiOUT, outcount, midi); outCount := outCount + 1; END; END; setLength(midiOUT, outCount); END ELSE BEGIN SetLength(midiOUT, 0); END; END; END;END;Statistics: Posted by woodslanding — 31 Oct 2017, 16:52