ArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArrayArray BrainModular BrainModular Users Forum 2010-01-10T12:47:11+02:00 https://brainmodular.org/forums/app.php/feed/topic/1777 2010-01-10T12:47:11+02:00 2010-01-10T12:47:11+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=11196#p11196 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
tomorrow....

Statistics: Posted by woodslanding — 10 Jan 2010, 11:47


]]>
2010-01-10T12:32:26+02:00 2010-01-10T12:32:26+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=11195#p11195 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
So I put in a couple of booleans to decide whether to send the note offs and disable the instrument, but then I called the actual methods from within process. Seems to work! Here's the code:

CODE:

&#40;*/////////////////////////////////////////////////////// CHANNEL  // Version 2009-11-21; author&#58; eric moon//// based on work by Bsork and amiga909//////////////////////////////////////////////////////*&#41;//  This takes a number of midi inputs &#40;on separate cables, for visual clarity&#41;//  and performs the following operations on each.//  enable, disable--per input//  strip CCs and AT and send them out a separate output//  read CC64 values &#40;or a CC of your choice&#41; to withhold noteoffs until the sus pedal is released.//  limit to minimum and maximum notes--one range affects all inputs, as it's assumed you'll typically be using one input at a time//  transpose--again, one range for all inputs.//  output rechannelizing--all outs are a single channel.  Use multiple strips to control multi-timbral modules.//  bypass output for turning off unused instruments.  waits for all notes to be released....//  drone switch that keeps current notes sounding, but discards new notesOns as long as it is held//  It is designed to function as part of a mixer channel strip, running between several keyboards and a vsti.//  When the 'learn' function is enabled, notes are sent out output 2//  the first note sets the lower range, the second note sets the upper limit.//  when both notes are sent, learn is disabled, and notes go to output 1 as usual.CONST SUS_PED= 64;    //change if you use an unorthodox CC for sustaining.CONST INPUT_COUNT = 2;  //allows up to 16 inputs, one per channelCONST NOTE_ON        = 144;CONST NOTE_OFF       = 128;CONST CONTROL        = 176;CONST PITCHBEND      = 224;VAR   noteList                              &#58; ARRAY OF boolean;VAR   transList                             &#58; ARRAY OF integer;VAR   midi,noteOff                          &#58; TMidi; var midiIns                                 &#58;  ARRAY OF Tparameter;var enables                                 &#58;  ARRAY OF TParameter;var notesOut  &#58; Tparameter;var otherOut  &#58; Tparameter;       // all CCs except the sustain value go out this output.  So does AT and PgChvar octave    &#58; TParameter;var semi      &#58; TParameter;var hiNote    &#58; TParameter;var lowNote   &#58; TParameter;var drone     &#58; TParameter;       // sustains, but ignores new noteonsvar outChan   &#58; TParameter;       // everything goes out one channel.  It's a channel strip. Use more if you need other channels!var instEnable&#58; TParameter;var lower    &#58; Tparameter;var upper   &#58; Tparameter; var learn     &#58; TParameter;VAR   octVal, semiVal, transpose            &#58; integer;VAR   hiVal, lowVal                         &#58; integer; VAR   midiInCount                           &#58; integer;VAR   otherOutCount, notesOutCount          &#58; integer;VAR   key, inputNum, byteNum                &#58; integer; VAR   minChn, maxChn, minKey, maxKey        &#58; integer;VAR   outputChannel                         &#58; integer;VAR   isSustained,noInput                   &#58; boolean;VAR   isEnabled                             &#58; Array of boolean;VAR   learning                              &#58; boolean;VAR   droning                               &#58; boolean;VAR   release                               &#58; boolean;VAR   disablable                            &#58; boolean;var   learnCount                            &#58; integer;//////////////////////////////////////////////////////// initialize//////////////////////////////////////////////////////PROCEDURE init;    BEGIN      minChn &#58;= INPUT_COUNT - 1;   // these are initially set to their opposite extremes....    maxChn &#58;= 0;     minKey &#58;= 128;     maxKey &#58;= 0;        isSustained &#58;= FALSE;              setArrayLength&#40;noteList, 128&#41;;      FOR key&#58;=0 TO 127 DO BEGIN         noteList&#91;key&#93;&#58;=FALSE;    END;    SetArrayLength&#40;transList, 128&#41;;    FOR key&#58;=0 TO 127 DO BEGIN         transList&#91;key&#93;&#58;=0;    END;           setArrayLength&#40;midiIns, INPUT_COUNT&#41;;    setArrayLength&#40;enables, INPUT_COUNT&#41;;    FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        enables&#91;inputNum&#93;  &#58;= CreateParam&#40;'enable ' + intToStr&#40;inputNum + 1&#41;,ptSwitch&#41;;         SetValue&#40;enables&#91;inputNum&#93;, 1&#41;;               SetIsOutPut&#40;enables&#91;inputNum&#93;,false&#41;;            END;           octave      &#58;= CreateParam&#40;'octave',ptDataFader&#41;;          SetIsOutPut&#40;octave,false&#41;;    semi        &#58;= CreateParam&#40;'semi',ptDataFader&#41;;            SetIsOutPut&#40;semi,false&#41;;    SetFormat&#40;octave,'%.0f'&#41;; SetMin&#40;octave,-4&#41;;  SetMax&#40;octave,4&#41;;        SetFormat&#40;semi,'%.0f'&#41;;   SetMin&#40;semi,-7&#41;;    SetMax&#40;semi,7&#41;;      hiNote        &#58;= CreateParam&#40;'high note',ptMidiNoteFader&#41;;   SetIsOutPut&#40;hiNote,false&#41;;    lowNote       &#58;= CreateParam&#40;'low note',ptMidiNoteFader&#41;;    SetIsOutPut&#40;lowNote,false&#41;;      outChan       &#58;= CreateParam&#40;'output chan', ptDataFader&#41;;     SetIsOutPut&#40;outchan,false&#41;;     SetFormat&#40;outChan,'%.0f'&#41;; SetMin&#40;outChan,1&#41;;  SetMax&#40;outChan,16&#41;;    SetValue&#40;lowNote, 10&#41;;    SetValue&#40;hiNote, 115&#41;;      drone         &#58;= CreateParam&#40;'drone', ptSwitch&#41;;              SetIsOutput&#40;drone,false&#41;;    instEnable  &#58;= CreateParam&#40;'inst enable', ptSwitch&#41;;          SetIsInput&#40;instEnable,false&#41;;     FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        midiIns&#91;inputNum&#93;  &#58;= CreateParam&#40;'MIDIin ' + intToStr&#40;inputNum + 1&#41; ,ptMidi&#41;;               SetIsOutPut&#40;midiIns&#91;inputNum&#93;,false&#41;;    END;        notesOut      &#58;= CreateParam&#40;'NoteMIDI',ptMidi&#41;;             SetIsInput&#40;notesOut,false&#41;;      otherOut      &#58;= CreateParam&#40;'otherMIDI',ptMidi&#41;;             SetIsInput&#40;otherOut,false&#41;;    learn &#58;= CreateParam&#40;'learn',ptButton&#41;;                       SetIsOutPut&#40;learn,false&#41;;    lower &#58;= CreateParam&#40;'lower',ptMidiNoteFader&#41;;                SetIsInPut&#40;lower,false&#41;;    upper &#58;= CreateParam&#40;'upper',ptMidiNoteFader&#41;;                SetIsInPut&#40;upper,false&#41;;         notesOutCount &#58;= 0;    otherOutCount &#58;= 0;    learnCount    &#58;= 0;    disablable   &#58;= FALSE;    droning       &#58;= FALSE;    release       &#58;= FALSE;       SetArrayLength&#40;isEnabled, INPUT_COUNT&#41;; END;// <F> isNoteOn&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOn&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN       IF &#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2>0&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> isNoteOff&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOff&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN          IF &#40;midi.msg = NOTE_OFF&#41; OR &#40;&#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2 = 0&#41;&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;    END;END; // <F> isSusPed&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isSusPed&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;midi.msg = CONTROL&#41; AND &#40;midi.data1 = SUS_PED&#41; THEN BEGIN        result &#58;= true;    END    ELSE BEGIN        result &#58;= false;    END;END; // <F> isPitchBend&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isPitchBend&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN     IF &#40;midi.msg = PITCHBEND&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> global function inRange--eliminates only noteons outside the range limits FUNCTION inRange&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;isNoteOn&#40;midi&#41;&#41; AND &#40;midi.data1 > lowVal&#41; AND &#40;midi.data1 < hiVal&#41; THEN BEGIN        result &#58;= TRUE;    END    ELSE BEGIN        result &#58;= FALSE;    END; END;// <F> isClear//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//FUNCTION isClear&#40;&#41;  &#58; boolean;   // can we stop this loop as soon as a key = true??  Didn't like 'while'VAR clear &#58; boolean;BEGIN    clear &#58;= TRUE;    BEGIN        FOR key&#58;= minKey TO maxKey DO BEGIN                IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN                 clear &#58;= FALSE;                       END;                                                                  END;     END;    result &#58;= clear;     END;// <F> ReleaseNotes  --when you release the sustain, or release the drone, or change the output channel//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//PROCEDURE ReleaseNotes;BEGIN    FOR key&#58;= minKey TO maxKey DO BEGIN            IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN             noteOff.msg &#58;= NOTE_OFF;            noteOff.channel &#58;= outputChannel; // byte is a conversion--is this needed?            noteOff.data1 &#58;= key;            noteOff.data2 &#58;= 0;            setMidiArrayValue&#40;notesOut, notesOutCount, noteOff&#41;;            strace&#40;'sending noteOff for ' + intToStr&#40;key&#41;&#41;;            notesOutCount &#58;= notesOutCount + 1;            noteList&#91;key&#93; &#58;= FALSE;        END;                                                              END; END;    // Global Procedure StoreNoteOffs--just de-inlined for readability//----------------------------------------------//PROCEDURE StoreNoteOffs;BEGIN    IF &#40;midi.data1 > maxKey&#41; THEN BEGIN           maxKey &#58;= midi.data1;    END;    IF &#40;midi.data1 < minKey&#41; THEN BEGIN         minKey &#58;= midi.data1;     END;     noteList&#91;midi.data1&#93; &#58;= TRUE;END;// Callback//----------------------------------------------// procedure Callback&#40;n&#58;integer&#41;;BEGIN    if &#40;n = hiNote&#41; then begin         hiVal &#58;= round&#40;getValue&#40;hiNote&#41;&#41;;         setValue&#40;upper, hiVal&#41;;    end    else if &#40;n = lowNote&#41; then begin         lowVal &#58;= round&#40;getValue&#40;lowNote&#41;&#41;;         setValue&#40;lower, lowVal&#41;;    end    else if &#40;n = learn&#41; and &#40;getValue&#40;n&#41; = 1&#41; then begin         learning&#58;= TRUE;        strace&#40;'learning...'&#41;;         learnCount &#58;= 0;    end    else if &#40;learnCount = 2&#41; then begin        // we've just learned, so we want to send out lower and upper          learning &#58;= FALSE;        learnCount &#58;= 0;        strace&#40;' finishedlearning'&#41;;    end     else begin        // get input values            octVal &#58;= trunc&#40;getValue&#40;octave&#41;&#41;;        semival &#58;= trunc&#40;getValue&#40;semi&#41;&#41;;        transpose &#58;= &#40;octVal * 12&#41; + semiVal;        outputChannel &#58;= trunc&#40;getValue&#40;outChan&#41;&#41;;        droning &#58;= &#40;getValue&#40;drone&#41; = 1&#41;;        // see if any input is enabled....        noInput &#58;= TRUE;                                                 FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO         BEGIN            IF getValue&#40;enables&#91;inputNum&#93;&#41; = 1 THEN BEGIN                isEnabled&#91;inputNum&#93; &#58;= TRUE;                 noInput &#58;= FALSE;            END            ELSE BEGIN                isEnabled&#91;inputNum&#93; &#58;= FALSE;            END;        END;                  // release notes if the drone has just been turned off, or if all inputs and notes are off, or if the channel is changed              IF &#40;&#40;n = drone&#41; and &#40;not&#40;Droning&#41;&#41;&#41; OR            &#40;&#40;noInput = TRUE&#41; AND &#40;isClear&#40;&#41; = TRUE&#41;&#41;           OR &#40;n = outChan&#41;                        THEN BEGIN            strace&#40;'releasing notes'&#41;;            release &#58;= true;               // booleans to check in process            disablable &#58;= true;        END        ELSE BEGIN            setValue&#40;instEnable, 1&#41;;        END;    end;END;  //////////////////////////////////////////////////////// process//////////////////////////////////////////////////////PROCEDURE PROCESS;BEGIN     notesOutCount &#58;= 0;    otherOutCount &#58;= 0;       if release then releaseNotes;    FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO BEGIN                    midiInCount &#58;= getLength&#40;midiIns&#91;inputNum&#93;&#41;;                               FOR byteNum &#58;= 0 TO &#40;midiInCount - 1&#41; DO BEGIN   // process input                                       getMidiArrayValue&#40;midiIns&#91;inputNum&#93;, byteNum, midi&#41;;            midi.channel &#58;= outputChannel;            if &#40;learning&#41; then begin                IF &#40;isNoteOn&#40;midi&#41;&#41; and &#40;learnCount = 0&#41; THEN BEGIN                    lowVal &#58;= midi.data1;                    setValue&#40;lower, lowVal &#41;;                    learnCount &#58;= 1;                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                     strace&#40;'learnCount = ' + intToStr&#40;learnCount&#41;&#41;;                                                 END                 ELSE IF &#40;isNoteOn&#40;midi&#41;&#41; and &#40;learnCount = 1&#41;  THEN BEGIN                    hiVal &#58;= midi.data1;                    setValue&#40;upper, hiVal&#41;;                    learnCount &#58;= 2;                    learning &#58;= FALSE;  // we've set our outs....                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;            end             else if &#40;droning&#41; then begin  // basically ignore all midi when droning                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;            end            else begin                If isSusPed&#40;midi&#41; THEN BEGIN                              if &#40;midi.data2 > 64&#41; THEN BEGIN                        isSustained &#58;= true;                    END                    ELSE BEGIN                                                 isSustained &#58;= false;                          ReleaseNotes;          // send noteoffs when the sus pedal is released                    END;                                              END;                 IF isNoteOn&#40;midi&#41; AND &#40;inRange&#40;midi&#41;&#41; AND &#40;isEnabled&#91;inputNum&#93;&#41; THEN BEGIN //note on, sus on, store and send                    transList&#91;midi.data1&#93; &#58;= transpose;                     midi.data1 &#58;= midi.data1 + transpose;                     IF &#40;isSustained = TRUE&#41; THEN BEGIN                                   StoreNoteOffs;                                      setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                    END                                          ELSE BEGIN                                        // valid noteon, sus off, send it out                                       setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                     END;                END                ELSE IF isNoteOff&#40;midi&#41; AND &#40;isSustained = FALSE&#41;  THEN BEGIN // valid noteoff, sus off, send it out                        midi.data1 &#58;= midi.data1 + transList&#91;midi.data1&#93;;                                         setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                                 END                                     ELSE IF isPitchBend&#40;midi&#41; THEN BEGIN                        // send PB along with the notes                                                 midi.channel &#58;= outputChannel;                                    setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                    notesOutCount &#58;= notesOutCount + 1;                END                ELSE IF &#40;NOT&#40;isNoteOn&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isNoteOff&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isPitchBend&#40;midi&#41;&#41;&#41; THEN BEGIN  //not a note, pb or sus pedal event                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;                               end;        END;    END;    setLength&#40;notesOut, notesOutCount&#41;;    setLength&#40;otherOut, otherOutCount&#41;;    if disablable then setValue&#40;instEnable, 0&#41;; END;

Statistics: Posted by woodslanding — 10 Jan 2010, 11:32


]]>
2010-01-10T12:18:49+02:00 2010-01-10T12:18:49+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=11194#p11194 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
And I finally got around to checking the drone out, and it actually works. Sort of. Problem is, the noteOffs are not going out the output, even though my strace shows the code is getting called with correct values. So I'm wondering if this is somehow related to the problems above.

I tried moving the noteOut count resetting to the beginning of process, but that just gave me a bunch of stuck notes.

So thanks for any tips. This is pretty close to working!

CODE:

