ArrayArrayArrayArrayArrayArrayArray
CODE: Statistics: Posted by bsork — 22 Feb 2010, 13:46 Statistics: Posted by Clearscreen — 22 Feb 2010, 11:42
Take the code below, copy it into an empty script overwriting the existing text and run compile (ctrl-F9].(*****************************************************************************************************Transpose.scriptScript for inserting into a MIDI stream to transpose all or just a part of the notes received.NoteOffs are mapped to the same channel and note number as the previous NoteOns, avoidinghanging notes even when changing parameters before the note is released.The input channel/note can be sent together with the transposed notes.Key/poly aftertouch can optionally also be transposed together with the notes.*****************************************************************************************************)CONST BUFFER_SIZE = 128;// MIDI channel messagesCONST NOTEOFF = Byte(128);CONST NOTEON = Byte(144);CONST KA = Byte(160); // Key (poly) AftertouchTYPE tMidiArr = ARRAY OF tMidi;TYPE tNoteOns = RECORD origChannel : Byte; origNoteNo : Byte; outChannel : Byte; outNoteNo : Byte; hasKA : Boolean; END;////////////////////////////////////////////////////////////////////////////////////////// In-/out parametersVAR pMidiIn, pMidiOut1 : tParameter;VAR pBypass, pChIn, pTrspLoLim, pTrspHiLim, pInclKA : tParameter;VAR pChOut, pTranspose, pOctFoldBack, pKeep : tParameter;// Global variablesVAR bypass, inclKA : Boolean;VAR sentNoteOns : ARRAY OF tNoteOns;VAR numIn, numSentNoteOns, numOut1 : Integer;VAR chIn, trspLoLim, trspHiLim, chOut : Byte;VAR transpose : Integer;VAR octFoldback, keepOrig : Boolean;////////////////////////////////////////////////////////////////////////////////////////PROCEDURE Init; VAR i : Integer;BEGIN trspLoLim := 0; trspHiLim := 127; chIn := 0; chOut := 0; pMidiIn := CreateParam('midi in', ptMidi); SetIsOutput(pMidiIn, FALSE); pMidiOut1 := CreateParam('midi out', ptMidi); SetIsInput(pMidiOut1, FALSE); pBypass := CreateParam('bypass', ptSwitch); SetIsOutput(pBypass, FALSE); pChIn := CreateParam('channel in', ptListbox); SetIsOutput(pChIn, FALSE); SetListboxString(pChIn, '"all","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"'); SetValue(pChIn, Single(chIn)); pTrspLoLim := CreateParam('note lo limit', ptMidiNoteFader); SetIsOutput(pTrspLoLim, FALSE); SetDefaultValue(pTrspLoLim, trspLoLim); SetValue(pTrspLoLim, trspLoLim); pTrspHiLim := CreateParam('note hi limit', ptMidiNoteFader); SetIsOutput(pTrspHiLim, FALSE); SetDefaultValue(pTrspHiLim, trspHiLim); SetValue(pTrspHiLim, trspHiLim); pInclKA := CreateParam('incl KA', ptSwitch); SetIsOutput(pInclKA, FALSE); pChOut := CreateParam('channel out', ptListbox); SetIsOutput(pChOut, FALSE); SetListboxString(pChOut, '"orig","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"'); SetValue(pChOut, Single(chOut)); pTranspose := CreateParam('transpose', ptDataFader); SetIsOutput(pTranspose, FALSE); SetMin(pTranspose, -48); SetMax(pTranspose, 48); SetFormat(pTranspose, '%.0f'); SetSymbol(pTranspose, 'sm'); pOctFoldback := CreateParam('oct foldback', ptSwitch); SetIsOutput(pOctFoldback, FALSE); pKeep := CreateParam('keep input', ptSwitch); SetIsOutput(pKeep, FALSE); SetArrayLength(sentNoteOns, BUFFER_SIZE); numSentNoteOns := 0; numOut1 := 0;END; // Init///////////////////////////////// Checking channel message types /////////////////////////////////FUNCTION IsNote (currMsg : tMidi) : Boolean;BEGIN IsNote := ((currMsg.msg = NOTEON) OR (currMsg.msg = NOTEOFF));END;FUNCTION IsNoteOn (currMsg : tMidi) : Boolean;BEGIN IsNoteOn := ((currMsg.msg = NOTEON) AND (currMsg.data2 > 0));END;FUNCTION IsNoteOff (currMsg : tMidi) : Boolean;BEGIN IsNoteOff := (currMsg.msg = NOTEOFF) OR ((currMsg.msg = NOTEON) AND (currMsg.data2 = 0));END;FUNCTION IsKA (currMsg : tMidi) : Boolean;BEGIN IsKA := (currMsg.msg = KA);END;////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE mTrace(s : String; m : tMidi);BEGIN WITH m DO WriteLn(s + ': msg:' + IntToStr(msg) + ' ch:' + IntToStr(channel) + ' d1:' + IntToStr(data1) + ' d2:' + IntToStr(data2));END; // mTrace////////////////////////////////////////////////////////////////////////////////////////////////////FUNCTION WithinRange(value : Byte) : Boolean; VAR retVal : Boolean;BEGIN retVal := FALSE; IF ((value >= trspLoLim) AND (value <= trspHiLim)) THEN BEGIN retVal := TRUE; END ELSE IF (value = trspLoLim) OR (value = trspHiLim) THEN BEGIN retVal := TRUE; END ELSE IF (trspLoLim > trspHiLim) THEN BEGIN retVal := ((value < trspHiLim) OR (value > trspLoLim)); END; WithinRange := retVal;END; // WithinRange////////////////////////////////////////////////////////////////////////////////////////////////////FUNCTION CalcTranspose(NoteNo : Byte) : Byte; VAR note : Integer; BEGIN note := Integer(NoteNo) + transpose; IF (note < 0) THEN BEGIN IF (NOT octFoldback) THEN BEGIN note := 0; END ELSE BEGIN note := abs(12 + note) MOD 12; END; END ELSE IF (note > 127) THEN BEGIN IF (NOT octFoldback) THEN BEGIN note := 127; END ELSE BEGIN note := ((note - 128) MOD 12) + 116; END; END; CalcTranspose := Byte(note);END; // CalcTranspose////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE CreateOut(currMsg : tMidi);BEGIN SetMidiArrayValue(pMidiOut1, numOut1, currMsg); numOut1 := numOut1 + 1;END; // CreateOut////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE CreateNoteOnOut(origMsg, outMsg : tMidi); VAR curr : tNoteOns;BEGIN WITH curr DO BEGIN origChannel := origMsg.channel; origNoteNo := origMsg.data1; outChannel := outMsg.channel; outNoteNo := outMsg.data1; hasKA := FALSE; END; sentNoteOns[numSentNoteOns] := curr; numSentNoteOns := numSentNoteOns + 1; CreateOut(outMsg);END; // CreateNoteOnOut///////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE CheckSendNoteOff(currMsg : tMidi); VAR i, j : Integer; VAR outMsg : tMidi; VAR curr : tNoteOns; VAR found : Boolean;BEGIN j := 0; found := FALSE; FOR i := 0 TO (numSentNoteOns - 1) DO BEGIN curr := sentNoteOns[i]; IF ((currMsg.channel = curr.origChannel) AND (currMsg.data1 = curr.origNoteNo)) THEN BEGIN outMsg.msg := currMsg.msg; outMsg.channel := curr.outChannel; outMsg.data1 := curr.outNoteNo; outMsg.data2 := currMsg.data2; CreateOut(outMsg); IF (curr.hasKA) THEN BEGIN outMsg.msg := KA; outMsg.data2 := 0; CreateOut(outMsg); // Resets any key aftertouch <> 0 END; j := j + 1; found := TRUE; END ELSE BEGIN sentNoteOns[i - j] := curr; END; END; numSentNoteOns := numSentNoteOns - j; IF (NOT found) THEN CreateOut(currMsg);END; // CheckSendNoteOff////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE CheckSendKA(currMsg : tMidi); VAR i : Integer; VAR outMsg : tMidi; VAR curr : tNoteOns;BEGIN FOR i := 0 TO (numSentNoteOns - 1) DO BEGIN curr := sentNoteOns[i]; IF ((currMsg.channel = curr.origChannel) AND (currMsg.data1 = curr.origNoteNo)) THEN BEGIN outMsg.msg := currMsg.msg; outMsg.channel := curr.outChannel; outMsg.data1 := curr.outNoteNo; outMsg.data2 := currMsg.data2; sentNoteOns[i].hasKA := TRUE; CreateOut(outMsg); END; END;END; // CheckSendKA////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE CheckInput(currMsg : tMidi); VAR newMsg : tMidi;BEGIN IF (bypass AND IsNoteOn(currMsg)) THEN BEGIN CreateNoteOnOut(currMsg, currMsg); END ELSE IF ( (NOT bypass) AND IsNoteOn(currMsg) AND ((chIn = 0) OR (chIn = currMsg.channel)) AND WithinRange(currMsg.data1)) THEN BEGIN newMsg := currMsg; IF (transpose <> 0) THEN newMsg.data1 := CalcTranspose(newMsg.data1); IF (chOut <> 0) THEN newMsg.channel := chOut; IF (keepOrig AND ((currMsg.channel <> newMsg.channel) OR (currMsg.data1 <> newMsg.data1))) THEN CreateNoteOnOut(currMsg, currMsg); CreateNoteOnOut(currMsg, newMsg); END ELSE IF (IsNoteOff(currMsg)) THEN BEGIN CheckSendNoteOff(currMsg); END ELSE IF (inclKA AND IsKA(currMsg)) THEN BEGIN CheckSendKA(currMsg); END ELSE BEGIN CreateOut(currMsg); END;END; // CheckInput////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE Callback(n : Integer);BEGIN //strace('callback: ' + IntToStr(n)); CASE n OF pMidiIn : numIn := GetLength(n); pBypass : bypass := (GetValue(n) > 0); pChIn : chIn := Byte(trunc(GetValue(n))); pTrspLoLim : trspLoLim := Byte(trunc(GetValue(n))); pTrspHiLim : trspHiLim := Byte(trunc(GetValue(n))); pInclKA : inclKA := (GetValue(n) > 0); pChOut : chOut := Byte(trunc(GetValue(n))); pTranspose : transpose := round(GetValue(n)); pOctFoldback : octFoldback := (GetValue(n) > 0); pKeep : keepOrig := (GetValue(n) > 0); END;END; // Callback////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE Process; VAR i : Integer; VAR currMsg : tMidi;BEGIN FOR i := 0 TO (numIn - 1) DO BEGIN GetMidiArrayValue(pMidiIn, i, currMsg); CheckInput(currMsg); END; SetLength(pMidiOut1, numOut1); numOut1 := 0;END; // Process
]]>![]()
]]>
Statistics: Posted by nofish — 21 Feb 2010, 15:26
Statistics: Posted by nay-seven — 21 Feb 2010, 10:27
Statistics: Posted by woodslanding — 21 Feb 2010, 10:22
Statistics: Posted by Ben J — 21 Feb 2010, 09:59
CODE:
(*****************************************************************************************************Transpose.scriptScript for inserting into a MIDI stream to transpose all or just a part of the notes received.NoteOffs are mapped to the same channel and note number as the previous NoteOns, avoidinghanging notes even when changing parameters before the note is released.The input channel/note can be sent together with the transposed notes.Key/poly aftertouch can optionally also be transposed together with the notes.*****************************************************************************************************)CONST BUFFER_SIZE = 128;// MIDI channel messagesCONST NOTEOFF = Byte(128);CONST NOTEON = Byte(144);CONST KA = Byte(160); // Key (poly) AftertouchTYPE tMidiArr = ARRAY OF tMidi;TYPE tNoteOns = RECORD origChannel : Byte; origNoteNo : Byte; outChannel : Byte; outNoteNo : Byte; hasKA : Boolean; END;////////////////////////////////////////////////////////////////////////////////////////// In-/out parametersVAR pMidiIn, pMidiOut1 : tParameter;VAR pBypass, pChIn, pTrspLoLim, pTrspHiLim, pInclKA : tParameter;VAR pChOut, pTranspose, pOctFoldBack, pKeep : tParameter;// Global variablesVAR bypass, inclKA : Boolean;VAR sentNoteOns : ARRAY OF tNoteOns;VAR numIn, numSentNoteOns, numOut1 : Integer;VAR chIn, trspLoLim, trspHiLim, chOut : Byte;VAR transpose : Integer;VAR octFoldback, keepOrig : Boolean;////////////////////////////////////////////////////////////////////////////////////////PROCEDURE Init; VAR i : Integer;BEGIN trspLoLim := 0; trspHiLim := 127; chIn := 0; chOut := 0; pMidiIn := CreateParam('midi in', ptMidi); SetIsOutput(pMidiIn, FALSE); pMidiOut1 := CreateParam('midi out', ptMidi); SetIsInput(pMidiOut1, FALSE); pBypass := CreateParam('bypass', ptSwitch); SetIsOutput(pBypass, FALSE); pChIn := CreateParam('channel in', ptListbox); SetIsOutput(pChIn, FALSE); SetListboxString(pChIn, '"all","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"'); SetValue(pChIn, Single(chIn)); pTrspLoLim := CreateParam('note lo limit', ptMidiNoteFader); SetIsOutput(pTrspLoLim, FALSE); SetDefaultValue(pTrspLoLim, trspLoLim); SetValue(pTrspLoLim, trspLoLim); pTrspHiLim := CreateParam('note hi limit', ptMidiNoteFader); SetIsOutput(pTrspHiLim, FALSE); SetDefaultValue(pTrspHiLim, trspHiLim); SetValue(pTrspHiLim, trspHiLim); pInclKA := CreateParam('incl KA', ptSwitch); SetIsOutput(pInclKA, FALSE); pChOut := CreateParam('channel out', ptListbox); SetIsOutput(pChOut, FALSE); SetListboxString(pChOut, '"orig","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"'); SetValue(pChOut, Single(chOut)); pTranspose := CreateParam('transpose', ptDataFader); SetIsOutput(pTranspose, FALSE); SetMin(pTranspose, -48); SetMax(pTranspose, 48); SetFormat(pTranspose, '%.0f'); SetSymbol(pTranspose, 'sm'); pOctFoldback := CreateParam('oct foldback', ptSwitch); SetIsOutput(pOctFoldback, FALSE); pKeep := CreateParam('keep input', ptSwitch); SetIsOutput(pKeep, FALSE); SetArrayLength(sentNoteOns, BUFFER_SIZE); numSentNoteOns := 0; numOut1 := 0;END; // Init///////////////////////////////// Checking channel message types /////////////////////////////////FUNCTION IsNote (currMsg : tMidi) : Boolean;BEGIN IsNote := ((currMsg.msg = NOTEON) OR (currMsg.msg = NOTEOFF));END;FUNCTION IsNoteOn (currMsg : tMidi) : Boolean;BEGIN IsNoteOn := ((currMsg.msg = NOTEON) AND (currMsg.data2 > 0));END;FUNCTION IsNoteOff (currMsg : tMidi) : Boolean;BEGIN IsNoteOff := (currMsg.msg = NOTEOFF) OR ((currMsg.msg = NOTEON) AND (currMsg.data2 = 0));END;FUNCTION IsKA (currMsg : tMidi) : Boolean;BEGIN IsKA := (currMsg.msg = KA);END;////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE mTrace(s : String; m : tMidi);BEGIN WITH m DO WriteLn(s + ': msg:' + IntToStr(msg) + ' ch:' + IntToStr(channel) + ' d1:' + IntToStr(data1) + ' d2:' + IntToStr(data2));END; // mTrace////////////////////////////////////////////////////////////////////////////////////////////////////FUNCTION WithinRange(value : Byte) : Boolean; VAR retVal : Boolean;BEGIN retVal := FALSE; IF ((value >= trspLoLim) AND (value <= trspHiLim)) THEN BEGIN retVal := TRUE; END ELSE IF (value = trspLoLim) OR (value = trspHiLim) THEN BEGIN retVal := TRUE; END ELSE IF (trspLoLim > trspHiLim) THEN BEGIN retVal := ((value < trspHiLim) OR (value > trspLoLim)); END; WithinRange := retVal;END; // WithinRange////////////////////////////////////////////////////////////////////////////////////////////////////FUNCTION CalcTranspose(NoteNo : Byte) : Byte; VAR note : Integer; BEGIN note := Integer(NoteNo) + transpose; IF (note < 0) THEN BEGIN IF (NOT octFoldback) THEN BEGIN note := 0; END ELSE BEGIN note := abs(12 + note) MOD 12; END; END ELSE IF (note > 127) THEN BEGIN IF (NOT octFoldback) THEN BEGIN note := 127; END ELSE BEGIN note := ((note - 128) MOD 12) + 116; END; END; CalcTranspose := Byte(note);END; // CalcTranspose////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE CreateOut(currMsg : tMidi);BEGIN SetMidiArrayValue(pMidiOut1, numOut1, currMsg); numOut1 := numOut1 + 1;END; // CreateOut////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE CreateNoteOnOut(origMsg, outMsg : tMidi); VAR curr : tNoteOns;BEGIN WITH curr DO BEGIN origChannel := origMsg.channel; origNoteNo := origMsg.data1; outChannel := outMsg.channel; outNoteNo := outMsg.data1; hasKA := FALSE; END; sentNoteOns[numSentNoteOns] := curr; numSentNoteOns := numSentNoteOns + 1; CreateOut(outMsg);END; // CreateNoteOnOut///////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE CheckSendNoteOff(currMsg : tMidi); VAR i, j : Integer; VAR outMsg : tMidi; VAR curr : tNoteOns; VAR found : Boolean;BEGIN j := 0; found := FALSE; FOR i := 0 TO (numSentNoteOns - 1) DO BEGIN curr := sentNoteOns[i]; IF ((currMsg.channel = curr.origChannel) AND (currMsg.data1 = curr.origNoteNo)) THEN BEGIN outMsg.msg := currMsg.msg; outMsg.channel := curr.outChannel; outMsg.data1 := curr.outNoteNo; outMsg.data2 := currMsg.data2; CreateOut(outMsg); IF (curr.hasKA) THEN BEGIN outMsg.msg := KA; outMsg.data2 := 0; CreateOut(outMsg); // Resets any key aftertouch <> 0 END; j := j + 1; found := TRUE; END ELSE BEGIN sentNoteOns[i - j] := curr; END; END; numSentNoteOns := numSentNoteOns - j; IF (NOT found) THEN CreateOut(currMsg);END; // CheckSendNoteOff////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE CheckSendKA(currMsg : tMidi); VAR i : Integer; VAR outMsg : tMidi; VAR curr : tNoteOns;BEGIN FOR i := 0 TO (numSentNoteOns - 1) DO BEGIN curr := sentNoteOns[i]; IF ((currMsg.channel = curr.origChannel) AND (currMsg.data1 = curr.origNoteNo)) THEN BEGIN outMsg.msg := currMsg.msg; outMsg.channel := curr.outChannel; outMsg.data1 := curr.outNoteNo; outMsg.data2 := currMsg.data2; sentNoteOns[i].hasKA := TRUE; CreateOut(outMsg); END; END;END; // CheckSendKA////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE CheckInput(currMsg : tMidi); VAR newMsg : tMidi;BEGIN IF (bypass AND IsNoteOn(currMsg)) THEN BEGIN CreateNoteOnOut(currMsg, currMsg); END ELSE IF ( (NOT bypass) AND IsNoteOn(currMsg) AND ((chIn = 0) OR (chIn = currMsg.channel)) AND WithinRange(currMsg.data1)) THEN BEGIN newMsg := currMsg; IF (transpose <> 0) THEN newMsg.data1 := CalcTranspose(newMsg.data1); IF (chOut <> 0) THEN newMsg.channel := chOut; IF (keepOrig AND ((currMsg.channel <> newMsg.channel) OR (currMsg.data1 <> newMsg.data1))) THEN CreateNoteOnOut(currMsg, currMsg); CreateNoteOnOut(currMsg, newMsg); END ELSE IF (IsNoteOff(currMsg)) THEN BEGIN CheckSendNoteOff(currMsg); END ELSE IF (inclKA AND IsKA(currMsg)) THEN BEGIN CheckSendKA(currMsg); END ELSE BEGIN CreateOut(currMsg); END;END; // CheckInput////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE Callback(n : Integer);BEGIN //strace('callback: ' + IntToStr(n)); CASE n OF pMidiIn : numIn := GetLength(n); pBypass : bypass := (GetValue(n) > 0); pChIn : chIn := Byte(trunc(GetValue(n))); pTrspLoLim : trspLoLim := Byte(trunc(GetValue(n))); pTrspHiLim : trspHiLim := Byte(trunc(GetValue(n))); pInclKA : inclKA := (GetValue(n) > 0); pChOut : chOut := Byte(trunc(GetValue(n))); pTranspose : transpose := round(GetValue(n)); pOctFoldback : octFoldback := (GetValue(n) > 0); pKeep : keepOrig := (GetValue(n) > 0); END;END; // Callback////////////////////////////////////////////////////////////////////////////////////////////////////PROCEDURE Process; VAR i : Integer; VAR currMsg : tMidi;BEGIN FOR i := 0 TO (numIn - 1) DO BEGIN GetMidiArrayValue(pMidiIn, i, currMsg); CheckInput(currMsg); END; SetLength(pMidiOut1, numOut1); numOut1 := 0;END; // ProcessStatistics: Posted by bsork — 22 Feb 2010, 13:46
Statistics: Posted by Clearscreen — 22 Feb 2010, 11:42
Statistics: Posted by nofish — 21 Feb 2010, 15:26
Statistics: Posted by nay-seven — 21 Feb 2010, 10:27
Statistics: Posted by woodslanding — 21 Feb 2010, 10:22
Statistics: Posted by Ben J — 21 Feb 2010, 09:59