Welcome to %s forums

BrainModular Users Forum

Login Register

my script is sending undesired noteoffs

I need help on a Patch
Post Reply
woodslanding
Member
Posts: 1327
Contact:

Unread post by woodslanding » 04 Nov 2008, 02:59

can anyone tell me why my script is sending noteoffs when I use the expression2 controller? (presumably expression1 also does it, but I haven't checked that) It's also correctly sending out expression values.... these noteoffs SEEM to be causing clicks in the B4, but that may be zipper noise..... not sure

Code: Select all

TYPE tTransp = ARRAY OF integer;
VAR transpositions : ARRAY OF tTransp;

// parameters declaration
var input    : Tparameter;   // midi input
var output   : Tparameter;   // midi output

var key1     : Tparameter;   // output notes from keyboard 1
var key2     : Tparameter;   // output notes from keyboard 2
var exp      : Tparameter;   // send out a volume control signal
var out1on   : Tparameter;   // enable output 1
var out2on   : Tparameter;   // enable output 2
var disable  : Tparameter;   // boolean control out for disabling VST if no keyboard is controlling it


var semi     : TParameter;   // transpose by semi-tone
var octave   : TParameter;   // transpose by octave
var split    : Tparameter;   // pitch below or above which notes are not sent
var upper    : Tparameter;   // send pitches above the split if on.  otherwise send pitches below.

var outCH    : Tparameter;   // rechannelize input.  Value of 0 leaves input channel unchanged


var exp1ch        : integer;
var exp1cc        : integer;
var exp2ch        : integer;
var exp2cc        : integer;
var exp1val      : single;
var exp2val      : single;
var outputCH     : integer;
var bytecount    : integer;
var midiLen      : integer;
var midi         : TMidi;
var transpose    : integer;
var splitVal     : integer;
var upperVal     : integer;
var key1Val      : integer;
var key2Val      : integer;
var key1ch       : integer;
var key2ch       : integer;
var i            : integer;
var channel      : integer;
var noteCount    : integer;
var disabled     : boolean;



// initialisation 
PROCEDURE init;
BEGIN  
 
    output := CreateParam('MIDIout',ptMidi);           SetIsInput(Output,false); 
    key1 := CreateParam('key1', ptSwitch);             SetIsOutput(key1,false);
    key2 := CreateParam('key2', ptSwitch);             SetIsOutput(key2,false);
    split := CreateParam('split',ptMidiNoteFader);     SetIsOutput(split,false);
    upper := CreateParam('upper',ptSwitch);            SetIsOutput(upper,false);
    
    exp := CreateParam('expression',ptDataField);       SetIsInput(exp,false);
    out1on := CreateParam('out1 enable',ptDataField);       SetIsInput(out1on,false);
    out2on := CreateParam('out2 enable',ptDataField);       SetIsInput(out2on,false);
    
    disable := CreateParam('vstBypass',ptDataField);   SetIsInput(disable,false);
    input := CreateParam('MIDIin',ptMidi);             SetIsOutput(Input,false);
    semi := CreateParam('semi',ptDataField);           SetIsOutput(semi,false);
    octave := CreateParam('8va',ptDataField);          SetIsOutput(octave,false);  
    outCH := CreateParam('outCH', ptDataField);        SetIsOutput(outCH,false);

 key1ch := 1;   
 key2ch := 2;
 exp1ch := 1;
 exp1cc := 4;
 exp2ch := 2;
 exp2cc := 3;
 

 noteCount := 0;
 
 SetArrayLength(transpositions, 2);
 FOR i := 0 TO 1 DO // we are going to ignore midi data on any but the 2 keyboard channels...
    SetArrayLength(transpositions[i], 128);
 
 //default values and formats
 SetDefaultValue(upper,1);
 SetDefaultValue(key1,1);
 SetDefaultValue(key2,1);

 SetFormat(split,'%.0f');
 SetMin(split,1);
 SetMax(split,127);
 SetDefaultValue(split,1);

 SetFormat(semi,'%.0f');
 SetMin(semi,-7);
 SetMax(semi,7);
 SetDefaultValue(semi,0);

 SetFormat(octave,'%.0f');
 SetMin(octave,-4);
 SetMax(octave,4);
 SetDefaultValue(octave,0);

 SetDefaultValue(outCH,1);

end;


PROCEDURE CreateOut(ch, msg, data1, data2 : integer);
BEGIN
   midi.msg := byte(msg);
   midi.data1 := byte(data1);
   midi.data2 := byte(data2);
   midi.channel := byte(ch);
   SetMidiArrayValue(output, bytecount, midi);   
END; // CreateOut

PROCEDURE processNoteOns;
BEGIN
    //writeln('in noteon loop');
    IF (((channel = key1ch) AND (key1Val = 1)) OR ((channel = key2ch) AND (key2Val = 1))) 
       AND &#40;&#40;&#40;midi.data1 >= splitVal&#41; AND &#40;upperVal = 1&#41;&#41; OR &#40;&#40;midi.data1 < splitVal&#41; AND &#40;upperVal = 0&#41;&#41;&#41;
    THEN BEGIN        
        transpositions&#91;channel - 1&#93;&#91;midi.data1&#93; &#58;= transpose;              // only works if keyboard ch's are 1 and 2....
        midi.data1 &#58;= midi.data1 + transpose;
        midi.channel &#58;= outputCH;
        SetMidiArrayValue&#40;output, bytecount, midi&#41;;
        //noteCount &#58;= noteCount + 1;  // increase count of held notes
        
    END;  
        
END;   //process Noteons

PROCEDURE processNoteOffs;
BEGIN
    midi.data1 &#58;= midi.data1 + transpositions&#91;channel - 1&#93;&#91;midi.data1&#93;; // Retrieve stored transpose and add to NoteOff
    midi.channel &#58;= outputCH; 
    SetMidiArrayValue&#40;output, bytecount, midi&#41;;
    //noteCount &#58;= noteCount - 1;      // decrease count of held notes
    writeln&#40;'in notes off = ' + intToStr&#40;noteCount&#41;&#41;;
END;  //processNoteoffs

PROCEDURE processSustain;
BEGIN
    IF &#40;midi.data2 < 64&#41; THEN   //send sus up on all instruments, selected or not...
        BEGIN
            midi.channel &#58;= outputCH;
            SetMidiArrayValue&#40;output, bytecount, midi&#41;;
        END
    ELSE IF &#40;&#40;&#40;channel = 1&#41; AND &#40;key1Val = 1&#41;&#41; OR &#40;&#40;channel = 2&#41; AND &#40;key2Val = 1&#41;&#41;&#41; THEN
    BEGIN
        IF &#40;midi.data2 >= 64&#41;  THEN  //send sus down only on selected instruments
        BEGIN 
            midi.channel &#58;= outputCH;   
            SetMidiArrayValue&#40;output, bytecount, midi&#41;;
        END;
    END;
END;   // process sustain

PROCEDURE disableVST;  // not used yet
BEGIN
   disabled &#58;= &#40; &#40;key1val = 0&#41; AND &#40;key2val = 0&#41;&#41;;
//   IF &#40;disabled&#41; THEN
      // wait until all notes are off before doing this--how??
      // and don't undo it when notes are back on!
//      IF &#40;noteCount = 0&#41; THEN
//      BEGIN
//          CreateOut&#40;outputCH, 208, 0, 0&#41;;   //reset aftertouch
//          CreateOut&#40;outputCH, 224, 0, 64&#41;;  //reset pitchbend
//          CreateOut&#40;outputCH, 176, 1, 0&#41;;   //reset mod wheel  
//          setValue&#40;disable, 1&#41;;
//          setValue&#40;out1on, 0&#41;;
//          setValue&#40;out2on, 0&#41;; 
//      END
//      ELSE BEGIN
//          setValue&#40;disable, 0&#41;;
//      END
//   ELSE
        setValue&#40;disable, 0&#41;;  
END;  // disable vst

PROCEDURE processExpression1;
BEGIN
    exp1val &#58;= &#40;midi.data2&#41;/128;
    setValue&#40;exp, exp1val&#41;; 
    
END;

PROCEDURE processExpression2;
BEGIN
    exp2val &#58;= &#40;midi.data2&#41;/128;
    setValue&#40;exp, exp2Val&#41;; 
    
END;

PROCEDURE processControllers;
BEGIN
    SetMidiArrayValue&#40;output, bytecount, midi&#41;; 
    
END;

        
// main
BEGIN
   
   // set variables from inputs
   transpose &#58;= trunc&#40;GetValue&#40;semi&#41; + &#40;&#40;getValue&#40;octave&#41; * 12&#41;&#41;&#41;;
   splitVal  &#58;= trunc&#40;getValue&#40;split&#41;&#41;;
   upperVal  &#58;= trunc&#40;getValue&#40;upper&#41;&#41;;
   key1Val   &#58;= trunc&#40;getValue&#40;key1&#41;&#41;;
   key2Val   &#58;= trunc&#40;getValue&#40;key2&#41;&#41;;
   outputCh  &#58;= trunc&#40;getValue&#40;outCH&#41;&#41;;

   // disable the VST if nothing is controlling it
   disableVST;
   setValue&#40;out1on, key1val&#41;;
   setValue&#40;out2on, key2val&#41;;
  

    
  
   midiLen &#58;= GetLength&#40;input&#41;;
   IF &#40;midiLen > 0&#41;  THEN
   BEGIN
        SetLength&#40;output, midiLen&#41;;
       
        // process midi
        
        FOR bytecount &#58;= 0 TO &#40;midiLen - 1&#41; DO 
        BEGIN
            GetMidiArrayValue&#40;input, bytecount, midi&#41;;
            channel &#58;= midi.channel;
            IF &#40;&#40;midi.msg = 144&#41; AND &#40;midi.data2 > 0&#41;&#41; 
            THEN BEGIN           // Noteon
                processNoteons;       
            END
            ELSE IF &#40;&#40;midi.msg = 128&#41;
                OR  &#40;&#40;midi.msg = 144&#41; AND &#40;midi.data2 = 0&#41;&#41;&#41; THEN
            BEGIN      // NoteOff
                processNoteoffs;
            END
            ELSE IF &#40;midi.msg = 176&#41; AND &#40;midi.data1 = 64&#41; THEN
            BEGIN
                processSustain;
            END
            ELSE IF &#40;midi.msg = 176&#41; AND &#40;midi.channel = exp1ch&#41; AND &#40;midi.data1 = exp1cc&#41; THEN
            BEGIN
                processExpression1;
            END
            ELSE IF &#40;midi.msg = 176&#41; AND &#40;midi.channel = exp2ch&#41; AND &#40;midi.data1 = exp2cc&#41; THEN
            BEGIN
                processExpression2;
            END 
            ELSE IF &#40;midi.msg = 176&#41; THEN
            BEGIN
                processControllers;
            END; 
                       
        END;
      
    END
        

    // no midi in this block....
    ELSE BEGIN
        SetLength&#40;output, 0&#41;;
    END;
END.
thanks as ever for any help!!

-e
Custom Ryzen 5900x MATX build, Win10, Fireface UFX, touchscreen
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify

bsork
Site Admin
Posts: 1334
Location: Asker, Norway
Contact:

Unread post by bsork » 04 Nov 2008, 08:20

Hi, I have had a quick look, and haven't found anything particular about the expression error as such, but you have made an error with the length of the output array. As long as you're not sending out the same number of messages as you get in, you can't use the length of the input array but have to create a counter to increment with 1 for each new message you add to the output, and then set the length of the MIDI array at the end with that variable.

Another small thing: Shouldn't the processExpression use midi.data2/127 instead of 128? With 128 you'll never get the max value 1.
Bjørn S

amiga909
Member
Posts: 324
Contact:

Unread post by amiga909 » 04 Nov 2008, 08:28

why do u use SetValue instead of 'SetMidiArrayValue(output, bytecount, midi);' (in expr1+2 proc)?
about the note offs I dont know. make sure the noteOffs are not already in the input (maybe uncheck NoteOff = noteOn AND velocity=0)

woodslanding
Member
Posts: 1327
Contact:

Unread post by woodslanding » 04 Nov 2008, 09:15

bsork wrote:Hi, I have had a quick look, and haven't found anything particular about the expression error as such, but you have made an error with the length of the output array. As long as you're not sending out the same number of messages as you get in, you can't use the length of the input array but have to create a counter to increment with 1 for each new message you add to the output, and then set the length of the MIDI array at the end with that variable.

Another small thing: Shouldn't the processExpression use midi.data2/127 instead of 128? With 128 you'll never get the max value 1.
Should it be 127?? Okay! I didn't realize that.

I see what you mean about the output array (sort of--it's all a bit unclear how it actually works) so I will keep an independent counter.

I'm sending out expression as a data out, not a midi out.....

I'll see if this helps...
Custom Ryzen 5900x MATX build, Win10, Fireface UFX, touchscreen
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify

Post Reply

Who is online

Users browsing this forum: No registered users and 35 guests