&#40;*/////////////////////////////////////////////////////// CHANNEL  // Version 2009-11-21; author&#58; eric moon//// based on work by Bsork and amiga909//////////////////////////////////////////////////////*&#41;//  This takes a number of midi inputs &#40;on separate cables, for visual clarity&#41;//  and performs the following operations on each.//  enable, disable--per input//  strip CCs and AT and send them out a separate output//  read CC64 values &#40;or a CC of your choice&#41; to withhold noteoffs until the sus pedal is released.//  limit to minimum and maximum notes--one range affects all inputs, as it's assumed you'll typically be using one input at a time//  transpose--again, one range for all inputs.//  output rechannelizing--all outs are a single channel.  Use multiple strips to control multi-timbral modules.//  bypass output for turning off unused instruments.  waits for all notes to be released....//  drone switch that keeps current notes sounding, but discards new notesOns as long as it is held//  It is designed to function as part of a mixer channel strip, running between several keyboards and a vsti.//  When the 'learn' function is enabled, notes are sent out output 2//  the first note sets the lower range, the second note sets the upper limit.//  when both notes are sent, learn is disabled, and notes go to output 1 as usual.CONST SUS_PED= 64;    //change if you use an unorthodox CC for sustaining.CONST INPUT_COUNT = 2;  //allows up to 16 inputs, one per channelCONST NOTE_ON        = 144;CONST NOTE_OFF       = 128;CONST CONTROL        = 176;CONST PITCHBEND      = 224;VAR   noteList                              &#58; ARRAY OF boolean;VAR   transList                             &#58; ARRAY OF integer;VAR   midi,noteOff                          &#58; TMidi; var midiIns                                 &#58;  ARRAY OF Tparameter;var enables                                 &#58;  ARRAY OF TParameter;var notesOut  &#58; Tparameter;var otherOut  &#58; Tparameter;       // all CCs except the sustain value go out this output.  So does AT and PgChvar octave    &#58; TParameter;var semi      &#58; TParameter;var hiNote    &#58; TParameter;var lowNote   &#58; TParameter;var drone     &#58; TParameter;       // sustains, but ignores new noteonsvar outChan   &#58; TParameter;       // everything goes out one channel.  It's a channel strip. Use more if you need other channels!var instEnable&#58; TParameter;var lower    &#58; Tparameter;var upper   &#58; Tparameter; var learn     &#58; TParameter;VAR   octVal, semiVal, transpose            &#58; integer;VAR   hiVal, lowVal                         &#58; integer; VAR   midiInCount                           &#58; integer;VAR   otherOutCount, notesOutCount          &#58; integer;VAR   key, inputNum, byteNum                &#58; integer; VAR   minChn, maxChn, minKey, maxKey        &#58; integer;VAR   outputChannel                         &#58; integer;VAR   isSustained,noInput                   &#58; boolean;VAR   isEnabled                             &#58; Array of boolean;VAR   learning                              &#58; boolean;VAR   droning                               &#58; boolean;var   learnCount                            &#58; integer;//////////////////////////////////////////////////////// initialize//////////////////////////////////////////////////////PROCEDURE init;    BEGIN      minChn &#58;= INPUT_COUNT - 1;   // these are initially set to their opposite extremes....    maxChn &#58;= 0;     minKey &#58;= 128;     maxKey &#58;= 0;        isSustained &#58;= FALSE;              setArrayLength&#40;noteList, 128&#41;;      FOR key&#58;=0 TO 127 DO BEGIN         noteList&#91;key&#93;&#58;=FALSE;    END;    SetArrayLength&#40;transList, 128&#41;;    FOR key&#58;=0 TO 127 DO BEGIN         transList&#91;key&#93;&#58;=0;    END;           setArrayLength&#40;midiIns, INPUT_COUNT&#41;;    setArrayLength&#40;enables, INPUT_COUNT&#41;;    FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        enables&#91;inputNum&#93;  &#58;= CreateParam&#40;'enable ' + intToStr&#40;inputNum + 1&#41;,ptSwitch&#41;;         SetValue&#40;enables&#91;inputNum&#93;, 1&#41;;               SetIsOutPut&#40;enables&#91;inputNum&#93;,false&#41;;            END;           octave      &#58;= CreateParam&#40;'octave',ptDataFader&#41;;          SetIsOutPut&#40;octave,false&#41;;    semi        &#58;= CreateParam&#40;'semi',ptDataFader&#41;;            SetIsOutPut&#40;semi,false&#41;;    SetFormat&#40;octave,'%.0f'&#41;; SetMin&#40;octave,-4&#41;;  SetMax&#40;octave,4&#41;;        SetFormat&#40;semi,'%.0f'&#41;;   SetMin&#40;semi,-7&#41;;    SetMax&#40;semi,7&#41;;      hiNote        &#58;= CreateParam&#40;'high note',ptMidiNoteFader&#41;;   SetIsOutPut&#40;hiNote,false&#41;;    lowNote       &#58;= CreateParam&#40;'low note',ptMidiNoteFader&#41;;    SetIsOutPut&#40;lowNote,false&#41;;      outChan       &#58;= CreateParam&#40;'output chan', ptDataFader&#41;;     SetIsOutPut&#40;outchan,false&#41;;     SetFormat&#40;outChan,'%.0f'&#41;; SetMin&#40;outChan,1&#41;;  SetMax&#40;outChan,16&#41;;    SetValue&#40;lowNote, 10&#41;;    SetValue&#40;hiNote, 115&#41;;      drone         &#58;= CreateParam&#40;'drone', ptSwitch&#41;;              SetIsOutput&#40;drone,false&#41;;    instEnable  &#58;= CreateParam&#40;'inst enable', ptSwitch&#41;;          SetIsInput&#40;instEnable,false&#41;;     FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        midiIns&#91;inputNum&#93;  &#58;= CreateParam&#40;'MIDIin ' + intToStr&#40;inputNum + 1&#41; ,ptMidi&#41;;               SetIsOutPut&#40;midiIns&#91;inputNum&#93;,false&#41;;    END;        notesOut      &#58;= CreateParam&#40;'NoteMIDI',ptMidi&#41;;             SetIsInput&#40;notesOut,false&#41;;      otherOut      &#58;= CreateParam&#40;'otherMIDI',ptMidi&#41;;             SetIsInput&#40;otherOut,false&#41;;    learn &#58;= CreateParam&#40;'learn',ptButton&#41;;                       SetIsOutPut&#40;learn,false&#41;;    lower &#58;= CreateParam&#40;'lower',ptMidiNoteFader&#41;;                SetIsInPut&#40;lower,false&#41;;    upper &#58;= CreateParam&#40;'upper',ptMidiNoteFader&#41;;                SetIsInPut&#40;upper,false&#41;;         notesOutCount &#58;= 0;    otherOutCount &#58;= 0;    learnCount    &#58;= 0;       SetArrayLength&#40;isEnabled, INPUT_COUNT&#41;; END;// <F> isNoteOn&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOn&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN       IF &#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2>0&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> isNoteOff&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOff&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN          IF &#40;midi.msg = NOTE_OFF&#41; OR &#40;&#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2 = 0&#41;&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;    END;END; // <F> isSusPed&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isSusPed&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;midi.msg = CONTROL&#41; AND &#40;midi.data1 = SUS_PED&#41; THEN BEGIN        result &#58;= true;    END    ELSE BEGIN        result &#58;= false;    END;END; // <F> isPitchBend&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isPitchBend&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN     IF &#40;midi.msg = PITCHBEND&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> global function inRange--eliminates only noteons outside the range limits FUNCTION inRange&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;isNoteOn&#40;midi&#41;&#41; AND &#40;midi.data1 > lowVal&#41; AND &#40;midi.data1 < hiVal&#41; THEN BEGIN        result &#58;= TRUE;    END    ELSE BEGIN        result &#58;= FALSE;    END; END;// <F> isClear//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//FUNCTION isClear&#40;&#41;  &#58; boolean;   // can we stop this loop as soon as a key = true??  Didn't like 'while'VAR clear &#58; boolean;BEGIN    clear &#58;= TRUE;    BEGIN        FOR key&#58;= minKey TO maxKey DO BEGIN                IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN                 clear &#58;= FALSE;                       END;                                                                  END;     END;    result &#58;= clear;     END;// <F> ReleaseNotes  --when you release the sustain, or release the drone, or change the output channel//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//PROCEDURE ReleaseNotes;BEGIN    FOR key&#58;= minKey TO maxKey DO BEGIN            IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN             noteOff.msg &#58;= NOTE_OFF;            noteOff.channel &#58;= outputChannel; // byte is a conversion--is this needed?            noteOff.data1 &#58;= key;            noteOff.data2 &#58;= 0;            setMidiArrayValue&#40;notesOut, notesOutCount, noteOff&#41;;strace&#40;'sending noteOff for ' + intToStr&#40;key&#41;&#41;;            notesOutCount &#58;= notesOutCount + 1;            noteList&#91;key&#93; &#58;= FALSE;        END;                                                              END; END;    // Global Procedure StoreNoteOffs--just de-inlined for readability//----------------------------------------------//PROCEDURE StoreNoteOffs;BEGIN    IF &#40;midi.data1 > maxKey&#41; THEN BEGIN           maxKey &#58;= midi.data1;    END;    IF &#40;midi.data1 < minKey&#41; THEN BEGIN         minKey &#58;= midi.data1;     END;     noteList&#91;midi.data1&#93; &#58;= TRUE;END;// Callback//----------------------------------------------// procedure Callback&#40;n&#58;integer&#41;;BEGIN    if &#40;n = hiNote&#41; then begin         hiVal &#58;= round&#40;getValue&#40;hiNote&#41;&#41;;         setValue&#40;upper, hiVal&#41;;    end    else if &#40;n = lowNote&#41; then begin         lowVal &#58;= round&#40;getValue&#40;lowNote&#41;&#41;;         setValue&#40;lower, lowVal&#41;;    end    else if &#40;n = learn&#41; and &#40;getValue&#40;n&#41; = 1&#41; then begin         learning&#58;= TRUE;        strace&#40;'learning...'&#41;;         learnCount &#58;= 0;    end    else if &#40;learnCount = 2&#41; then begin         learning &#58;= FALSE;        learnCount &#58;= 0;        strace&#40;' finishedlearning'&#41;;    end     else begin        // get input values            octVal &#58;= trunc&#40;getValue&#40;octave&#41;&#41;;        semival &#58;= trunc&#40;getValue&#40;semi&#41;&#41;;        transpose &#58;= &#40;octVal * 12&#41; + semiVal;        outputChannel &#58;= trunc&#40;getValue&#40;outChan&#41;&#41;;        droning &#58;= &#40;getValue&#40;drone&#41; = 1&#41;;        // see if any input is enabled....        noInput &#58;= TRUE;                                                 FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO         BEGIN            IF getValue&#40;enables&#91;inputNum&#93;&#41; = 1 THEN BEGIN                isEnabled&#91;inputNum&#93; &#58;= TRUE;                 noInput &#58;= FALSE;            END            ELSE BEGIN                isEnabled&#91;inputNum&#93; &#58;= FALSE;            END;        END;                  // release notes if the drone has just been turned off, or if all inputs and notes are off, or if the channel is changed              IF &#40;&#40;n = drone&#41; and &#40;not&#40;Droning&#41;&#41;&#41; OR            &#40;&#40;noInput = TRUE&#41; AND &#40;isClear&#40;&#41; = TRUE&#41;&#41;           OR &#40;n = outChan&#41;                        THEN BEGIN            strace&#40;'releasing notes'&#41;;            releaseNotes;               setValue&#40;instEnable, 0&#41;;        END        ELSE BEGIN            setValue&#40;instEnable, 1&#41;;        END;    end;END;  //////////////////////////////////////////////////////// process//////////////////////////////////////////////////////PROCEDURE PROCESS;BEGIN     notesOutCount &#58;= 0;    otherOutCount &#58;= 0;           FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO BEGIN                    midiInCount &#58;= getLength&#40;midiIns&#91;inputNum&#93;&#41;;                               FOR byteNum &#58;= 0 TO &#40;midiInCount - 1&#41; DO BEGIN   // process input                                       getMidiArrayValue&#40;midiIns&#91;inputNum&#93;, byteNum, midi&#41;;            midi.channel &#58;= outputChannel;            if &#40;learning&#41; then begin                IF &#40;isNoteOn&#40;midi&#41;&#41; and &#40;learnCount = 0&#41; THEN BEGIN                    lowVal &#58;= midi.data1;                    setValue&#40;lower, lowVal &#41;;                    learnCount &#58;= 1;                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                     strace&#40;'learnCount = ' + intToStr&#40;learnCount&#41;&#41;;                                                 END                 ELSE IF &#40;isNoteOn&#40;midi&#41;&#41; and &#40;learnCount = 1&#41;  THEN BEGIN                    hiVal &#58;= midi.data1;                    setValue&#40;upper, hiVal&#41;;                    learnCount &#58;= 2;                    learning &#58;= FALSE;  // we've set our outs....                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;            end             else if &#40;droning&#41; then begin  // basically ignore all midi when droning                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;            end            else begin                If isSusPed&#40;midi&#41; THEN BEGIN                              if &#40;midi.data2 > 64&#41; THEN BEGIN                        isSustained &#58;= true;                    END                    ELSE BEGIN                                                 isSustained &#58;= false;                          ReleaseNotes;          // send noteoffs when the sus pedal is released                    END;                                              END;                 IF isNoteOn&#40;midi&#41; AND &#40;inRange&#40;midi&#41;&#41; AND &#40;isEnabled&#91;inputNum&#93;&#41; THEN BEGIN //note on, sus on, store and send                    transList&#91;midi.data1&#93; &#58;= transpose;                     midi.data1 &#58;= midi.data1 + transpose;                     IF &#40;isSustained = TRUE&#41; THEN BEGIN                                   StoreNoteOffs;                                      setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                    END                                          ELSE BEGIN                                        // valid noteon, sus off, send it out                                       setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                     END;                END                ELSE IF isNoteOff&#40;midi&#41; AND &#40;isSustained = FALSE&#41;  THEN BEGIN // valid noteoff, sus off, send it out                        midi.data1 &#58;= midi.data1 + transList&#91;midi.data1&#93;;                                         setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                                 END                                     ELSE IF isPitchBend&#40;midi&#41; THEN BEGIN                        // send PB along with the notes                                                 midi.channel &#58;= outputChannel;                                    setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                    notesOutCount &#58;= notesOutCount + 1;                END                ELSE IF &#40;NOT&#40;isNoteOn&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isNoteOff&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isPitchBend&#40;midi&#41;&#41;&#41; THEN BEGIN  //not a note, pb or sus pedal event                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;                               end;        END;    END;    setLength&#40;notesOut, notesOutCount&#41;;    setLength&#40;otherOut, otherOutCount&#41;; END;

Statistics: Posted by woodslanding — 10 Jan 2010, 11:18


]]>
2009-12-04T17:15:54+02:00 2009-12-04T17:15:54+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10855#p10855 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
I will try to implement stuff like this, but the more straight-forward stuff like filtering, transposition, rerouting and value scaling will have the priority.

Statistics: Posted by bsork — 04 Dec 2009, 16:15


]]>
2009-12-04T04:17:34+02:00 2009-12-04T04:17:34+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10849#p10849 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Definately more tools like this are needed in Usine!

Statistics: Posted by gurulogic — 04 Dec 2009, 03:17


]]>
2009-12-03T22:44:29+02:00 2009-12-03T22:44:29+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10842#p10842 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>

There are some things that MungRack do that I have no plans of implementing, but there are also stuff that I - from reading the docs - don't think it will do; like the sustain/sustenotu/hold stuff mentioned before in this topic. I will also try to do my best to avoid hanging notes, even when changing channel/note range/transpose/output parameters when notes are sounding.

Just to recap a little; what I'm working on is a patch with a script to handle various filters and transformers, and I also plan to create smaller, single function version patches with most, if not all, the transformers etc.

Still got a lot of work to do, I'm afraid...

Statistics: Posted by bsork — 03 Dec 2009, 21:44


]]>
2009-12-03T20:19:31+02:00 2009-12-03T20:19:31+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10839#p10839 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> http://www.asseca.com/nicfit/mungrack.html

Statistics: Posted by gurulogic — 03 Dec 2009, 19:19


]]>
2009-11-27T06:56:34+02:00 2009-11-27T06:56:34+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10781#p10781 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by woodslanding — 27 Nov 2009, 05:56


]]>
2009-11-26T22:11:32+02:00 2009-11-26T22:11:32+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10776#p10776 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by bsork — 26 Nov 2009, 21:11


]]>
2009-11-26T21:46:12+02:00 2009-11-26T21:46:12+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10772#p10772 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
Sostenuto is clever--I've never seen that in the midi world!

Statistics: Posted by woodslanding — 26 Nov 2009, 20:46


]]>
2009-11-26T12:50:40+02:00 2009-11-26T12:50:40+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10769#p10769 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
You still have to move the 'notesOutCount := 0; otherOutCount := 0;' down below where you set the lengths though, as you're calling releaseNotes from Callback. Remember that Callback is executed once for each change in an input parameter before Process is called, so what happens when drone is turned off you first fill the outputs in releaseNotes, then in Process the counters are zeroed which means that the data from Callback->releaseNotes is never sent.

BTW, I'm thinking of implementing these varieties of sustain within the script I'm working on:
Sustain: Like your script (without drone); delays NoteOffs until sustain is deactivated.
Sustenuto: Delays NoteOffs only for notes held when activating sustain.
Hold: Like amiga909's script; accumulates notes until all have been released, and send NoteOffs when a new NoteOn is received or sustain is deactivated.
There will also be a trigger/button input to send all missing NoteOffs + CC123/AllNotesOff.

Statistics: Posted by bsork — 26 Nov 2009, 11:50


]]>
2009-11-26T11:28:00+02:00 2009-11-26T11:28:00+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10765#p10765 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
Wow, just looked at the code, and in reality it would be 'for i = 0 to -1'

doesn't sound like a good thing, but it's not crashing the script.... but I guess the important thing is that I can bypass the FOR loop without specifically setting the output array length to zero--if it startes out at size zero, and nothing is added to it, it's still size zero.

Any clues why my transpose value isn't tracking? What I'm doing in callback() seems very simple and straighforward. It is the only place the value of transpose is changed......

Oh--maybe I need to be getting parameters in the process loop, ala your earlier suggestion!! I will try that.

thanks!
-e

Statistics: Posted by woodslanding — 26 Nov 2009, 10:28


]]>
2009-11-26T10:41:25+02:00 2009-11-26T10:41:25+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10764#p10764 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
I took the test for midLength > 0 out. Why was that in there?? It doesn't seem like it saves a step. If the length is zero, it's just not going to run the for loop anyway, right?? or was the script engine not able to handle 'for i = 0 to 0' correctly before?
Beware that FOR i := 0 TO 0 will execute the loop once! So you should either check length 0 with an IF before the loop, or use a WHILE loop. Something like:

CODE:

 i &#58;= 0;WHILE i < cnt DO BEGIN   do_something...   i &#58;= i + 1;END;

Statistics: Posted by bsork — 26 Nov 2009, 09:41


]]>
2009-11-26T09:56:25+02:00 2009-11-26T09:56:25+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10763#p10763 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
about the hanging-note thing:
there actually is a vst series that takes care of it:
"•most plugins include a sort of hanging-note-protection system (where applicable) to enable making changes during playback (e.g. when a MIDI thru option is toggled) without the risk of not releasing notes which are played at the same time the changes happen "

about a sustain effect:
S-CC-Sustain-Lite
http://www.s-production.de/
haven't tested it but i dont think a usine script would be much more effective.
Missed this the first time. I'm going to check it out. Looks like good stuff, and if it's programmed in C, should be fast.

Thanks!
-e

Statistics: Posted by woodslanding — 26 Nov 2009, 08:56


]]>
2009-11-26T09:26:56+02:00 2009-11-26T09:26:56+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10760#p10760 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
So it's functioning, and the sustain pedal is sustaining, but I am getting stuck notes, so I'll have to think carefully about the code. Also, my code as it stands seems to not always update transpose correctly. Sometimes the writeln test value changes, but the note out doesn't, and other times neither is synched up with the values on the sliders.

nevertheless it is an encouraging start.

cheers!
-eric

The code as it stands:

CODE:

&#40;*/////////////////////////////////////////////////////// CHANNEL  // Version 2009-11-21; author&#58; eric moon//// based on work by Bsork and amiga909//////////////////////////////////////////////////////*&#41;//  This takes a number of midi inputs &#40;on separate cables, for visual clarity&#41;//  and performs the following operations on each.//  enable, disable--per input//  strip CCs and AT and send them out a separate output//  read CC64 values &#40;or a CC of your choice&#41; to withhold noteoffs until the sus pedal is released.//  limit to minimum and maximum notes--one range affects all inputs, as it's assumed you'll typically be using one input at a time//  transpose--again, one range for all inputs.//  output rechannelizing--all outs are a single channel.  Use multiple strips to control multi-timbral modules.//  bypass output for turning off unused instruments.  waits for all notes to be released....//  drone switch that keeps current notes sounding, but discards new notesOns as long as it is held//  It is designed to function as part of a mixer channel strip, running between several keyboards and a vsti.CONST SUS_PED= 64;    //change if you use an unorthodox CC for sustaining.CONST INPUT_COUNT = 2;  //allows up to 16 inputs, one per channelCONST NOTE_ON        = 144;CONST NOTE_OFF       = 128;CONST CONTROL        = 176;CONST PITCHBEND      = 224;VAR   noteList                              &#58; ARRAY OF boolean;VAR   transList                             &#58; ARRAY OF integer;VAR   midi,noteOff                          &#58; TMidi; var midiIns                                 &#58;  ARRAY OF Tparameter;var enables                                 &#58;  ARRAY OF TParameter;var notesOut  &#58; Tparameter;var otherOut  &#58; Tparameter;       // all CCs except the sustain value go out this output.  So does AT and PgChvar octave    &#58; TParameter;var semi      &#58; TParameter;var hiNote    &#58; TParameter;var lowNote   &#58; TParameter;var drone     &#58; TParameter;       // sustains, but ignores new noteonsvar outChan   &#58; TParameter;       // everything goes out one channel.  It's a channel strip. Use more if you need other channels!var instBypass&#58; TParameter; VAR   octVal, semiVal, transpose            &#58; integer;VAR   hiVal, lowVal                         &#58; integer; VAR   midiInCount                           &#58; integer;VAR   otherOutCount, notesOutCount          &#58; integer;VAR   key, inputNum, byteNum                &#58; integer; VAR   minChn, maxChn, minKey, maxKey        &#58; integer;VAR   outputChannel                         &#58; integer;VAR   isSustained,noInput                   &#58; boolean;VAR   isEnabled                             &#58; Array of boolean;//////////////////////////////////////////////////////// initialize//////////////////////////////////////////////////////PROCEDURE init;    BEGIN      minChn &#58;= INPUT_COUNT - 1;   // these are initially set to their opposite extremes....    maxChn &#58;= 0;     minKey &#58;= 128;     maxKey &#58;= 0;        isSustained &#58;= FALSE;              setArrayLength&#40;noteList, 128&#41;;      FOR key&#58;=0 TO 127 DO BEGIN         noteList&#91;key&#93;&#58;=FALSE;    END;    SetArrayLength&#40;transList, 128&#41;;    FOR key&#58;=0 TO 127 DO BEGIN         transList&#91;key&#93;&#58;=0;    END;           setArrayLength&#40;midiIns, INPUT_COUNT&#41;;    setArrayLength&#40;enables, INPUT_COUNT&#41;;    FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        enables&#91;inputNum&#93;  &#58;= CreateParam&#40;'enable ' + intToStr&#40;inputNum + 1&#41;,ptSwitch&#41;;         SetValue&#40;enables&#91;inputNum&#93;, 1&#41;;               SetIsOutPut&#40;enables&#91;inputNum&#93;,false&#41;;            END;           octave      &#58;= CreateParam&#40;'octave',ptDataFader&#41;;          SetIsOutPut&#40;octave,false&#41;;    semi        &#58;= CreateParam&#40;'semi',ptDataFader&#41;;            SetIsOutPut&#40;semi,false&#41;;    SetFormat&#40;octave,'%.0f'&#41;; SetMin&#40;octave,-4&#41;;  SetMax&#40;octave,4&#41;;        SetFormat&#40;semi,'%.0f'&#41;;   SetMin&#40;semi,-7&#41;;    SetMax&#40;semi,7&#41;;      hiNote        &#58;= CreateParam&#40;'high note',ptMidiNoteFader&#41;;   SetIsOutPut&#40;hiNote,false&#41;;    lowNote       &#58;= CreateParam&#40;'low note',ptMidiNoteFader&#41;;    SetIsOutPut&#40;lowNote,false&#41;;      outChan       &#58;= CreateParam&#40;'output chan', ptDataFader&#41;;     SetIsOutPut&#40;outchan,false&#41;;     SetFormat&#40;outChan,'%.0f'&#41;; SetMin&#40;outChan,1&#41;;  SetMax&#40;outChan,16&#41;;    SetValue&#40;lowNote, 10&#41;;    SetValue&#40;hiNote, 115&#41;;      drone         &#58;= CreateParam&#40;'drone', ptSwitch&#41;;              SetIsOutput&#40;drone,false&#41;;    instBypass  &#58;= CreateParam&#40;'inst bypass', ptSwitch&#41;;       SetIsInput&#40;instBypass,false&#41;;      FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        midiIns&#91;inputNum&#93;  &#58;= CreateParam&#40;'MIDIin ' + intToStr&#40;inputNum + 1&#41; ,ptMidi&#41;;               SetIsOutPut&#40;midiIns&#91;inputNum&#93;,false&#41;;    END;        notesOut      &#58;= CreateParam&#40;'Notes Out',ptMidi&#41;;             SetIsInput&#40;notesOut,false&#41;;      otherOut      &#58;= CreateParam&#40;'other Out',ptMidi&#41;;             SetIsInput&#40;otherOut,false&#41;;      notesOutCount &#58;= 0;    otherOutCount &#58;= 0;       SetArrayLength&#40;isEnabled, INPUT_COUNT&#41;; END;// <F> isNoteOn&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOn&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN       IF &#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2>0&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> isNoteOff&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOff&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN          IF &#40;midi.msg = NOTE_OFF&#41; OR &#40;&#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2 = 0&#41;&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;    END;END; // <F> isSusPed&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isSusPed&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;midi.msg = CONTROL&#41; AND &#40;midi.data1 = SUS_PED&#41; THEN BEGIN        result &#58;= true;    END    ELSE BEGIN        result &#58;= false;    END;END; // <F> isPitchBend&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isPitchBend&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN     IF &#40;midi.msg = PITCHBEND&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> global function inRange--eliminates only noteons outside the range limits FUNCTION inRange&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;isNoteOn&#40;midi&#41;&#41; AND &#40;midi.data1 > lowVal&#41; AND &#40;midi.data1 < hiVal&#41; THEN BEGIN        result &#58;= TRUE;    END    ELSE BEGIN        result &#58;= FALSE;    END; END;// <F> isClear//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//FUNCTION isClear&#40;&#41;  &#58; boolean;   // can we stop this loop as soon as a key = true??  Didn't like 'while'VAR clear &#58; boolean;BEGIN    clear &#58;= TRUE;    BEGIN        FOR key&#58;= minKey TO maxKey DO BEGIN                IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN                 clear &#58;= FALSE;                       END;                                                                  END;     END;    result &#58;= clear;     END;// <F> ReleaseNotes  --when you release the sustain, or release the drone, or change the output channel//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//PROCEDURE ReleaseNotes;BEGIN    FOR key&#58;= minKey TO maxKey DO BEGIN            IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN             noteOff.msg &#58;= NOTE_OFF;            noteOff.channel &#58;= outputChannel; // byte is a conversion--is this needed?            noteOff.data1 &#58;= key;            noteOff.data2 &#58;= 0;            setMidiArrayValue&#40;notesOut, notesOutCount, noteOff&#41;;  //danger when called from callback?            notesOutCount &#58;= notesOutCount + 1;            noteList&#91;key&#93; &#58;= FALSE;        END;                                                              END; END;    // Global Procedure StoreNoteOffs--just de-inlined for readability//----------------------------------------------//PROCEDURE StoreNoteOffs;BEGIN    IF &#40;midi.data1 > maxKey&#41; THEN BEGIN           maxKey &#58;= midi.data1;    END;    IF &#40;midi.data1 < minKey&#41; THEN BEGIN         minKey &#58;= midi.data1;     END;     noteList&#91;midi.data1&#93; &#58;= TRUE;END;// Callback//----------------------------------------------// procedure Callback&#40;n&#58;integer&#41;;BEGIN    // get input values        hiVal &#58;= trunc&#40;getValue&#40;hiNote&#41;&#41;;    lowVal &#58;= trunc&#40;getValue&#40;lowNote&#41;&#41;;    octVal &#58;= trunc&#40;getValue&#40;octave&#41;&#41;;    semival &#58;= trunc&#40;getValue&#40;semi&#41;&#41;;    transpose &#58;= &#40;octVal * 12&#41; + semiVal;writeln&#40;'transpose = ' + intToStr&#40;transpose&#41;&#41;;    outputChannel &#58;= trunc&#40;getValue&#40;outChan&#41;&#41;;    // see if any input is enabled....    noInput &#58;= TRUE;                                             FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO     BEGIN        IF getValue&#40;enables&#91;inputNum&#93;&#41; = 1 THEN BEGIN            isEnabled&#91;inputNum&#93; &#58;= TRUE;             noInput &#58;= FALSE;        END        ELSE BEGIN            isEnabled&#91;inputNum&#93; &#58;= FALSE;        END;    END;          // release notes if the drone has just been turned off, or if all inputs and notes are off, or if the channel is changed    IF &#40;&#40;n = drone&#41; and &#40;getValue&#40;drone&#41; = 0&#41;&#41; OR        &#40;&#40;noInput = TRUE&#41; AND &#40;isClear&#40;&#41; = TRUE&#41;&#41;       OR &#40;n = outChan&#41;                    THEN     BEGIN        releaseNotes;               // can I call this from callback?        setValue&#40;instBypass, 1&#41;;    END    ELSE BEGIN        setValue&#40;instBypass, 0&#41;;    END;END;  //////////////////////////////////////////////////////// process//////////////////////////////////////////////////////PROCEDURE PROCESS;BEGIN     notesOutCount &#58;= 0;    otherOutCount &#58;= 0;    FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO BEGIN                    midiInCount &#58;= getLength&#40;midiIns&#91;inputNum&#93;&#41;;               FOR byteNum &#58;= 0 TO &#40;midiInCount - 1&#41; DO BEGIN   // process input                                       getMidiArrayValue&#40;midiIns&#91;inputNum&#93;, byteNum, midi&#41;;                midi.channel &#58;= outputChannel;                 If isSusPed&#40;midi&#41; THEN BEGIN                              if &#40;midi.data2 > 64&#41; THEN BEGIN                        isSustained &#58;= true;                    END                    ELSE BEGIN                                                 isSustained &#58;= false;                          ReleaseNotes;          // send noteoffs when the sus pedal is released                    END;                                              END;                 IF isNoteOn&#40;midi&#41; AND &#40;inRange&#40;midi&#41;&#41; AND &#40;isEnabled&#91;inputNum&#93;&#41; THEN BEGIN //note on, sus on, store and send                    transList&#91;midi.data1&#93; &#58;= transpose;                     midi.data1 &#58;= midi.data1 + transpose;                     IF &#40;isSustained = TRUE&#41; THEN BEGIN                                   StoreNoteOffs;                                      setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                    END                                          ELSE BEGIN                                        // valid noteon, sus off, send it out                                       setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                     END;                END                ELSE IF isNoteOff&#40;midi&#41; AND &#40;isSustained = FALSE&#41;  THEN BEGIN // valid noteoff, sus off, send it out                        midi.data1 &#58;= midi.data1 + transList&#91;midi.data1&#93;;                                         setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                                 END                                     ELSE IF isPitchBend&#40;midi&#41; THEN BEGIN                        // send PB along with the notes                                                 midi.channel &#58;= outputChannel;                                    setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                    notesOutCount &#58;= notesOutCount + 1;                END                ELSE IF &#40;NOT&#40;isNoteOn&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isNoteOff&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isPitchBend&#40;midi&#41;&#41;&#41; THEN BEGIN  //not a note, pb or sus pedal event                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;                              END;    END;    setLength&#40;notesOut, notesOutCount&#41;;    setLength&#40;otherOut, otherOutCount&#41;;  END;

Statistics: Posted by woodslanding — 26 Nov 2009, 08:26


]]>
2009-11-25T09:53:16+02:00 2009-11-25T09:53:16+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10753#p10753 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
In a way it behaves the opposite way of what you get by filling the array and setting the length within a block and then forget to zero the length in the next block. In that case the same data will be sent each block until something else in the script overwrites it.

I didn't have time yesterday for a closer look at your script as I was struggling with some other issues in some of the "normal" Usine modules, but as I said I managed to get data some simple data through just by moving the counter initializations down to the bottom. I did however notice that the alpha seemed more unstable running your script than most others I've tried. You better take a close look at how variables are treated etc, and remember that the new script engine seems less forgiving about minor incompatibilities and errors. You might have to quit and restart once in a while also.

The flip side of more possibilities is that you also get more possibilities for doing something wrong... ;)

Statistics: Posted by bsork — 25 Nov 2009, 08:53


]]>
2009-11-25T06:24:25+02:00 2009-11-25T06:24:25+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10752#p10752 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
Probably should have started with a smaller script, but I got all excited! ;)

-e

Statistics: Posted by woodslanding — 25 Nov 2009, 05:24


]]>
2009-11-25T05:56:32+02:00 2009-11-25T05:56:32+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10750#p10750 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
thanks,
-e

Statistics: Posted by woodslanding — 25 Nov 2009, 04:56


]]>
2009-11-24T21:57:56+02:00 2009-11-24T21:57:56+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10749#p10749 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by amiga909 — 24 Nov 2009, 20:57


]]>
2009-11-24T15:31:06+02:00 2009-11-24T15:31:06+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10748#p10748 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>

Since you're adding stuff to the outputs from Callback, you have to move the resetting of notesOutCount and otherOutCount to the end of Process. (I think I have done the same mistake myself, but my script isn't yet finished enough for the problem to occur. Will have to check later.)

I've only tested with a couple of CreateMidi modules without bothering with any transposing etc and I get the expected data out of the script with the exception of NoteOffs.

Statistics: Posted by bsork — 24 Nov 2009, 14:31


]]>
2009-11-24T10:32:57+02:00 2009-11-24T10:32:57+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10745#p10745 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by bsork — 24 Nov 2009, 09:32


]]>
2009-11-24T10:00:48+02:00 2009-11-24T10:00:48+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10743#p10743 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>

CODE:

&#40;*/////////////////////////////////////////////////////// CHANNEL  // Version 2009-11-21; author&#58; eric moon//// based on work by Bsork and amiga909//////////////////////////////////////////////////////*&#41;//  This takes a number of midi inputs &#40;on separate cables, for visual clarity&#41;//  and performs the following operations on each.//  enable, disable--per input//  strip CCs and AT and send them out a separate output//  read CC64 values &#40;or a CC of your choice&#41; to withhold noteoffs until the sus pedal is released.//  limit to minimum and maximum notes--one range affects all inputs, as it's assumed you'll typically be using one input at a time//  transpose--again, one range for all inputs.//  output rechannelizing--all outs are a single channel.  Use multiple strips to control multi-timbral modules.//  bypass output for turning off unused instruments.  waits for all notes to be released....//  drone switch that keeps current notes sounding, but discards new notesOns as long as it is held//  It is designed to function as part of a mixer channel strip, running between several keyboards and a vsti.CONST SUS_PED= 64;    //change if you use an unorthodox CC for sustaining.CONST INPUT_COUNT = 2;  //number of midi note sourcesCONST NOTE_ON        = 144;CONST NOTE_OFF       = 128;CONST CONTROL        = 176;CONST PITCHBEND      = 224;VAR   noteList                              &#58; ARRAY OF boolean;VAR   transList                             &#58; ARRAY OF integer;VAR   midi,noteOff                          &#58; TMidi; var midiIns                                 &#58;  ARRAY OF Tparameter;var enables                                 &#58;  ARRAY OF TParameter;var notesOut  &#58; Tparameter;var otherOut  &#58; Tparameter;       // all CCs except the sustain value go out this output.  So does AT and PgChvar octave    &#58; TParameter;var semi      &#58; TParameter;var hiNote    &#58; TParameter;var lowNote   &#58; TParameter;var drone     &#58; TParameter;       // sustains, but ignores new noteonsvar outChan   &#58; TParameter;       // everything goes out one channel.  It's a channel strip. Use more if you need other channels!var instBypass&#58; TParameter; VAR   octVal, semiVal, transpose            &#58; integer;VAR   hiVal, lowVal                         &#58; integer; VAR   midiInCount                           &#58; integer;VAR   otherOutCount, notesOutCount          &#58; integer;VAR   key, inputNum, byteNum                &#58; integer; VAR   minChn, maxChn, minKey, maxKey        &#58; integer;VAR   outputChannel                         &#58; integer;VAR   isSustained,noInput                   &#58; boolean;VAR   isEnabled                             &#58; Array of boolean;//////////////////////////////////////////////////////// initialize//////////////////////////////////////////////////////PROCEDURE init;    BEGIN      minChn &#58;= INPUT_COUNT - 1;   // these are initially set to their opposite extremes....    maxChn &#58;= 0;     minKey &#58;= 128;     maxKey &#58;= 0;        isSustained &#58;= FALSE;              setArrayLength&#40;noteList, 128&#41;;      FOR key&#58;=0 TO 127 DO BEGIN         noteList&#91;key&#93;&#58;=FALSE;    END;    SetArrayLength&#40;transList, 128&#41;;    FOR key&#58;=0 TO 127 DO BEGIN         transList&#91;key&#93;&#58;=0;    END;           setArrayLength&#40;midiIns, INPUT_COUNT&#41;;    setArrayLength&#40;enables, INPUT_COUNT&#41;;    FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        enables&#91;inputNum&#93;  &#58;= CreateParam&#40;'enable ' + intToStr&#40;inputNum + 1&#41;,ptSwitch&#41;;         SetValue&#40;enables&#91;inputNum&#93;, 1&#41;;               SetIsOutPut&#40;enables&#91;inputNum&#93;,false&#41;;            END;           octave      &#58;= CreateParam&#40;'octave',ptDataFader&#41;;          SetIsOutPut&#40;octave,false&#41;;    semi        &#58;= CreateParam&#40;'semi',ptDataFader&#41;;            SetIsOutPut&#40;semi,false&#41;;    SetFormat&#40;octave,'%.0f'&#41;; SetMin&#40;octave,-4&#41;;  SetMax&#40;octave,4&#41;;        SetFormat&#40;semi,'%.0f'&#41;;   SetMin&#40;semi,-7&#41;;    SetMax&#40;semi,7&#41;;      hiNote        &#58;= CreateParam&#40;'high note',ptMidiNoteFader&#41;;   SetIsOutPut&#40;hiNote,false&#41;;    lowNote       &#58;= CreateParam&#40;'low note',ptMidiNoteFader&#41;;    SetIsOutPut&#40;lowNote,false&#41;;      outChan       &#58;= CreateParam&#40;'output chan', ptDataFader&#41;;     SetIsOutPut&#40;outchan,false&#41;;     SetFormat&#40;outChan,'%.0f'&#41;; SetMin&#40;outChan,1&#41;;  SetMax&#40;outChan,16&#41;;    SetValue&#40;lowNote, 10&#41;;    SetValue&#40;hiNote, 115&#41;;      drone         &#58;= CreateParam&#40;'drone', ptSwitch&#41;;              SetIsOutput&#40;drone,false&#41;;    instBypass  &#58;= CreateParam&#40;'inst bypass', ptSwitch&#41;;       SetIsInput&#40;instBypass,false&#41;;      FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        midiIns&#91;inputNum&#93;  &#58;= CreateParam&#40;'MIDIin ' + intToStr&#40;inputNum + 1&#41; ,ptMidi&#41;;               SetIsOutPut&#40;midiIns&#91;inputNum&#93;,false&#41;;    END;        notesOut      &#58;= CreateParam&#40;'Notes Out',ptMidi&#41;;             SetIsInput&#40;notesOut,false&#41;;      otherOut      &#58;= CreateParam&#40;'other Out',ptMidi&#41;;             SetIsInput&#40;otherOut,false&#41;;      SetArrayLength&#40;isEnabled, INPUT_COUNT&#41;;    END;// <F> isNoteOn&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOn&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN       IF &#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2>0&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> isNoteOff&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOff&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN          IF &#40;midi.msg = NOTE_OFF&#41; OR &#40;&#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2 = 0&#41;&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;    END;END; // <F> isSusPed&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isSusPed&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;midi.msg = CONTROL&#41; AND &#40;midi.data1 = SUS_PED&#41; THEN BEGIN        result &#58;= true;    END    ELSE BEGIN        result &#58;= false;    END;END; // <F> isPitchBend&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isPitchBend&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN     IF &#40;midi.msg = PITCHBEND&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> global function inRange--eliminates only noteons outside the range limits FUNCTION inRange&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;isNoteOn&#40;midi&#41;&#41; AND &#40;midi.data1 > lowVal&#41; AND &#40;midi.data1 < hiVal&#41; THEN BEGIN        result &#58;= TRUE;    END    ELSE BEGIN        result &#58;= FALSE;    END; END;// <F> isClear//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//FUNCTION isClear&#40;&#41;  &#58; boolean;   // can we stop this loop as soon as a key = true??  Didn't like 'while'VAR clear &#58; boolean;BEGIN    clear &#58;= TRUE;    BEGIN        FOR key&#58;= minKey TO maxKey DO BEGIN                IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN                 clear &#58;= FALSE;                       END;                                                                  END;     END;    result &#58;= clear;     END;// <F> ReleaseNotes  --when you release the sustain, or release the drone, or change the output channel//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//PROCEDURE ReleaseNotes;BEGIN    FOR key&#58;= minKey TO maxKey DO BEGIN            IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN             noteOff.msg &#58;= NOTE_OFF;            noteOff.channel &#58;= outputChannel; // byte is a conversion--is this needed?            noteOff.data1 &#58;= key;            noteOff.data2 &#58;= 0;            setMidiArrayValue&#40;notesOut, notesOutCount, noteOff&#41;;  //danger when called from callback?            notesOutCount &#58;= notesOutCount + 1;            noteList&#91;key&#93; &#58;= FALSE;        END;                                                              END; END;    // Global Procedure StoreNoteOffs--just de-inlined for readability//----------------------------------------------//PROCEDURE StoreNoteOffs;BEGIN    IF &#40;midi.data1 > maxKey&#41; THEN BEGIN           maxKey &#58;= midi.data1;    END;    IF &#40;midi.data1 < minKey&#41; THEN BEGIN         minKey &#58;= midi.data1;     END;     noteList&#91;midi.data1&#93; &#58;= TRUE;END;// Callback//----------------------------------------------// procedure Callback&#40;n&#58;integer&#41;;BEGIN    // get input values        hiVal &#58;= trunc&#40;getValue&#40;hiNote&#41;&#41;;    lowVal &#58;= trunc&#40;getValue&#40;lowNote&#41;&#41;;    octVal &#58;= trunc&#40;getValue&#40;octave&#41;&#41;;    semival &#58;= trunc&#40;getValue&#40;semi&#41;&#41;;    transpose &#58;= &#40;octVal * 12&#41; + semiVal;writeln&#40;'transpose = ' + intToStr&#40;transpose&#41;&#41;;    outputChannel &#58;= trunc&#40;getValue&#40;outChan&#41;&#41;;    // see if any input is enabled....    noInput &#58;= TRUE;                                             FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO     BEGIN        IF getValue&#40;enables&#91;inputNum&#93;&#41; = 1 THEN BEGIN            isEnabled&#91;inputNum&#93; &#58;= TRUE;             noInput &#58;= FALSE;        END        ELSE BEGIN            isEnabled&#91;inputNum&#93; &#58;= FALSE;        END;    END;            // release notes if the drone has just been turned off, or if all inputs and notes are off, or if the channel is changed    IF &#40;&#40;n = drone&#41; and &#40;getValue&#40;drone&#41; = 0&#41;&#41; OR        &#40;&#40;noInput = TRUE&#41; AND &#40;isClear&#40;&#41; = TRUE&#41;&#41;       OR &#40;n = outChan&#41;                    THEN     BEGIN        releaseNotes;               // can I call this from callback?        setValue&#40;instBypass, 1&#41;;    END    ELSE BEGIN        setValue&#40;instBypass, 0&#41;;    END;END;  //////////////////////////////////////////////////////// process//////////////////////////////////////////////////////PROCEDURE PROCESS;BEGIN     FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO BEGIN                    midiInCount &#58;= getLength&#40;midiIns&#91;inputNum&#93;&#41;;    IF &#40;midiInCount > 0&#41; THEN BEGIN            notesOutCount &#58;= 0;            otherOutCount &#58;= 0;                FOR byteNum &#58;= 0 TO &#40;midiInCount - 1&#41; DO BEGIN   // process input                                       getMidiArrayValue&#40;midiIns&#91;inputNum&#93;, byteNum, midi&#41;;                midi.channel &#58;= outputChannel;                 If isSusPed&#40;midi&#41; THEN BEGIN                              if &#40;midi.data2 > 64&#41; THEN BEGIN                        isSustained &#58;= true;                    END                    ELSE BEGIN                                                 isSustained &#58;= false;                          ReleaseNotes;          // send noteoffs when the sus pedal is released                    END;                                              END;                 IF isNoteOn&#40;midi&#41; AND &#40;inRange&#40;midi&#41;&#41; AND &#40;isEnabled&#91;inputNum&#93;&#41; THEN BEGIN //note on, sus on, store and send                    IF &#40;isSustained = TRUE&#41; THEN BEGIN                                   StoreNoteOffs;                                      setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                    END                                          ELSE BEGIN                                        // valid noteon, sus off, send it out                        transList&#91;midi.data1&#93; &#58;= transpose;                         midi.data1 &#58;= midi.data1 + transpose;                                        setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                     END;                END                ELSE IF isNoteOff&#40;midi&#41; AND &#40;isSustained = FALSE&#41;  THEN BEGIN // valid noteoff, sus off, send it out                        midi.data1 &#58;= midi.data1 + transList&#91;midi.data1&#93;;                                         setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                                 END                                     ELSE IF isPitchBend&#40;midi&#41; THEN BEGIN                        // send PB along with the notes                                                 midi.channel &#58;= outputChannel;                                    setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                    notesOutCount &#58;= notesOutCount + 1;                END                ELSE IF &#40;NOT&#40;isNoteOn&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isNoteOff&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isPitchBend&#40;midi&#41;&#41;&#41; THEN BEGIN  //not a note, pb or sus pedal event                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;                               END;                        // process input            setLength&#40;notesOut, notesOutCount&#41;;            setLength&#40;otherOut, otherOutCount&#41;;                    END        ELSE BEGIN             setLength&#40;notesOut,0&#41;;            setLength&#40;otherOut, 0&#41;;         END;    END;  END;
Does it do this for you???

Statistics: Posted by woodslanding — 24 Nov 2009, 09:00


]]>
2009-11-24T09:14:34+02:00 2009-11-24T09:14:34+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10741#p10741 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by bsork — 24 Nov 2009, 08:14


]]>
2009-11-24T08:13:36+02:00 2009-11-24T08:13:36+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10740#p10740 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by woodslanding — 24 Nov 2009, 07:13


]]>
2009-11-23T22:52:03+02:00 2009-11-23T22:52:03+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10736#p10736 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
As long as you're defining your variables globally you can access them from anywhere in the script. (Well, I suppose they have to be declared before getting used. ;)) Within the scripts themselves, there are no differences between the Init, Callback and Process methods and the procedures and/or functions you declare yourself, except for when they are called. Regarding Callback you have to remember that it's called once for each parameter that's changed within the block, so if you have a patch where several parameters may be updated simultaneously (on a recall of preset for instance), and you do a lot of computing with these parameters, it can be wise to use a boolean (doUpdate := TRUE) in Callback, and check that boolean in Process. As far as I can tell, all the Callback calls happen before Process is called.

Eg:

CODE:

VAR pParam1, pParam2, pParam3 &#58; tParameter;VAR param1, param2, param3 &#58; single;VAR doUpdate &#58; boolean;....PROCEDURE Init;BEGIN   pParam1 &#58;= CreateParam&#40;'param 1', ...   pParam2 &#58;= CreateParam&#40;'param 2', ...   pParam3 &#58;= CreateParam&#40;'param 3', ...   doUpdate &#58;= FALSE;END;PROCEDURE GetParams;BEGIN    param1 &#58;= GetValue&#40;pParam1&#41;;    param2 &#58;= GetValue&#40;pParam2&#41;;    param3 &#58;= GetValue&#40;pParam3&#41;; END;PROCEDURE Callback&#40;n ; integer&#41;;BEGIN   // You can of course use IF-statements instead of CASE   CASE n OF       pParam1 &#58; doUpdate &#58;= TRUE;       pParam2 &#58; doUpdate &#58;= TRUE;       pParam3 &#58; doUpdate &#58;= TRUE;   END;END;PROCEDURE Process;BEGIN   IF &#40;doUpdate&#41; THEN BEGIN      GetParams;      doUpdate &#58;= FALSE;   END;   ...END;
To sum up:
Init is called only when compiling, that means only once, so as well defining input/output parameters, put all code that initializes variables (values, array lengths, ...) in here.
Callback is called every time an input parameter is changed, and can be called several times within the same block.
Process is called once for each block.
You can create a script with only the Init procedure, bot mostly you would want to use either Callback or Process or both as well.

Did that help?

Statistics: Posted by bsork — 23 Nov 2009, 21:52


]]>
BrainModular BrainModular Users Forum 2010-01-10T12:47:11+02:00 https://brainmodular.org/forums/app.php/feed/topic/1777 2010-01-10T12:47:11+02:00 2010-01-10T12:47:11+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=11196#p11196 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
tomorrow....

Statistics: Posted by woodslanding — 10 Jan 2010, 11:47


]]>
2010-01-10T12:32:26+02:00 2010-01-10T12:32:26+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=11195#p11195 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
So I put in a couple of booleans to decide whether to send the note offs and disable the instrument, but then I called the actual methods from within process. Seems to work! Here's the code:

CODE:

&#40;*/////////////////////////////////////////////////////// CHANNEL  // Version 2009-11-21; author&#58; eric moon//// based on work by Bsork and amiga909//////////////////////////////////////////////////////*&#41;//  This takes a number of midi inputs &#40;on separate cables, for visual clarity&#41;//  and performs the following operations on each.//  enable, disable--per input//  strip CCs and AT and send them out a separate output//  read CC64 values &#40;or a CC of your choice&#41; to withhold noteoffs until the sus pedal is released.//  limit to minimum and maximum notes--one range affects all inputs, as it's assumed you'll typically be using one input at a time//  transpose--again, one range for all inputs.//  output rechannelizing--all outs are a single channel.  Use multiple strips to control multi-timbral modules.//  bypass output for turning off unused instruments.  waits for all notes to be released....//  drone switch that keeps current notes sounding, but discards new notesOns as long as it is held//  It is designed to function as part of a mixer channel strip, running between several keyboards and a vsti.//  When the 'learn' function is enabled, notes are sent out output 2//  the first note sets the lower range, the second note sets the upper limit.//  when both notes are sent, learn is disabled, and notes go to output 1 as usual.CONST SUS_PED= 64;    //change if you use an unorthodox CC for sustaining.CONST INPUT_COUNT = 2;  //allows up to 16 inputs, one per channelCONST NOTE_ON        = 144;CONST NOTE_OFF       = 128;CONST CONTROL        = 176;CONST PITCHBEND      = 224;VAR   noteList                              &#58; ARRAY OF boolean;VAR   transList                             &#58; ARRAY OF integer;VAR   midi,noteOff                          &#58; TMidi; var midiIns                                 &#58;  ARRAY OF Tparameter;var enables                                 &#58;  ARRAY OF TParameter;var notesOut  &#58; Tparameter;var otherOut  &#58; Tparameter;       // all CCs except the sustain value go out this output.  So does AT and PgChvar octave    &#58; TParameter;var semi      &#58; TParameter;var hiNote    &#58; TParameter;var lowNote   &#58; TParameter;var drone     &#58; TParameter;       // sustains, but ignores new noteonsvar outChan   &#58; TParameter;       // everything goes out one channel.  It's a channel strip. Use more if you need other channels!var instEnable&#58; TParameter;var lower    &#58; Tparameter;var upper   &#58; Tparameter; var learn     &#58; TParameter;VAR   octVal, semiVal, transpose            &#58; integer;VAR   hiVal, lowVal                         &#58; integer; VAR   midiInCount                           &#58; integer;VAR   otherOutCount, notesOutCount          &#58; integer;VAR   key, inputNum, byteNum                &#58; integer; VAR   minChn, maxChn, minKey, maxKey        &#58; integer;VAR   outputChannel                         &#58; integer;VAR   isSustained,noInput                   &#58; boolean;VAR   isEnabled                             &#58; Array of boolean;VAR   learning                              &#58; boolean;VAR   droning                               &#58; boolean;VAR   release                               &#58; boolean;VAR   disablable                            &#58; boolean;var   learnCount                            &#58; integer;//////////////////////////////////////////////////////// initialize//////////////////////////////////////////////////////PROCEDURE init;    BEGIN      minChn &#58;= INPUT_COUNT - 1;   // these are initially set to their opposite extremes....    maxChn &#58;= 0;     minKey &#58;= 128;     maxKey &#58;= 0;        isSustained &#58;= FALSE;              setArrayLength&#40;noteList, 128&#41;;      FOR key&#58;=0 TO 127 DO BEGIN         noteList&#91;key&#93;&#58;=FALSE;    END;    SetArrayLength&#40;transList, 128&#41;;    FOR key&#58;=0 TO 127 DO BEGIN         transList&#91;key&#93;&#58;=0;    END;           setArrayLength&#40;midiIns, INPUT_COUNT&#41;;    setArrayLength&#40;enables, INPUT_COUNT&#41;;    FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        enables&#91;inputNum&#93;  &#58;= CreateParam&#40;'enable ' + intToStr&#40;inputNum + 1&#41;,ptSwitch&#41;;         SetValue&#40;enables&#91;inputNum&#93;, 1&#41;;               SetIsOutPut&#40;enables&#91;inputNum&#93;,false&#41;;            END;           octave      &#58;= CreateParam&#40;'octave',ptDataFader&#41;;          SetIsOutPut&#40;octave,false&#41;;    semi        &#58;= CreateParam&#40;'semi',ptDataFader&#41;;            SetIsOutPut&#40;semi,false&#41;;    SetFormat&#40;octave,'%.0f'&#41;; SetMin&#40;octave,-4&#41;;  SetMax&#40;octave,4&#41;;        SetFormat&#40;semi,'%.0f'&#41;;   SetMin&#40;semi,-7&#41;;    SetMax&#40;semi,7&#41;;      hiNote        &#58;= CreateParam&#40;'high note',ptMidiNoteFader&#41;;   SetIsOutPut&#40;hiNote,false&#41;;    lowNote       &#58;= CreateParam&#40;'low note',ptMidiNoteFader&#41;;    SetIsOutPut&#40;lowNote,false&#41;;      outChan       &#58;= CreateParam&#40;'output chan', ptDataFader&#41;;     SetIsOutPut&#40;outchan,false&#41;;     SetFormat&#40;outChan,'%.0f'&#41;; SetMin&#40;outChan,1&#41;;  SetMax&#40;outChan,16&#41;;    SetValue&#40;lowNote, 10&#41;;    SetValue&#40;hiNote, 115&#41;;      drone         &#58;= CreateParam&#40;'drone', ptSwitch&#41;;              SetIsOutput&#40;drone,false&#41;;    instEnable  &#58;= CreateParam&#40;'inst enable', ptSwitch&#41;;          SetIsInput&#40;instEnable,false&#41;;     FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        midiIns&#91;inputNum&#93;  &#58;= CreateParam&#40;'MIDIin ' + intToStr&#40;inputNum + 1&#41; ,ptMidi&#41;;               SetIsOutPut&#40;midiIns&#91;inputNum&#93;,false&#41;;    END;        notesOut      &#58;= CreateParam&#40;'NoteMIDI',ptMidi&#41;;             SetIsInput&#40;notesOut,false&#41;;      otherOut      &#58;= CreateParam&#40;'otherMIDI',ptMidi&#41;;             SetIsInput&#40;otherOut,false&#41;;    learn &#58;= CreateParam&#40;'learn',ptButton&#41;;                       SetIsOutPut&#40;learn,false&#41;;    lower &#58;= CreateParam&#40;'lower',ptMidiNoteFader&#41;;                SetIsInPut&#40;lower,false&#41;;    upper &#58;= CreateParam&#40;'upper',ptMidiNoteFader&#41;;                SetIsInPut&#40;upper,false&#41;;         notesOutCount &#58;= 0;    otherOutCount &#58;= 0;    learnCount    &#58;= 0;    disablable   &#58;= FALSE;    droning       &#58;= FALSE;    release       &#58;= FALSE;       SetArrayLength&#40;isEnabled, INPUT_COUNT&#41;; END;// <F> isNoteOn&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOn&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN       IF &#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2>0&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> isNoteOff&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOff&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN          IF &#40;midi.msg = NOTE_OFF&#41; OR &#40;&#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2 = 0&#41;&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;    END;END; // <F> isSusPed&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isSusPed&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;midi.msg = CONTROL&#41; AND &#40;midi.data1 = SUS_PED&#41; THEN BEGIN        result &#58;= true;    END    ELSE BEGIN        result &#58;= false;    END;END; // <F> isPitchBend&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isPitchBend&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN     IF &#40;midi.msg = PITCHBEND&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> global function inRange--eliminates only noteons outside the range limits FUNCTION inRange&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;isNoteOn&#40;midi&#41;&#41; AND &#40;midi.data1 > lowVal&#41; AND &#40;midi.data1 < hiVal&#41; THEN BEGIN        result &#58;= TRUE;    END    ELSE BEGIN        result &#58;= FALSE;    END; END;// <F> isClear//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//FUNCTION isClear&#40;&#41;  &#58; boolean;   // can we stop this loop as soon as a key = true??  Didn't like 'while'VAR clear &#58; boolean;BEGIN    clear &#58;= TRUE;    BEGIN        FOR key&#58;= minKey TO maxKey DO BEGIN                IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN                 clear &#58;= FALSE;                       END;                                                                  END;     END;    result &#58;= clear;     END;// <F> ReleaseNotes  --when you release the sustain, or release the drone, or change the output channel//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//PROCEDURE ReleaseNotes;BEGIN    FOR key&#58;= minKey TO maxKey DO BEGIN            IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN             noteOff.msg &#58;= NOTE_OFF;            noteOff.channel &#58;= outputChannel; // byte is a conversion--is this needed?            noteOff.data1 &#58;= key;            noteOff.data2 &#58;= 0;            setMidiArrayValue&#40;notesOut, notesOutCount, noteOff&#41;;            strace&#40;'sending noteOff for ' + intToStr&#40;key&#41;&#41;;            notesOutCount &#58;= notesOutCount + 1;            noteList&#91;key&#93; &#58;= FALSE;        END;                                                              END; END;    // Global Procedure StoreNoteOffs--just de-inlined for readability//----------------------------------------------//PROCEDURE StoreNoteOffs;BEGIN    IF &#40;midi.data1 > maxKey&#41; THEN BEGIN           maxKey &#58;= midi.data1;    END;    IF &#40;midi.data1 < minKey&#41; THEN BEGIN         minKey &#58;= midi.data1;     END;     noteList&#91;midi.data1&#93; &#58;= TRUE;END;// Callback//----------------------------------------------// procedure Callback&#40;n&#58;integer&#41;;BEGIN    if &#40;n = hiNote&#41; then begin         hiVal &#58;= round&#40;getValue&#40;hiNote&#41;&#41;;         setValue&#40;upper, hiVal&#41;;    end    else if &#40;n = lowNote&#41; then begin         lowVal &#58;= round&#40;getValue&#40;lowNote&#41;&#41;;         setValue&#40;lower, lowVal&#41;;    end    else if &#40;n = learn&#41; and &#40;getValue&#40;n&#41; = 1&#41; then begin         learning&#58;= TRUE;        strace&#40;'learning...'&#41;;         learnCount &#58;= 0;    end    else if &#40;learnCount = 2&#41; then begin        // we've just learned, so we want to send out lower and upper          learning &#58;= FALSE;        learnCount &#58;= 0;        strace&#40;' finishedlearning'&#41;;    end     else begin        // get input values            octVal &#58;= trunc&#40;getValue&#40;octave&#41;&#41;;        semival &#58;= trunc&#40;getValue&#40;semi&#41;&#41;;        transpose &#58;= &#40;octVal * 12&#41; + semiVal;        outputChannel &#58;= trunc&#40;getValue&#40;outChan&#41;&#41;;        droning &#58;= &#40;getValue&#40;drone&#41; = 1&#41;;        // see if any input is enabled....        noInput &#58;= TRUE;                                                 FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO         BEGIN            IF getValue&#40;enables&#91;inputNum&#93;&#41; = 1 THEN BEGIN                isEnabled&#91;inputNum&#93; &#58;= TRUE;                 noInput &#58;= FALSE;            END            ELSE BEGIN                isEnabled&#91;inputNum&#93; &#58;= FALSE;            END;        END;                  // release notes if the drone has just been turned off, or if all inputs and notes are off, or if the channel is changed              IF &#40;&#40;n = drone&#41; and &#40;not&#40;Droning&#41;&#41;&#41; OR            &#40;&#40;noInput = TRUE&#41; AND &#40;isClear&#40;&#41; = TRUE&#41;&#41;           OR &#40;n = outChan&#41;                        THEN BEGIN            strace&#40;'releasing notes'&#41;;            release &#58;= true;               // booleans to check in process            disablable &#58;= true;        END        ELSE BEGIN            setValue&#40;instEnable, 1&#41;;        END;    end;END;  //////////////////////////////////////////////////////// process//////////////////////////////////////////////////////PROCEDURE PROCESS;BEGIN     notesOutCount &#58;= 0;    otherOutCount &#58;= 0;       if release then releaseNotes;    FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO BEGIN                    midiInCount &#58;= getLength&#40;midiIns&#91;inputNum&#93;&#41;;                               FOR byteNum &#58;= 0 TO &#40;midiInCount - 1&#41; DO BEGIN   // process input                                       getMidiArrayValue&#40;midiIns&#91;inputNum&#93;, byteNum, midi&#41;;            midi.channel &#58;= outputChannel;            if &#40;learning&#41; then begin                IF &#40;isNoteOn&#40;midi&#41;&#41; and &#40;learnCount = 0&#41; THEN BEGIN                    lowVal &#58;= midi.data1;                    setValue&#40;lower, lowVal &#41;;                    learnCount &#58;= 1;                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                     strace&#40;'learnCount = ' + intToStr&#40;learnCount&#41;&#41;;                                                 END                 ELSE IF &#40;isNoteOn&#40;midi&#41;&#41; and &#40;learnCount = 1&#41;  THEN BEGIN                    hiVal &#58;= midi.data1;                    setValue&#40;upper, hiVal&#41;;                    learnCount &#58;= 2;                    learning &#58;= FALSE;  // we've set our outs....                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;            end             else if &#40;droning&#41; then begin  // basically ignore all midi when droning                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;            end            else begin                If isSusPed&#40;midi&#41; THEN BEGIN                              if &#40;midi.data2 > 64&#41; THEN BEGIN                        isSustained &#58;= true;                    END                    ELSE BEGIN                                                 isSustained &#58;= false;                          ReleaseNotes;          // send noteoffs when the sus pedal is released                    END;                                              END;                 IF isNoteOn&#40;midi&#41; AND &#40;inRange&#40;midi&#41;&#41; AND &#40;isEnabled&#91;inputNum&#93;&#41; THEN BEGIN //note on, sus on, store and send                    transList&#91;midi.data1&#93; &#58;= transpose;                     midi.data1 &#58;= midi.data1 + transpose;                     IF &#40;isSustained = TRUE&#41; THEN BEGIN                                   StoreNoteOffs;                                      setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                    END                                          ELSE BEGIN                                        // valid noteon, sus off, send it out                                       setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                     END;                END                ELSE IF isNoteOff&#40;midi&#41; AND &#40;isSustained = FALSE&#41;  THEN BEGIN // valid noteoff, sus off, send it out                        midi.data1 &#58;= midi.data1 + transList&#91;midi.data1&#93;;                                         setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                                 END                                     ELSE IF isPitchBend&#40;midi&#41; THEN BEGIN                        // send PB along with the notes                                                 midi.channel &#58;= outputChannel;                                    setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                    notesOutCount &#58;= notesOutCount + 1;                END                ELSE IF &#40;NOT&#40;isNoteOn&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isNoteOff&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isPitchBend&#40;midi&#41;&#41;&#41; THEN BEGIN  //not a note, pb or sus pedal event                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;                               end;        END;    END;    setLength&#40;notesOut, notesOutCount&#41;;    setLength&#40;otherOut, otherOutCount&#41;;    if disablable then setValue&#40;instEnable, 0&#41;; END;

Statistics: Posted by woodslanding — 10 Jan 2010, 11:32


]]>
2010-01-10T12:18:49+02:00 2010-01-10T12:18:49+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=11194#p11194 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
And I finally got around to checking the drone out, and it actually works. Sort of. Problem is, the noteOffs are not going out the output, even though my strace shows the code is getting called with correct values. So I'm wondering if this is somehow related to the problems above.

I tried moving the noteOut count resetting to the beginning of process, but that just gave me a bunch of stuck notes.

So thanks for any tips. This is pretty close to working!

CODE:

&#40;*/////////////////////////////////////////////////////// CHANNEL  // Version 2009-11-21; author&#58; eric moon//// based on work by Bsork and amiga909//////////////////////////////////////////////////////*&#41;//  This takes a number of midi inputs &#40;on separate cables, for visual clarity&#41;//  and performs the following operations on each.//  enable, disable--per input//  strip CCs and AT and send them out a separate output//  read CC64 values &#40;or a CC of your choice&#41; to withhold noteoffs until the sus pedal is released.//  limit to minimum and maximum notes--one range affects all inputs, as it's assumed you'll typically be using one input at a time//  transpose--again, one range for all inputs.//  output rechannelizing--all outs are a single channel.  Use multiple strips to control multi-timbral modules.//  bypass output for turning off unused instruments.  waits for all notes to be released....//  drone switch that keeps current notes sounding, but discards new notesOns as long as it is held//  It is designed to function as part of a mixer channel strip, running between several keyboards and a vsti.//  When the 'learn' function is enabled, notes are sent out output 2//  the first note sets the lower range, the second note sets the upper limit.//  when both notes are sent, learn is disabled, and notes go to output 1 as usual.CONST SUS_PED= 64;    //change if you use an unorthodox CC for sustaining.CONST INPUT_COUNT = 2;  //allows up to 16 inputs, one per channelCONST NOTE_ON        = 144;CONST NOTE_OFF       = 128;CONST CONTROL        = 176;CONST PITCHBEND      = 224;VAR   noteList                              &#58; ARRAY OF boolean;VAR   transList                             &#58; ARRAY OF integer;VAR   midi,noteOff                          &#58; TMidi; var midiIns                                 &#58;  ARRAY OF Tparameter;var enables                                 &#58;  ARRAY OF TParameter;var notesOut  &#58; Tparameter;var otherOut  &#58; Tparameter;       // all CCs except the sustain value go out this output.  So does AT and PgChvar octave    &#58; TParameter;var semi      &#58; TParameter;var hiNote    &#58; TParameter;var lowNote   &#58; TParameter;var drone     &#58; TParameter;       // sustains, but ignores new noteonsvar outChan   &#58; TParameter;       // everything goes out one channel.  It's a channel strip. Use more if you need other channels!var instEnable&#58; TParameter;var lower    &#58; Tparameter;var upper   &#58; Tparameter; var learn     &#58; TParameter;VAR   octVal, semiVal, transpose            &#58; integer;VAR   hiVal, lowVal                         &#58; integer; VAR   midiInCount                           &#58; integer;VAR   otherOutCount, notesOutCount          &#58; integer;VAR   key, inputNum, byteNum                &#58; integer; VAR   minChn, maxChn, minKey, maxKey        &#58; integer;VAR   outputChannel                         &#58; integer;VAR   isSustained,noInput                   &#58; boolean;VAR   isEnabled                             &#58; Array of boolean;VAR   learning                              &#58; boolean;VAR   droning                               &#58; boolean;var   learnCount                            &#58; integer;//////////////////////////////////////////////////////// initialize//////////////////////////////////////////////////////PROCEDURE init;    BEGIN      minChn &#58;= INPUT_COUNT - 1;   // these are initially set to their opposite extremes....    maxChn &#58;= 0;     minKey &#58;= 128;     maxKey &#58;= 0;        isSustained &#58;= FALSE;              setArrayLength&#40;noteList, 128&#41;;      FOR key&#58;=0 TO 127 DO BEGIN         noteList&#91;key&#93;&#58;=FALSE;    END;    SetArrayLength&#40;transList, 128&#41;;    FOR key&#58;=0 TO 127 DO BEGIN         transList&#91;key&#93;&#58;=0;    END;           setArrayLength&#40;midiIns, INPUT_COUNT&#41;;    setArrayLength&#40;enables, INPUT_COUNT&#41;;    FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        enables&#91;inputNum&#93;  &#58;= CreateParam&#40;'enable ' + intToStr&#40;inputNum + 1&#41;,ptSwitch&#41;;         SetValue&#40;enables&#91;inputNum&#93;, 1&#41;;               SetIsOutPut&#40;enables&#91;inputNum&#93;,false&#41;;            END;           octave      &#58;= CreateParam&#40;'octave',ptDataFader&#41;;          SetIsOutPut&#40;octave,false&#41;;    semi        &#58;= CreateParam&#40;'semi',ptDataFader&#41;;            SetIsOutPut&#40;semi,false&#41;;    SetFormat&#40;octave,'%.0f'&#41;; SetMin&#40;octave,-4&#41;;  SetMax&#40;octave,4&#41;;        SetFormat&#40;semi,'%.0f'&#41;;   SetMin&#40;semi,-7&#41;;    SetMax&#40;semi,7&#41;;      hiNote        &#58;= CreateParam&#40;'high note',ptMidiNoteFader&#41;;   SetIsOutPut&#40;hiNote,false&#41;;    lowNote       &#58;= CreateParam&#40;'low note',ptMidiNoteFader&#41;;    SetIsOutPut&#40;lowNote,false&#41;;      outChan       &#58;= CreateParam&#40;'output chan', ptDataFader&#41;;     SetIsOutPut&#40;outchan,false&#41;;     SetFormat&#40;outChan,'%.0f'&#41;; SetMin&#40;outChan,1&#41;;  SetMax&#40;outChan,16&#41;;    SetValue&#40;lowNote, 10&#41;;    SetValue&#40;hiNote, 115&#41;;      drone         &#58;= CreateParam&#40;'drone', ptSwitch&#41;;              SetIsOutput&#40;drone,false&#41;;    instEnable  &#58;= CreateParam&#40;'inst enable', ptSwitch&#41;;          SetIsInput&#40;instEnable,false&#41;;     FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        midiIns&#91;inputNum&#93;  &#58;= CreateParam&#40;'MIDIin ' + intToStr&#40;inputNum + 1&#41; ,ptMidi&#41;;               SetIsOutPut&#40;midiIns&#91;inputNum&#93;,false&#41;;    END;        notesOut      &#58;= CreateParam&#40;'NoteMIDI',ptMidi&#41;;             SetIsInput&#40;notesOut,false&#41;;      otherOut      &#58;= CreateParam&#40;'otherMIDI',ptMidi&#41;;             SetIsInput&#40;otherOut,false&#41;;    learn &#58;= CreateParam&#40;'learn',ptButton&#41;;                       SetIsOutPut&#40;learn,false&#41;;    lower &#58;= CreateParam&#40;'lower',ptMidiNoteFader&#41;;                SetIsInPut&#40;lower,false&#41;;    upper &#58;= CreateParam&#40;'upper',ptMidiNoteFader&#41;;                SetIsInPut&#40;upper,false&#41;;         notesOutCount &#58;= 0;    otherOutCount &#58;= 0;    learnCount    &#58;= 0;       SetArrayLength&#40;isEnabled, INPUT_COUNT&#41;; END;// <F> isNoteOn&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOn&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN       IF &#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2>0&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> isNoteOff&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOff&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN          IF &#40;midi.msg = NOTE_OFF&#41; OR &#40;&#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2 = 0&#41;&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;    END;END; // <F> isSusPed&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isSusPed&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;midi.msg = CONTROL&#41; AND &#40;midi.data1 = SUS_PED&#41; THEN BEGIN        result &#58;= true;    END    ELSE BEGIN        result &#58;= false;    END;END; // <F> isPitchBend&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isPitchBend&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN     IF &#40;midi.msg = PITCHBEND&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> global function inRange--eliminates only noteons outside the range limits FUNCTION inRange&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;isNoteOn&#40;midi&#41;&#41; AND &#40;midi.data1 > lowVal&#41; AND &#40;midi.data1 < hiVal&#41; THEN BEGIN        result &#58;= TRUE;    END    ELSE BEGIN        result &#58;= FALSE;    END; END;// <F> isClear//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//FUNCTION isClear&#40;&#41;  &#58; boolean;   // can we stop this loop as soon as a key = true??  Didn't like 'while'VAR clear &#58; boolean;BEGIN    clear &#58;= TRUE;    BEGIN        FOR key&#58;= minKey TO maxKey DO BEGIN                IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN                 clear &#58;= FALSE;                       END;                                                                  END;     END;    result &#58;= clear;     END;// <F> ReleaseNotes  --when you release the sustain, or release the drone, or change the output channel//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//PROCEDURE ReleaseNotes;BEGIN    FOR key&#58;= minKey TO maxKey DO BEGIN            IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN             noteOff.msg &#58;= NOTE_OFF;            noteOff.channel &#58;= outputChannel; // byte is a conversion--is this needed?            noteOff.data1 &#58;= key;            noteOff.data2 &#58;= 0;            setMidiArrayValue&#40;notesOut, notesOutCount, noteOff&#41;;strace&#40;'sending noteOff for ' + intToStr&#40;key&#41;&#41;;            notesOutCount &#58;= notesOutCount + 1;            noteList&#91;key&#93; &#58;= FALSE;        END;                                                              END; END;    // Global Procedure StoreNoteOffs--just de-inlined for readability//----------------------------------------------//PROCEDURE StoreNoteOffs;BEGIN    IF &#40;midi.data1 > maxKey&#41; THEN BEGIN           maxKey &#58;= midi.data1;    END;    IF &#40;midi.data1 < minKey&#41; THEN BEGIN         minKey &#58;= midi.data1;     END;     noteList&#91;midi.data1&#93; &#58;= TRUE;END;// Callback//----------------------------------------------// procedure Callback&#40;n&#58;integer&#41;;BEGIN    if &#40;n = hiNote&#41; then begin         hiVal &#58;= round&#40;getValue&#40;hiNote&#41;&#41;;         setValue&#40;upper, hiVal&#41;;    end    else if &#40;n = lowNote&#41; then begin         lowVal &#58;= round&#40;getValue&#40;lowNote&#41;&#41;;         setValue&#40;lower, lowVal&#41;;    end    else if &#40;n = learn&#41; and &#40;getValue&#40;n&#41; = 1&#41; then begin         learning&#58;= TRUE;        strace&#40;'learning...'&#41;;         learnCount &#58;= 0;    end    else if &#40;learnCount = 2&#41; then begin         learning &#58;= FALSE;        learnCount &#58;= 0;        strace&#40;' finishedlearning'&#41;;    end     else begin        // get input values            octVal &#58;= trunc&#40;getValue&#40;octave&#41;&#41;;        semival &#58;= trunc&#40;getValue&#40;semi&#41;&#41;;        transpose &#58;= &#40;octVal * 12&#41; + semiVal;        outputChannel &#58;= trunc&#40;getValue&#40;outChan&#41;&#41;;        droning &#58;= &#40;getValue&#40;drone&#41; = 1&#41;;        // see if any input is enabled....        noInput &#58;= TRUE;                                                 FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO         BEGIN            IF getValue&#40;enables&#91;inputNum&#93;&#41; = 1 THEN BEGIN                isEnabled&#91;inputNum&#93; &#58;= TRUE;                 noInput &#58;= FALSE;            END            ELSE BEGIN                isEnabled&#91;inputNum&#93; &#58;= FALSE;            END;        END;                  // release notes if the drone has just been turned off, or if all inputs and notes are off, or if the channel is changed              IF &#40;&#40;n = drone&#41; and &#40;not&#40;Droning&#41;&#41;&#41; OR            &#40;&#40;noInput = TRUE&#41; AND &#40;isClear&#40;&#41; = TRUE&#41;&#41;           OR &#40;n = outChan&#41;                        THEN BEGIN            strace&#40;'releasing notes'&#41;;            releaseNotes;               setValue&#40;instEnable, 0&#41;;        END        ELSE BEGIN            setValue&#40;instEnable, 1&#41;;        END;    end;END;  //////////////////////////////////////////////////////// process//////////////////////////////////////////////////////PROCEDURE PROCESS;BEGIN     notesOutCount &#58;= 0;    otherOutCount &#58;= 0;           FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO BEGIN                    midiInCount &#58;= getLength&#40;midiIns&#91;inputNum&#93;&#41;;                               FOR byteNum &#58;= 0 TO &#40;midiInCount - 1&#41; DO BEGIN   // process input                                       getMidiArrayValue&#40;midiIns&#91;inputNum&#93;, byteNum, midi&#41;;            midi.channel &#58;= outputChannel;            if &#40;learning&#41; then begin                IF &#40;isNoteOn&#40;midi&#41;&#41; and &#40;learnCount = 0&#41; THEN BEGIN                    lowVal &#58;= midi.data1;                    setValue&#40;lower, lowVal &#41;;                    learnCount &#58;= 1;                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                     strace&#40;'learnCount = ' + intToStr&#40;learnCount&#41;&#41;;                                                 END                 ELSE IF &#40;isNoteOn&#40;midi&#41;&#41; and &#40;learnCount = 1&#41;  THEN BEGIN                    hiVal &#58;= midi.data1;                    setValue&#40;upper, hiVal&#41;;                    learnCount &#58;= 2;                    learning &#58;= FALSE;  // we've set our outs....                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;            end             else if &#40;droning&#41; then begin  // basically ignore all midi when droning                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;            end            else begin                If isSusPed&#40;midi&#41; THEN BEGIN                              if &#40;midi.data2 > 64&#41; THEN BEGIN                        isSustained &#58;= true;                    END                    ELSE BEGIN                                                 isSustained &#58;= false;                          ReleaseNotes;          // send noteoffs when the sus pedal is released                    END;                                              END;                 IF isNoteOn&#40;midi&#41; AND &#40;inRange&#40;midi&#41;&#41; AND &#40;isEnabled&#91;inputNum&#93;&#41; THEN BEGIN //note on, sus on, store and send                    transList&#91;midi.data1&#93; &#58;= transpose;                     midi.data1 &#58;= midi.data1 + transpose;                     IF &#40;isSustained = TRUE&#41; THEN BEGIN                                   StoreNoteOffs;                                      setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                    END                                          ELSE BEGIN                                        // valid noteon, sus off, send it out                                       setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                     END;                END                ELSE IF isNoteOff&#40;midi&#41; AND &#40;isSustained = FALSE&#41;  THEN BEGIN // valid noteoff, sus off, send it out                        midi.data1 &#58;= midi.data1 + transList&#91;midi.data1&#93;;                                         setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                                 END                                     ELSE IF isPitchBend&#40;midi&#41; THEN BEGIN                        // send PB along with the notes                                                 midi.channel &#58;= outputChannel;                                    setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                    notesOutCount &#58;= notesOutCount + 1;                END                ELSE IF &#40;NOT&#40;isNoteOn&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isNoteOff&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isPitchBend&#40;midi&#41;&#41;&#41; THEN BEGIN  //not a note, pb or sus pedal event                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;                               end;        END;    END;    setLength&#40;notesOut, notesOutCount&#41;;    setLength&#40;otherOut, otherOutCount&#41;; END;

Statistics: Posted by woodslanding — 10 Jan 2010, 11:18


]]>
2009-12-04T17:15:54+02:00 2009-12-04T17:15:54+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10855#p10855 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
I will try to implement stuff like this, but the more straight-forward stuff like filtering, transposition, rerouting and value scaling will have the priority.

Statistics: Posted by bsork — 04 Dec 2009, 16:15


]]>
2009-12-04T04:17:34+02:00 2009-12-04T04:17:34+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10849#p10849 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Definately more tools like this are needed in Usine!

Statistics: Posted by gurulogic — 04 Dec 2009, 03:17


]]>
2009-12-03T22:44:29+02:00 2009-12-03T22:44:29+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10842#p10842 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>

There are some things that MungRack do that I have no plans of implementing, but there are also stuff that I - from reading the docs - don't think it will do; like the sustain/sustenotu/hold stuff mentioned before in this topic. I will also try to do my best to avoid hanging notes, even when changing channel/note range/transpose/output parameters when notes are sounding.

Just to recap a little; what I'm working on is a patch with a script to handle various filters and transformers, and I also plan to create smaller, single function version patches with most, if not all, the transformers etc.

Still got a lot of work to do, I'm afraid...

Statistics: Posted by bsork — 03 Dec 2009, 21:44


]]>
2009-12-03T20:19:31+02:00 2009-12-03T20:19:31+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10839#p10839 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> http://www.asseca.com/nicfit/mungrack.html

Statistics: Posted by gurulogic — 03 Dec 2009, 19:19


]]>
2009-11-27T06:56:34+02:00 2009-11-27T06:56:34+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10781#p10781 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by woodslanding — 27 Nov 2009, 05:56


]]>
2009-11-26T22:11:32+02:00 2009-11-26T22:11:32+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10776#p10776 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by bsork — 26 Nov 2009, 21:11


]]>
2009-11-26T21:46:12+02:00 2009-11-26T21:46:12+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10772#p10772 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
Sostenuto is clever--I've never seen that in the midi world!

Statistics: Posted by woodslanding — 26 Nov 2009, 20:46


]]>
2009-11-26T12:50:40+02:00 2009-11-26T12:50:40+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10769#p10769 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
You still have to move the 'notesOutCount := 0; otherOutCount := 0;' down below where you set the lengths though, as you're calling releaseNotes from Callback. Remember that Callback is executed once for each change in an input parameter before Process is called, so what happens when drone is turned off you first fill the outputs in releaseNotes, then in Process the counters are zeroed which means that the data from Callback->releaseNotes is never sent.

BTW, I'm thinking of implementing these varieties of sustain within the script I'm working on:
Sustain: Like your script (without drone); delays NoteOffs until sustain is deactivated.
Sustenuto: Delays NoteOffs only for notes held when activating sustain.
Hold: Like amiga909's script; accumulates notes until all have been released, and send NoteOffs when a new NoteOn is received or sustain is deactivated.
There will also be a trigger/button input to send all missing NoteOffs + CC123/AllNotesOff.

Statistics: Posted by bsork — 26 Nov 2009, 11:50


]]>
2009-11-26T11:28:00+02:00 2009-11-26T11:28:00+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10765#p10765 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
Wow, just looked at the code, and in reality it would be 'for i = 0 to -1'

doesn't sound like a good thing, but it's not crashing the script.... but I guess the important thing is that I can bypass the FOR loop without specifically setting the output array length to zero--if it startes out at size zero, and nothing is added to it, it's still size zero.

Any clues why my transpose value isn't tracking? What I'm doing in callback() seems very simple and straighforward. It is the only place the value of transpose is changed......

Oh--maybe I need to be getting parameters in the process loop, ala your earlier suggestion!! I will try that.

thanks!
-e

Statistics: Posted by woodslanding — 26 Nov 2009, 10:28


]]>
2009-11-26T10:41:25+02:00 2009-11-26T10:41:25+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10764#p10764 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
I took the test for midLength > 0 out. Why was that in there?? It doesn't seem like it saves a step. If the length is zero, it's just not going to run the for loop anyway, right?? or was the script engine not able to handle 'for i = 0 to 0' correctly before?
Beware that FOR i := 0 TO 0 will execute the loop once! So you should either check length 0 with an IF before the loop, or use a WHILE loop. Something like:

CODE:

 i &#58;= 0;WHILE i < cnt DO BEGIN   do_something...   i &#58;= i + 1;END;

Statistics: Posted by bsork — 26 Nov 2009, 09:41


]]>
2009-11-26T09:56:25+02:00 2009-11-26T09:56:25+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10763#p10763 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
about the hanging-note thing:
there actually is a vst series that takes care of it:
"•most plugins include a sort of hanging-note-protection system (where applicable) to enable making changes during playback (e.g. when a MIDI thru option is toggled) without the risk of not releasing notes which are played at the same time the changes happen "

about a sustain effect:
S-CC-Sustain-Lite
http://www.s-production.de/
haven't tested it but i dont think a usine script would be much more effective.
Missed this the first time. I'm going to check it out. Looks like good stuff, and if it's programmed in C, should be fast.

Thanks!
-e

Statistics: Posted by woodslanding — 26 Nov 2009, 08:56


]]>
2009-11-26T09:26:56+02:00 2009-11-26T09:26:56+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10760#p10760 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
So it's functioning, and the sustain pedal is sustaining, but I am getting stuck notes, so I'll have to think carefully about the code. Also, my code as it stands seems to not always update transpose correctly. Sometimes the writeln test value changes, but the note out doesn't, and other times neither is synched up with the values on the sliders.

nevertheless it is an encouraging start.

cheers!
-eric

The code as it stands:

CODE:

&#40;*/////////////////////////////////////////////////////// CHANNEL  // Version 2009-11-21; author&#58; eric moon//// based on work by Bsork and amiga909//////////////////////////////////////////////////////*&#41;//  This takes a number of midi inputs &#40;on separate cables, for visual clarity&#41;//  and performs the following operations on each.//  enable, disable--per input//  strip CCs and AT and send them out a separate output//  read CC64 values &#40;or a CC of your choice&#41; to withhold noteoffs until the sus pedal is released.//  limit to minimum and maximum notes--one range affects all inputs, as it's assumed you'll typically be using one input at a time//  transpose--again, one range for all inputs.//  output rechannelizing--all outs are a single channel.  Use multiple strips to control multi-timbral modules.//  bypass output for turning off unused instruments.  waits for all notes to be released....//  drone switch that keeps current notes sounding, but discards new notesOns as long as it is held//  It is designed to function as part of a mixer channel strip, running between several keyboards and a vsti.CONST SUS_PED= 64;    //change if you use an unorthodox CC for sustaining.CONST INPUT_COUNT = 2;  //allows up to 16 inputs, one per channelCONST NOTE_ON        = 144;CONST NOTE_OFF       = 128;CONST CONTROL        = 176;CONST PITCHBEND      = 224;VAR   noteList                              &#58; ARRAY OF boolean;VAR   transList                             &#58; ARRAY OF integer;VAR   midi,noteOff                          &#58; TMidi; var midiIns                                 &#58;  ARRAY OF Tparameter;var enables                                 &#58;  ARRAY OF TParameter;var notesOut  &#58; Tparameter;var otherOut  &#58; Tparameter;       // all CCs except the sustain value go out this output.  So does AT and PgChvar octave    &#58; TParameter;var semi      &#58; TParameter;var hiNote    &#58; TParameter;var lowNote   &#58; TParameter;var drone     &#58; TParameter;       // sustains, but ignores new noteonsvar outChan   &#58; TParameter;       // everything goes out one channel.  It's a channel strip. Use more if you need other channels!var instBypass&#58; TParameter; VAR   octVal, semiVal, transpose            &#58; integer;VAR   hiVal, lowVal                         &#58; integer; VAR   midiInCount                           &#58; integer;VAR   otherOutCount, notesOutCount          &#58; integer;VAR   key, inputNum, byteNum                &#58; integer; VAR   minChn, maxChn, minKey, maxKey        &#58; integer;VAR   outputChannel                         &#58; integer;VAR   isSustained,noInput                   &#58; boolean;VAR   isEnabled                             &#58; Array of boolean;//////////////////////////////////////////////////////// initialize//////////////////////////////////////////////////////PROCEDURE init;    BEGIN      minChn &#58;= INPUT_COUNT - 1;   // these are initially set to their opposite extremes....    maxChn &#58;= 0;     minKey &#58;= 128;     maxKey &#58;= 0;        isSustained &#58;= FALSE;              setArrayLength&#40;noteList, 128&#41;;      FOR key&#58;=0 TO 127 DO BEGIN         noteList&#91;key&#93;&#58;=FALSE;    END;    SetArrayLength&#40;transList, 128&#41;;    FOR key&#58;=0 TO 127 DO BEGIN         transList&#91;key&#93;&#58;=0;    END;           setArrayLength&#40;midiIns, INPUT_COUNT&#41;;    setArrayLength&#40;enables, INPUT_COUNT&#41;;    FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        enables&#91;inputNum&#93;  &#58;= CreateParam&#40;'enable ' + intToStr&#40;inputNum + 1&#41;,ptSwitch&#41;;         SetValue&#40;enables&#91;inputNum&#93;, 1&#41;;               SetIsOutPut&#40;enables&#91;inputNum&#93;,false&#41;;            END;           octave      &#58;= CreateParam&#40;'octave',ptDataFader&#41;;          SetIsOutPut&#40;octave,false&#41;;    semi        &#58;= CreateParam&#40;'semi',ptDataFader&#41;;            SetIsOutPut&#40;semi,false&#41;;    SetFormat&#40;octave,'%.0f'&#41;; SetMin&#40;octave,-4&#41;;  SetMax&#40;octave,4&#41;;        SetFormat&#40;semi,'%.0f'&#41;;   SetMin&#40;semi,-7&#41;;    SetMax&#40;semi,7&#41;;      hiNote        &#58;= CreateParam&#40;'high note',ptMidiNoteFader&#41;;   SetIsOutPut&#40;hiNote,false&#41;;    lowNote       &#58;= CreateParam&#40;'low note',ptMidiNoteFader&#41;;    SetIsOutPut&#40;lowNote,false&#41;;      outChan       &#58;= CreateParam&#40;'output chan', ptDataFader&#41;;     SetIsOutPut&#40;outchan,false&#41;;     SetFormat&#40;outChan,'%.0f'&#41;; SetMin&#40;outChan,1&#41;;  SetMax&#40;outChan,16&#41;;    SetValue&#40;lowNote, 10&#41;;    SetValue&#40;hiNote, 115&#41;;      drone         &#58;= CreateParam&#40;'drone', ptSwitch&#41;;              SetIsOutput&#40;drone,false&#41;;    instBypass  &#58;= CreateParam&#40;'inst bypass', ptSwitch&#41;;       SetIsInput&#40;instBypass,false&#41;;      FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        midiIns&#91;inputNum&#93;  &#58;= CreateParam&#40;'MIDIin ' + intToStr&#40;inputNum + 1&#41; ,ptMidi&#41;;               SetIsOutPut&#40;midiIns&#91;inputNum&#93;,false&#41;;    END;        notesOut      &#58;= CreateParam&#40;'Notes Out',ptMidi&#41;;             SetIsInput&#40;notesOut,false&#41;;      otherOut      &#58;= CreateParam&#40;'other Out',ptMidi&#41;;             SetIsInput&#40;otherOut,false&#41;;      notesOutCount &#58;= 0;    otherOutCount &#58;= 0;       SetArrayLength&#40;isEnabled, INPUT_COUNT&#41;; END;// <F> isNoteOn&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOn&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN       IF &#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2>0&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> isNoteOff&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOff&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN          IF &#40;midi.msg = NOTE_OFF&#41; OR &#40;&#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2 = 0&#41;&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;    END;END; // <F> isSusPed&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isSusPed&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;midi.msg = CONTROL&#41; AND &#40;midi.data1 = SUS_PED&#41; THEN BEGIN        result &#58;= true;    END    ELSE BEGIN        result &#58;= false;    END;END; // <F> isPitchBend&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isPitchBend&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN     IF &#40;midi.msg = PITCHBEND&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> global function inRange--eliminates only noteons outside the range limits FUNCTION inRange&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;isNoteOn&#40;midi&#41;&#41; AND &#40;midi.data1 > lowVal&#41; AND &#40;midi.data1 < hiVal&#41; THEN BEGIN        result &#58;= TRUE;    END    ELSE BEGIN        result &#58;= FALSE;    END; END;// <F> isClear//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//FUNCTION isClear&#40;&#41;  &#58; boolean;   // can we stop this loop as soon as a key = true??  Didn't like 'while'VAR clear &#58; boolean;BEGIN    clear &#58;= TRUE;    BEGIN        FOR key&#58;= minKey TO maxKey DO BEGIN                IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN                 clear &#58;= FALSE;                       END;                                                                  END;     END;    result &#58;= clear;     END;// <F> ReleaseNotes  --when you release the sustain, or release the drone, or change the output channel//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//PROCEDURE ReleaseNotes;BEGIN    FOR key&#58;= minKey TO maxKey DO BEGIN            IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN             noteOff.msg &#58;= NOTE_OFF;            noteOff.channel &#58;= outputChannel; // byte is a conversion--is this needed?            noteOff.data1 &#58;= key;            noteOff.data2 &#58;= 0;            setMidiArrayValue&#40;notesOut, notesOutCount, noteOff&#41;;  //danger when called from callback?            notesOutCount &#58;= notesOutCount + 1;            noteList&#91;key&#93; &#58;= FALSE;        END;                                                              END; END;    // Global Procedure StoreNoteOffs--just de-inlined for readability//----------------------------------------------//PROCEDURE StoreNoteOffs;BEGIN    IF &#40;midi.data1 > maxKey&#41; THEN BEGIN           maxKey &#58;= midi.data1;    END;    IF &#40;midi.data1 < minKey&#41; THEN BEGIN         minKey &#58;= midi.data1;     END;     noteList&#91;midi.data1&#93; &#58;= TRUE;END;// Callback//----------------------------------------------// procedure Callback&#40;n&#58;integer&#41;;BEGIN    // get input values        hiVal &#58;= trunc&#40;getValue&#40;hiNote&#41;&#41;;    lowVal &#58;= trunc&#40;getValue&#40;lowNote&#41;&#41;;    octVal &#58;= trunc&#40;getValue&#40;octave&#41;&#41;;    semival &#58;= trunc&#40;getValue&#40;semi&#41;&#41;;    transpose &#58;= &#40;octVal * 12&#41; + semiVal;writeln&#40;'transpose = ' + intToStr&#40;transpose&#41;&#41;;    outputChannel &#58;= trunc&#40;getValue&#40;outChan&#41;&#41;;    // see if any input is enabled....    noInput &#58;= TRUE;                                             FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO     BEGIN        IF getValue&#40;enables&#91;inputNum&#93;&#41; = 1 THEN BEGIN            isEnabled&#91;inputNum&#93; &#58;= TRUE;             noInput &#58;= FALSE;        END        ELSE BEGIN            isEnabled&#91;inputNum&#93; &#58;= FALSE;        END;    END;          // release notes if the drone has just been turned off, or if all inputs and notes are off, or if the channel is changed    IF &#40;&#40;n = drone&#41; and &#40;getValue&#40;drone&#41; = 0&#41;&#41; OR        &#40;&#40;noInput = TRUE&#41; AND &#40;isClear&#40;&#41; = TRUE&#41;&#41;       OR &#40;n = outChan&#41;                    THEN     BEGIN        releaseNotes;               // can I call this from callback?        setValue&#40;instBypass, 1&#41;;    END    ELSE BEGIN        setValue&#40;instBypass, 0&#41;;    END;END;  //////////////////////////////////////////////////////// process//////////////////////////////////////////////////////PROCEDURE PROCESS;BEGIN     notesOutCount &#58;= 0;    otherOutCount &#58;= 0;    FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO BEGIN                    midiInCount &#58;= getLength&#40;midiIns&#91;inputNum&#93;&#41;;               FOR byteNum &#58;= 0 TO &#40;midiInCount - 1&#41; DO BEGIN   // process input                                       getMidiArrayValue&#40;midiIns&#91;inputNum&#93;, byteNum, midi&#41;;                midi.channel &#58;= outputChannel;                 If isSusPed&#40;midi&#41; THEN BEGIN                              if &#40;midi.data2 > 64&#41; THEN BEGIN                        isSustained &#58;= true;                    END                    ELSE BEGIN                                                 isSustained &#58;= false;                          ReleaseNotes;          // send noteoffs when the sus pedal is released                    END;                                              END;                 IF isNoteOn&#40;midi&#41; AND &#40;inRange&#40;midi&#41;&#41; AND &#40;isEnabled&#91;inputNum&#93;&#41; THEN BEGIN //note on, sus on, store and send                    transList&#91;midi.data1&#93; &#58;= transpose;                     midi.data1 &#58;= midi.data1 + transpose;                     IF &#40;isSustained = TRUE&#41; THEN BEGIN                                   StoreNoteOffs;                                      setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                    END                                          ELSE BEGIN                                        // valid noteon, sus off, send it out                                       setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                     END;                END                ELSE IF isNoteOff&#40;midi&#41; AND &#40;isSustained = FALSE&#41;  THEN BEGIN // valid noteoff, sus off, send it out                        midi.data1 &#58;= midi.data1 + transList&#91;midi.data1&#93;;                                         setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                                 END                                     ELSE IF isPitchBend&#40;midi&#41; THEN BEGIN                        // send PB along with the notes                                                 midi.channel &#58;= outputChannel;                                    setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                    notesOutCount &#58;= notesOutCount + 1;                END                ELSE IF &#40;NOT&#40;isNoteOn&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isNoteOff&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isPitchBend&#40;midi&#41;&#41;&#41; THEN BEGIN  //not a note, pb or sus pedal event                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;                              END;    END;    setLength&#40;notesOut, notesOutCount&#41;;    setLength&#40;otherOut, otherOutCount&#41;;  END;

Statistics: Posted by woodslanding — 26 Nov 2009, 08:26


]]>
2009-11-25T09:53:16+02:00 2009-11-25T09:53:16+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10753#p10753 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
In a way it behaves the opposite way of what you get by filling the array and setting the length within a block and then forget to zero the length in the next block. In that case the same data will be sent each block until something else in the script overwrites it.

I didn't have time yesterday for a closer look at your script as I was struggling with some other issues in some of the "normal" Usine modules, but as I said I managed to get data some simple data through just by moving the counter initializations down to the bottom. I did however notice that the alpha seemed more unstable running your script than most others I've tried. You better take a close look at how variables are treated etc, and remember that the new script engine seems less forgiving about minor incompatibilities and errors. You might have to quit and restart once in a while also.

The flip side of more possibilities is that you also get more possibilities for doing something wrong... ;)

Statistics: Posted by bsork — 25 Nov 2009, 08:53


]]>
2009-11-25T06:24:25+02:00 2009-11-25T06:24:25+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10752#p10752 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
Probably should have started with a smaller script, but I got all excited! ;)

-e

Statistics: Posted by woodslanding — 25 Nov 2009, 05:24


]]>
2009-11-25T05:56:32+02:00 2009-11-25T05:56:32+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10750#p10750 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
thanks,
-e

Statistics: Posted by woodslanding — 25 Nov 2009, 04:56


]]>
2009-11-24T21:57:56+02:00 2009-11-24T21:57:56+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10749#p10749 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by amiga909 — 24 Nov 2009, 20:57


]]>
2009-11-24T15:31:06+02:00 2009-11-24T15:31:06+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10748#p10748 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>

Since you're adding stuff to the outputs from Callback, you have to move the resetting of notesOutCount and otherOutCount to the end of Process. (I think I have done the same mistake myself, but my script isn't yet finished enough for the problem to occur. Will have to check later.)

I've only tested with a couple of CreateMidi modules without bothering with any transposing etc and I get the expected data out of the script with the exception of NoteOffs.

Statistics: Posted by bsork — 24 Nov 2009, 14:31


]]>
2009-11-24T10:32:57+02:00 2009-11-24T10:32:57+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10745#p10745 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by bsork — 24 Nov 2009, 09:32


]]>
2009-11-24T10:00:48+02:00 2009-11-24T10:00:48+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10743#p10743 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>

CODE:

&#40;*/////////////////////////////////////////////////////// CHANNEL  // Version 2009-11-21; author&#58; eric moon//// based on work by Bsork and amiga909//////////////////////////////////////////////////////*&#41;//  This takes a number of midi inputs &#40;on separate cables, for visual clarity&#41;//  and performs the following operations on each.//  enable, disable--per input//  strip CCs and AT and send them out a separate output//  read CC64 values &#40;or a CC of your choice&#41; to withhold noteoffs until the sus pedal is released.//  limit to minimum and maximum notes--one range affects all inputs, as it's assumed you'll typically be using one input at a time//  transpose--again, one range for all inputs.//  output rechannelizing--all outs are a single channel.  Use multiple strips to control multi-timbral modules.//  bypass output for turning off unused instruments.  waits for all notes to be released....//  drone switch that keeps current notes sounding, but discards new notesOns as long as it is held//  It is designed to function as part of a mixer channel strip, running between several keyboards and a vsti.CONST SUS_PED= 64;    //change if you use an unorthodox CC for sustaining.CONST INPUT_COUNT = 2;  //number of midi note sourcesCONST NOTE_ON        = 144;CONST NOTE_OFF       = 128;CONST CONTROL        = 176;CONST PITCHBEND      = 224;VAR   noteList                              &#58; ARRAY OF boolean;VAR   transList                             &#58; ARRAY OF integer;VAR   midi,noteOff                          &#58; TMidi; var midiIns                                 &#58;  ARRAY OF Tparameter;var enables                                 &#58;  ARRAY OF TParameter;var notesOut  &#58; Tparameter;var otherOut  &#58; Tparameter;       // all CCs except the sustain value go out this output.  So does AT and PgChvar octave    &#58; TParameter;var semi      &#58; TParameter;var hiNote    &#58; TParameter;var lowNote   &#58; TParameter;var drone     &#58; TParameter;       // sustains, but ignores new noteonsvar outChan   &#58; TParameter;       // everything goes out one channel.  It's a channel strip. Use more if you need other channels!var instBypass&#58; TParameter; VAR   octVal, semiVal, transpose            &#58; integer;VAR   hiVal, lowVal                         &#58; integer; VAR   midiInCount                           &#58; integer;VAR   otherOutCount, notesOutCount          &#58; integer;VAR   key, inputNum, byteNum                &#58; integer; VAR   minChn, maxChn, minKey, maxKey        &#58; integer;VAR   outputChannel                         &#58; integer;VAR   isSustained,noInput                   &#58; boolean;VAR   isEnabled                             &#58; Array of boolean;//////////////////////////////////////////////////////// initialize//////////////////////////////////////////////////////PROCEDURE init;    BEGIN      minChn &#58;= INPUT_COUNT - 1;   // these are initially set to their opposite extremes....    maxChn &#58;= 0;     minKey &#58;= 128;     maxKey &#58;= 0;        isSustained &#58;= FALSE;              setArrayLength&#40;noteList, 128&#41;;      FOR key&#58;=0 TO 127 DO BEGIN         noteList&#91;key&#93;&#58;=FALSE;    END;    SetArrayLength&#40;transList, 128&#41;;    FOR key&#58;=0 TO 127 DO BEGIN         transList&#91;key&#93;&#58;=0;    END;           setArrayLength&#40;midiIns, INPUT_COUNT&#41;;    setArrayLength&#40;enables, INPUT_COUNT&#41;;    FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        enables&#91;inputNum&#93;  &#58;= CreateParam&#40;'enable ' + intToStr&#40;inputNum + 1&#41;,ptSwitch&#41;;         SetValue&#40;enables&#91;inputNum&#93;, 1&#41;;               SetIsOutPut&#40;enables&#91;inputNum&#93;,false&#41;;            END;           octave      &#58;= CreateParam&#40;'octave',ptDataFader&#41;;          SetIsOutPut&#40;octave,false&#41;;    semi        &#58;= CreateParam&#40;'semi',ptDataFader&#41;;            SetIsOutPut&#40;semi,false&#41;;    SetFormat&#40;octave,'%.0f'&#41;; SetMin&#40;octave,-4&#41;;  SetMax&#40;octave,4&#41;;        SetFormat&#40;semi,'%.0f'&#41;;   SetMin&#40;semi,-7&#41;;    SetMax&#40;semi,7&#41;;      hiNote        &#58;= CreateParam&#40;'high note',ptMidiNoteFader&#41;;   SetIsOutPut&#40;hiNote,false&#41;;    lowNote       &#58;= CreateParam&#40;'low note',ptMidiNoteFader&#41;;    SetIsOutPut&#40;lowNote,false&#41;;      outChan       &#58;= CreateParam&#40;'output chan', ptDataFader&#41;;     SetIsOutPut&#40;outchan,false&#41;;     SetFormat&#40;outChan,'%.0f'&#41;; SetMin&#40;outChan,1&#41;;  SetMax&#40;outChan,16&#41;;    SetValue&#40;lowNote, 10&#41;;    SetValue&#40;hiNote, 115&#41;;      drone         &#58;= CreateParam&#40;'drone', ptSwitch&#41;;              SetIsOutput&#40;drone,false&#41;;    instBypass  &#58;= CreateParam&#40;'inst bypass', ptSwitch&#41;;       SetIsInput&#40;instBypass,false&#41;;      FOR inputNum &#58;= 0 TO INPUT_COUNT - 1 DO  BEGIN        midiIns&#91;inputNum&#93;  &#58;= CreateParam&#40;'MIDIin ' + intToStr&#40;inputNum + 1&#41; ,ptMidi&#41;;               SetIsOutPut&#40;midiIns&#91;inputNum&#93;,false&#41;;    END;        notesOut      &#58;= CreateParam&#40;'Notes Out',ptMidi&#41;;             SetIsInput&#40;notesOut,false&#41;;      otherOut      &#58;= CreateParam&#40;'other Out',ptMidi&#41;;             SetIsInput&#40;otherOut,false&#41;;      SetArrayLength&#40;isEnabled, INPUT_COUNT&#41;;    END;// <F> isNoteOn&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOn&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN       IF &#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2>0&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> isNoteOff&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isNoteOff&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN          IF &#40;midi.msg = NOTE_OFF&#41; OR &#40;&#40;midi.msg = NOTE_ON&#41; AND &#40;midi.data2 = 0&#41;&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;    END;END; // <F> isSusPed&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isSusPed&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;midi.msg = CONTROL&#41; AND &#40;midi.data1 = SUS_PED&#41; THEN BEGIN        result &#58;= true;    END    ELSE BEGIN        result &#58;= false;    END;END; // <F> isPitchBend&#58;  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// FUNCTION isPitchBend&#40;midi&#58; tMidi&#41;&#58; boolean;BEGIN     IF &#40;midi.msg = PITCHBEND&#41; THEN BEGIN         result &#58;= true;    END    ELSE BEGIN         result &#58;= false;     END;END;// <F> global function inRange--eliminates only noteons outside the range limits FUNCTION inRange&#40;midi&#58; tMidi&#41; &#58; boolean;BEGIN    IF &#40;isNoteOn&#40;midi&#41;&#41; AND &#40;midi.data1 > lowVal&#41; AND &#40;midi.data1 < hiVal&#41; THEN BEGIN        result &#58;= TRUE;    END    ELSE BEGIN        result &#58;= FALSE;    END; END;// <F> isClear//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//FUNCTION isClear&#40;&#41;  &#58; boolean;   // can we stop this loop as soon as a key = true??  Didn't like 'while'VAR clear &#58; boolean;BEGIN    clear &#58;= TRUE;    BEGIN        FOR key&#58;= minKey TO maxKey DO BEGIN                IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN                 clear &#58;= FALSE;                       END;                                                                  END;     END;    result &#58;= clear;     END;// <F> ReleaseNotes  --when you release the sustain, or release the drone, or change the output channel//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//PROCEDURE ReleaseNotes;BEGIN    FOR key&#58;= minKey TO maxKey DO BEGIN            IF &#40;noteList&#91;key&#93; = TRUE&#41; THEN BEGIN             noteOff.msg &#58;= NOTE_OFF;            noteOff.channel &#58;= outputChannel; // byte is a conversion--is this needed?            noteOff.data1 &#58;= key;            noteOff.data2 &#58;= 0;            setMidiArrayValue&#40;notesOut, notesOutCount, noteOff&#41;;  //danger when called from callback?            notesOutCount &#58;= notesOutCount + 1;            noteList&#91;key&#93; &#58;= FALSE;        END;                                                              END; END;    // Global Procedure StoreNoteOffs--just de-inlined for readability//----------------------------------------------//PROCEDURE StoreNoteOffs;BEGIN    IF &#40;midi.data1 > maxKey&#41; THEN BEGIN           maxKey &#58;= midi.data1;    END;    IF &#40;midi.data1 < minKey&#41; THEN BEGIN         minKey &#58;= midi.data1;     END;     noteList&#91;midi.data1&#93; &#58;= TRUE;END;// Callback//----------------------------------------------// procedure Callback&#40;n&#58;integer&#41;;BEGIN    // get input values        hiVal &#58;= trunc&#40;getValue&#40;hiNote&#41;&#41;;    lowVal &#58;= trunc&#40;getValue&#40;lowNote&#41;&#41;;    octVal &#58;= trunc&#40;getValue&#40;octave&#41;&#41;;    semival &#58;= trunc&#40;getValue&#40;semi&#41;&#41;;    transpose &#58;= &#40;octVal * 12&#41; + semiVal;writeln&#40;'transpose = ' + intToStr&#40;transpose&#41;&#41;;    outputChannel &#58;= trunc&#40;getValue&#40;outChan&#41;&#41;;    // see if any input is enabled....    noInput &#58;= TRUE;                                             FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO     BEGIN        IF getValue&#40;enables&#91;inputNum&#93;&#41; = 1 THEN BEGIN            isEnabled&#91;inputNum&#93; &#58;= TRUE;             noInput &#58;= FALSE;        END        ELSE BEGIN            isEnabled&#91;inputNum&#93; &#58;= FALSE;        END;    END;            // release notes if the drone has just been turned off, or if all inputs and notes are off, or if the channel is changed    IF &#40;&#40;n = drone&#41; and &#40;getValue&#40;drone&#41; = 0&#41;&#41; OR        &#40;&#40;noInput = TRUE&#41; AND &#40;isClear&#40;&#41; = TRUE&#41;&#41;       OR &#40;n = outChan&#41;                    THEN     BEGIN        releaseNotes;               // can I call this from callback?        setValue&#40;instBypass, 1&#41;;    END    ELSE BEGIN        setValue&#40;instBypass, 0&#41;;    END;END;  //////////////////////////////////////////////////////// process//////////////////////////////////////////////////////PROCEDURE PROCESS;BEGIN     FOR inputNum &#58;= 0 to INPUT_COUNT - 1 DO BEGIN                    midiInCount &#58;= getLength&#40;midiIns&#91;inputNum&#93;&#41;;    IF &#40;midiInCount > 0&#41; THEN BEGIN            notesOutCount &#58;= 0;            otherOutCount &#58;= 0;                FOR byteNum &#58;= 0 TO &#40;midiInCount - 1&#41; DO BEGIN   // process input                                       getMidiArrayValue&#40;midiIns&#91;inputNum&#93;, byteNum, midi&#41;;                midi.channel &#58;= outputChannel;                 If isSusPed&#40;midi&#41; THEN BEGIN                              if &#40;midi.data2 > 64&#41; THEN BEGIN                        isSustained &#58;= true;                    END                    ELSE BEGIN                                                 isSustained &#58;= false;                          ReleaseNotes;          // send noteoffs when the sus pedal is released                    END;                                              END;                 IF isNoteOn&#40;midi&#41; AND &#40;inRange&#40;midi&#41;&#41; AND &#40;isEnabled&#91;inputNum&#93;&#41; THEN BEGIN //note on, sus on, store and send                    IF &#40;isSustained = TRUE&#41; THEN BEGIN                                   StoreNoteOffs;                                      setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                    END                                          ELSE BEGIN                                        // valid noteon, sus off, send it out                        transList&#91;midi.data1&#93; &#58;= transpose;                         midi.data1 &#58;= midi.data1 + transpose;                                        setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                     END;                END                ELSE IF isNoteOff&#40;midi&#41; AND &#40;isSustained = FALSE&#41;  THEN BEGIN // valid noteoff, sus off, send it out                        midi.data1 &#58;= midi.data1 + transList&#91;midi.data1&#93;;                                         setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                        notesOutCount &#58;= notesOutCount + 1;                                 END                                     ELSE IF isPitchBend&#40;midi&#41; THEN BEGIN                        // send PB along with the notes                                                 midi.channel &#58;= outputChannel;                                    setMidiArrayValue&#40;notesOut, notesOutCount, midi&#41;;                    notesOutCount &#58;= notesOutCount + 1;                END                ELSE IF &#40;NOT&#40;isNoteOn&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isNoteOff&#40;midi&#41;&#41;&#41; AND &#40;NOT&#40;isPitchBend&#40;midi&#41;&#41;&#41; THEN BEGIN  //not a note, pb or sus pedal event                    setMidiArrayValue&#40;otherOut, otherOutCount, midi&#41;;                    otherOutCount &#58;= otherOutCount + 1;                END;                               END;                        // process input            setLength&#40;notesOut, notesOutCount&#41;;            setLength&#40;otherOut, otherOutCount&#41;;                    END        ELSE BEGIN             setLength&#40;notesOut,0&#41;;            setLength&#40;otherOut, 0&#41;;         END;    END;  END;
Does it do this for you???

Statistics: Posted by woodslanding — 24 Nov 2009, 09:00


]]>
2009-11-24T09:14:34+02:00 2009-11-24T09:14:34+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10741#p10741 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by bsork — 24 Nov 2009, 08:14


]]>
2009-11-24T08:13:36+02:00 2009-11-24T08:13:36+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10740#p10740 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]> Statistics: Posted by woodslanding — 24 Nov 2009, 07:13


]]>
2009-11-23T22:52:03+02:00 2009-11-23T22:52:03+02:00 https://brainmodular.org/forums/viewtopic.php?t=1777&p=10736#p10736 <![CDATA[Question #1: What MIDI Mapper functions would you like to see in V5?]]>
As long as you're defining your variables globally you can access them from anywhere in the script. (Well, I suppose they have to be declared before getting used. ;)) Within the scripts themselves, there are no differences between the Init, Callback and Process methods and the procedures and/or functions you declare yourself, except for when they are called. Regarding Callback you have to remember that it's called once for each parameter that's changed within the block, so if you have a patch where several parameters may be updated simultaneously (on a recall of preset for instance), and you do a lot of computing with these parameters, it can be wise to use a boolean (doUpdate := TRUE) in Callback, and check that boolean in Process. As far as I can tell, all the Callback calls happen before Process is called.

Eg:

CODE:

VAR pParam1, pParam2, pParam3 &#58; tParameter;VAR param1, param2, param3 &#58; single;VAR doUpdate &#58; boolean;....PROCEDURE Init;BEGIN   pParam1 &#58;= CreateParam&#40;'param 1', ...   pParam2 &#58;= CreateParam&#40;'param 2', ...   pParam3 &#58;= CreateParam&#40;'param 3', ...   doUpdate &#58;= FALSE;END;PROCEDURE GetParams;BEGIN    param1 &#58;= GetValue&#40;pParam1&#41;;    param2 &#58;= GetValue&#40;pParam2&#41;;    param3 &#58;= GetValue&#40;pParam3&#41;; END;PROCEDURE Callback&#40;n ; integer&#41;;BEGIN   // You can of course use IF-statements instead of CASE   CASE n OF       pParam1 &#58; doUpdate &#58;= TRUE;       pParam2 &#58; doUpdate &#58;= TRUE;       pParam3 &#58; doUpdate &#58;= TRUE;   END;END;PROCEDURE Process;BEGIN   IF &#40;doUpdate&#41; THEN BEGIN      GetParams;      doUpdate &#58;= FALSE;   END;   ...END;
To sum up:
Init is called only when compiling, that means only once, so as well defining input/output parameters, put all code that initializes variables (values, array lengths, ...) in here.
Callback is called every time an input parameter is changed, and can be called several times within the same block.
Process is called once for each block.
You can create a script with only the Init procedure, bot mostly you would want to use either Callback or Process or both as well.

Did that help?

Statistics: Posted by bsork — 23 Nov 2009, 21:52


]]>