Page 1 of 1

Posted: 20 Nov 2010, 18:41
by ethnix73
I'm always a noob script but i would like to use this script found in the matrix pack.

I want to use it with my launchpad patch, but i'm really enable to modify it...

Is there any script guru who could help me to add velocity and note lenght to this script?

Code: Select all

//////////////////////////
// 
/////////////////////////
// parameters declaration
var RowIn        : Tparameter;
var OnModeIn     : Tparameter;
var OffModeIn    : Tparameter;
var BaseOctaveIn : Tparameter;
var TickIn       : Tparameter;
var MidiOut      : Tparameter;

var BaseOctave      : integer;
var NbOfMidiNotes   : integer;
var OnMode          : integer;
var OffMode         : integer;
var PlayNotes       : boolean;
var CurrentNotes    : array of single;
var CurrentNotesLen : integer;
var LastNotes       : array of single;

CONST MID_NOTE_ON   = 144;
CONST MID_VOL_RANGE = 127;

CONST OCTAVE_RANGE  = 12;
CONST ON_MODE       = '"each","group"';
CONST OFF_MODE      = '"hold","cut"';
 
// initialisation : create parameters
procedure init;
begin  
 
 RowIn := CreateParam('row in',ptArray);
 SetIsOutput(RowIn,false);
 
 OnModeIn := CreateParam('on mode',ptListBox);
 SetIsOutput(OnModeIn,false);
 SetListBoxString(OnModeIn,ON_MODE);
 
 OffModeIn := CreateParam('off mode',ptListBox);
 SetIsOutput(OffModeIn,false);
 SetListBoxString(OffModeIn,OFF_MODE);
 
 BaseOctaveIn := CreateParam('octave',ptDataFader);
 SetIsOutput    (BaseOctaveIn,false);
 SetMin	        (BaseOctaveIn , 1);  
 SetMax	        (BaseOctaveIn , 10); 
 SetDefaultValue(BaseOctaveIn , 5); 
 SetFormat      (BaseOctaveIn , '%.0f'); 
 
 TickIn := CreateParam('tick',ptButton);
 SetIsOutput(RowIn,false);
 
 MidiOut := CreateParam('midi out',ptMidi);
 SetIsInput(MidiOut,false);

 BaseOctave := 5;
 NbOfMidiNotes := 0;
 OnMode := 0;
 OffMode := 0;
 PlayNotes := FALSE;
 SetArrayLength(CurrentNotes , 0);
 CurrentNotesLen := 0;
end;

// Global variables
var Miditmp      : TMidi;

//////////////////////////////
// callback proc
//////////////////////////////
procedure Callback(n:integer);
var i : integer;
var vol : single;
begin
    if (n = RowIn) then begin
        CurrentNotesLen := GetLength(RowIn);

        SetArrayLength(CurrentNotes , CurrentNotesLen);
        SetArrayLength(LastNotes , CurrentNotesLen);
        i := 0;
        while i < CurrentNotesLen  do begin
            
            vol &#58;= GetDataArrayValue&#40;RowIn, i&#41;;
            CurrentNotes&#91;i&#93; &#58;= vol;     
            i &#58;= i+1;
        end;
    end
    else if &#40;n = OnModeIn&#41; then begin
        OnMode &#58;= round&#40; GetValue&#40;OnModeIn&#41; &#41;;
    end
    else if &#40;n = OffModeIn&#41; then begin
        OffMode &#58;= round&#40; GetValue&#40;OffModeIn&#41; &#41;;
    end
    else if &#40;n = BaseOctaveIn&#41; then begin
        BaseOctave &#58;= round&#40; GetValue&#40;BaseOctaveIn&#41; &#41;;
    end
    else if &#40;n = TickIn&#41; then begin
        
        NbOfMidiNotes &#58;= 0; 
        
        i &#58;= 0;
        while i < CurrentNotesLen  do begin

            if &#40;&#40;OnMode = 1&#41; and  &#40;CurrentNotes&#91;i&#93; <> LastNotes&#91;i&#93;&#41; and  &#40;CurrentNotes&#91;i&#93; > 0&#41;&#41;
            or &#40;&#40;OnMode = 0&#41; and  &#40;CurrentNotes&#91;i&#93; > 0&#41;&#41;
            or &#40;&#40;OffMode = 1&#41; and  &#40;CurrentNotes&#91;i&#93; = 0&#41;&#41;
            then begin
                Miditmp.Channel &#58;= byte&#40;1&#41;;
                Miditmp.Msg &#58;= MID_NOTE_ON;
                Miditmp.Data1 &#58;= byte&#40; &#40;BaseOctave * OCTAVE_RANGE&#41; + i&#41;;
                Miditmp.Data2 &#58;= round&#40;MID_VOL_RANGE * CurrentNotes&#91;i&#93;&#41;;

                SetMidiArrayValue&#40;MidiOut, NbOfMidiNotes ,Miditmp&#41;;  // set output value
                NbOfMidiNotes &#58;= NbOfMidiNotes + 1;
            end; 
            LastNotes&#91;i&#93; &#58;= CurrentNotes&#91;i&#93;;    
            i &#58;= i+1;
        end;
        SetLength&#40;MidiOut,NbOfMidiNotes&#41;; 
        PlayNotes &#58;= TRUE;
    end;
end;


//////////////////////////////
// main proc
//////////////////////////////
Procedure Process;
var i &#58; integer;
var len &#58; integer;
var vol &#58; single;
begin
    if PlayNotes then  begin
        PlayNotes &#58;= FALSE;
    end
    else begin
        SetLength&#40;MidiOut,0&#41;;
    end;
end;

Posted: 21 Nov 2010, 15:43
by 23fx23
mm it 's strange caus it seems it was coded in,

i still fight a bit with midi and script, but ill try to have a look tonight.

but if martin watch i thinks this one is from him.

Posted: 24 Nov 2010, 00:15
by martignasse
hi ethnix73,

arf, it's a pretty tricky script you try to custom here :rolleyes: (the hard way to learn script...23fx23 is kind of unique about learning curve;) )

anyway, if i remember correctly, we speak about the 'arr to midi' script of the 'matrix_fall_seq_example'

the note length is just a matter of note on and note off time laps.
in this script, 'on mode' and 'off mode' trigger when we should fire a note on and a note off, finally, it's processed in the 'else if (n = TickIn) then begin' section.

velocity, isn't triggered in this script, but i believe it's just a matter of multiplying the volume by the velocity (i'm not a midi master...)

hope it help

Posted: 24 Nov 2010, 00:47
by 23fx23
mmm now i think i remember im pretty sure i already moded it to add velocity in my MX_zoom_sequencer patch, gonna check it now

edit: mmm yes it seems, maybe try this one:

Code: Select all

//////////////////////////
// 
/////////////////////////
// parameters declaration
var RowIn        &#58; Tparameter;
var OnModeIn     &#58; Tparameter;
var OffModeIn    &#58; Tparameter;
var BaseOctaveIn &#58; Tparameter;
var TickIn       &#58; Tparameter;
var MidiOut      &#58; Tparameter;

var BaseOctave      &#58; integer;
var NbOfMidiNotes   &#58; integer;
var OnMode          &#58; integer;
var OffMode         &#58; integer;
var PlayNotes       &#58; boolean;
var CurrentNotes    &#58; array of single;
var CurrentNotesLen &#58; integer;
var LastNotes       &#58; array of single;

CONST MID_NOTE_ON   = 144;
CONST MID_NOTE_OFF  = 128;
CONST MID_VOL_RANGE = 127;

CONST OCTAVE_RANGE  = 12;
CONST ON_MODE       = '"each","group"';
CONST OFF_MODE      = '"hold","cut"';
 
// initialisation &#58; create parameters
procedure init;
begin  
 
 RowIn &#58;= CreateParam&#40;'row in',ptArray&#41;;
 SetIsOutput&#40;RowIn,false&#41;;
 
 OnModeIn &#58;= CreateParam&#40;'on mode',ptListBox&#41;;
 SetIsOutput&#40;OnModeIn,false&#41;;
 SetListBoxString&#40;OnModeIn,ON_MODE&#41;;
 
 OffModeIn &#58;= CreateParam&#40;'off mode',ptListBox&#41;;
 SetIsOutput&#40;OffModeIn,false&#41;;
 SetListBoxString&#40;OffModeIn,OFF_MODE&#41;;
 
 BaseOctaveIn &#58;= CreateParam&#40;'octave',ptDataFader&#41;;
 SetIsOutput    &#40;BaseOctaveIn,false&#41;;
 SetMin	        &#40;BaseOctaveIn , 1&#41;;  
 SetMax	        &#40;BaseOctaveIn , 10&#41;; 
 SetDefaultValue&#40;BaseOctaveIn , 5&#41;; 
 SetFormat      &#40;BaseOctaveIn , '%.0f'&#41;; 
 
 TickIn &#58;= CreateParam&#40;'tick',ptButton&#41;;
 SetIsOutput&#40;RowIn,false&#41;;
 
 MidiOut &#58;= CreateParam&#40;'midi out',ptMidi&#41;;
 SetIsInput&#40;MidiOut,false&#41;;

 BaseOctave &#58;= 5;
 NbOfMidiNotes &#58;= 0;
 OnMode &#58;= 0;
 OffMode &#58;= 0;
 PlayNotes &#58;= FALSE;
 SetArrayLength&#40;CurrentNotes , 0&#41;;
 CurrentNotesLen &#58;= 0;
end;

// Global variables
var Miditmp      &#58; TMidi;

//////////////////////////////
// callback proc
//////////////////////////////
procedure Callback&#40;n&#58;integer&#41;;
var i &#58; integer;
var vol &#58; single;
begin
    if &#40;n = RowIn&#41; then begin
        CurrentNotesLen &#58;= GetLength&#40;RowIn&#41;;

        SetArrayLength&#40;CurrentNotes , CurrentNotesLen&#41;;
        SetArrayLength&#40;LastNotes , CurrentNotesLen&#41;;
        i &#58;= 0;
        while i < CurrentNotesLen  do begin
            
            vol &#58;= GetDataArrayValue&#40;RowIn, i&#41;;
            CurrentNotes&#91;i&#93; &#58;= vol;     
            i &#58;= i+1;
        end;
    end
    else if &#40;n = OnModeIn&#41; then begin
        OnMode &#58;= round&#40; GetValue&#40;OnModeIn&#41; &#41;;
    end
    else if &#40;n = OffModeIn&#41; then begin
        OffMode &#58;= round&#40; GetValue&#40;OffModeIn&#41; &#41;;
    end
    else if &#40;n = BaseOctaveIn&#41; then begin
        BaseOctave &#58;= round&#40; GetValue&#40;BaseOctaveIn&#41; &#41;;
    end
    else if &#40;n = TickIn&#41; then begin
        
        NbOfMidiNotes &#58;= 0; 
        
        i &#58;= 0;
        while i < CurrentNotesLen  do begin

            if &#40;&#40;OnMode = 1&#41; and  &#40;CurrentNotes&#91;i&#93; <> LastNotes&#91;i&#93;&#41; and  &#40;CurrentNotes&#91;i&#93; > 0&#41;&#41;
            or &#40;&#40;OnMode = 0&#41; and  &#40;CurrentNotes&#91;i&#93; > 0&#41;&#41;
            or &#40;&#40;OffMode = 1&#41; and  &#40;CurrentNotes&#91;i&#93; = 0&#41;&#41;
            then begin
                Miditmp.Channel &#58;= byte&#40;1&#41;;
                 if currentNotes&#91;i&#93;>0 then begin
                    Miditmp.Msg &#58;= MID_NOTE_ON;
                    end
                    else begin
                    Miditmp.Msg &#58;= MID_NOTE_OFF;
                    end;
                Miditmp.Data1 &#58;= byte&#40; &#40;BaseOctave * OCTAVE_RANGE&#41; + i&#41;;
                Miditmp.Data2 &#58;= round&#40;MID_VOL_RANGE * CurrentNotes&#91;i&#93;&#41;;

                SetMidiArrayValue&#40;MidiOut, NbOfMidiNotes ,Miditmp&#41;;  // set output value
                NbOfMidiNotes &#58;= NbOfMidiNotes + 1;
            end; 
            LastNotes&#91;i&#93; &#58;= CurrentNotes&#91;i&#93;;    
            i &#58;= i+1;
        end;
        SetLength&#40;MidiOut,NbOfMidiNotes&#41;; 
        PlayNotes &#58;= TRUE;
    end;
end;


//////////////////////////////
// main proc
//////////////////////////////
Procedure Process;
var i &#58; integer;
var len &#58; integer;
var vol &#58; single;
begin
    if PlayNotes then  begin
        PlayNotes &#58;= FALSE;
    end
    else begin
        SetLength&#40;MidiOut,0&#41;;
    end;
end;

Posted: 24 Nov 2010, 00:49
by ethnix73
Thanks for your answer martignasse,

I will have a look, and make some try even if it's a hard way...
Anyway, learning script becomes more and more essential, so i will start with this one because i need it :)

Posted: 24 Nov 2010, 00:53
by ethnix73
yeah!

Thanks marvellous 23fx23!

I will try it on tomorrow morning...

Posted: 24 Nov 2010, 01:23
by 23fx23
@martin thx for wise wordz, but i started on much simpler thingz :)

@ethnix: note there is no lenght setting here but velocity should be ok as i can see it clicking on wire,

Also, it would need to be optimized by checking only the needed midi events and set the midiarray out of that size. actually, it is constantly of the row size, wich is probably ok for a 8x matrix, (i tested on a 32xok) but could be problematic with bigger matrixes
and could be a tiny lower cpu with optimized code.

Note lengh is another much harder challenge at it implies dealing with time variable internally, and ideally in a polyphonic way,
mean keep a track of wich notes were on, trig time counters for each ect. but i would also love to make a mx sequencer with two XY variables, one for velocity and one for lengh. think that's a pretty much harder scripting challenge, still possible.

I was thinking from a while of a different should be easier technique, instead of dealing midi inside the scripts, matrix would
remote the pianoroll, entering notes, length and velocity and so pianoroll would handle the midi playing , being able to save
or recall sequences, finer later editing ect without bothering complex scripting.
It should be pretty doable if olivier manage to make the events array in possible to receive infos ans spread the notes.

Posted: 24 Nov 2010, 10:18
by ethnix73
Thanks 23fx23,

First step with velocity (MidVolRange) inlet is done...

:)

Code: Select all

//////////////////////////
// 
/////////////////////////
// parameters declaration
var RowIn         &#58; Tparameter;
var OnModeIn      &#58; Tparameter;
var OffModeIn     &#58; Tparameter;
var MidVolRangeIn &#58; Tparameter;
var BaseOctaveIn  &#58; Tparameter;
var TickIn        &#58; Tparameter;
var MidiOut       &#58; Tparameter;

var BaseOctave      &#58; integer;
var NbOfMidiNotes   &#58; integer;
var OnMode          &#58; integer;
var OffMode         &#58; integer;
var PlayNotes       &#58; boolean;
var CurrentNotes    &#58; array of single;
var CurrentNotesLen &#58; integer;
var LastNotes       &#58; array of single;
var MidVolRange     &#58; integer;

CONST MID_NOTE_ON   = 144;
CONST MID_NOTE_OFF  = 128;

CONST OCTAVE_RANGE  = 12;
CONST ON_MODE       = '"each","group"';
CONST OFF_MODE      = '"hold","cut"';
 
// initialisation &#58; create parameters
procedure init;
begin  
 
 RowIn &#58;= CreateParam&#40;'row in',ptArray&#41;;
 SetIsOutput&#40;RowIn,false&#41;;
 
 MidVolRangeIn &#58;= CreateParam&#40;'MidVolRange',ptDataFader&#41;;
 SetIsOutput &#40;MidVolRangeIn,false&#41;;
 SetMin           &#40;MidVolRangeIn , 0&#41;;
 SetMax           &#40;MidVolRangeIn , 127&#41;;
 SetDefaultValue   &#40;MidVolRangeIn , 64&#41;;

 OnModeIn &#58;= CreateParam&#40;'on mode',ptListBox&#41;;
 SetIsOutput&#40;OnModeIn,false&#41;;
 SetListBoxString&#40;OnModeIn,ON_MODE&#41;;
 
 OffModeIn &#58;= CreateParam&#40;'off mode',ptListBox&#41;;
 SetIsOutput&#40;OffModeIn,false&#41;;
 SetListBoxString&#40;OffModeIn,OFF_MODE&#41;;
 
 BaseOctaveIn &#58;= CreateParam&#40;'octave',ptDataFader&#41;;
 SetIsOutput    &#40;BaseOctaveIn,false&#41;;
 SetMin            &#40;BaseOctaveIn , 1&#41;;  
 SetMax            &#40;BaseOctaveIn , 10&#41;; 
 SetDefaultValue&#40;BaseOctaveIn , 5&#41;; 
 SetFormat      &#40;BaseOctaveIn , '%.0f'&#41;; 
 
 TickIn &#58;= CreateParam&#40;'tick',ptButton&#41;;
 SetIsOutput&#40;RowIn,false&#41;;
 
 MidiOut &#58;= CreateParam&#40;'midi out',ptMidi&#41;;
 SetIsInput&#40;MidiOut,false&#41;;

 BaseOctave &#58;= 5;
 MidVolRange &#58;=64;
 NbOfMidiNotes &#58;= 0;
 OnMode &#58;= 0;
 OffMode &#58;= 0;
 PlayNotes &#58;= FALSE;
 SetArrayLength&#40;CurrentNotes , 0&#41;;
 CurrentNotesLen &#58;= 0;
end;

// Global variables
var Miditmp      &#58; TMidi;

//////////////////////////////
// callback proc
//////////////////////////////
procedure Callback&#40;n&#58;integer&#41;;
var i &#58; integer;
var vol &#58; single;
begin
    if &#40;n = RowIn&#41; then begin
        CurrentNotesLen &#58;= GetLength&#40;RowIn&#41;;

        SetArrayLength&#40;CurrentNotes , CurrentNotesLen&#41;;
        SetArrayLength&#40;LastNotes , CurrentNotesLen&#41;;
        i &#58;= 0;
        while i < CurrentNotesLen  do begin
            
            vol &#58;= GetDataArrayValue&#40;RowIn, i&#41;;
            CurrentNotes&#91;i&#93; &#58;= vol;     
            i &#58;= i+1;
        end;
    end
    else if &#40;n = OnModeIn&#41; then begin
        OnMode &#58;= round&#40; GetValue&#40;OnModeIn&#41; &#41;;
    end
    else if &#40;n = OffModeIn&#41; then begin
        OffMode &#58;= round&#40; GetValue&#40;OffModeIn&#41; &#41;;
    end
    else if &#40;n=MidVolRangeIn&#41; then begin
         MidVolRange &#58;= round&#40; GetValue&#40;MidVolRangeIn&#41; &#41;;
    end
    else if &#40;n = BaseOctaveIn&#41; then begin
        BaseOctave &#58;= round&#40; GetValue&#40;BaseOctaveIn&#41; &#41;;
    end
    else if &#40;n = TickIn&#41; then begin
        
        NbOfMidiNotes &#58;= 0; 
        
        i &#58;= 0;
        while i < CurrentNotesLen  do begin

            if &#40;&#40;OnMode = 1&#41; and  &#40;CurrentNotes&#91;i&#93; <> LastNotes&#91;i&#93;&#41; and  &#40;CurrentNotes&#91;i&#93; > 0&#41;&#41;
            or &#40;&#40;OnMode = 0&#41; and  &#40;CurrentNotes&#91;i&#93; > 0&#41;&#41;
            or &#40;&#40;OffMode = 1&#41; and  &#40;CurrentNotes&#91;i&#93; = 0&#41;&#41;
            then begin
                Miditmp.Channel &#58;= byte&#40;1&#41;;
                 if currentNotes&#91;i&#93;>0 then begin
                    Miditmp.Msg &#58;= MID_NOTE_ON;
                    end
                    else begin
                    Miditmp.Msg &#58;= MID_NOTE_OFF;
                    end;
                Miditmp.Data1 &#58;= byte&#40; &#40;BaseOctave * OCTAVE_RANGE&#41; + i&#41;;
                Miditmp.Data2 &#58;= round&#40;MidVolRange * CurrentNotes&#91;i&#93;&#41;;

                SetMidiArrayValue&#40;MidiOut, NbOfMidiNotes ,Miditmp&#41;;  // set output value
                NbOfMidiNotes &#58;= NbOfMidiNotes + 1;
            end; 
            LastNotes&#91;i&#93; &#58;= CurrentNotes&#91;i&#93;;    
            i &#58;= i+1;
        end;
        SetLength&#40;MidiOut,NbOfMidiNotes&#41;; 
        PlayNotes &#58;= TRUE;
    end;
end;


//////////////////////////////
// main proc
//////////////////////////////
Procedure Process;
var i &#58; integer;
var len &#58; integer;
var vol &#58; single;
begin
    if PlayNotes then  begin
        PlayNotes &#58;= FALSE;
    end
    else begin
        SetLength&#40;MidiOut,0&#41;;
    end;
end;

Posted: 24 Nov 2010, 11:08
by 23fx23
cool! well done.

Posted: 24 Nov 2010, 11:29
by nay-seven
great !
don't have test but in the old matrix_fall_seq_example, the fade mode send velocity too , so what the difference precisely with yours.?

Posted: 24 Nov 2010, 13:05
by 23fx23
mmm yes that's why i had doubts saying it was already coded, you re right.

don't remember what i moded then, and why but i definitely changed something lol
now checkin booth i see the script is different in a section where i put something that seems to make a note off when cell is 0,
the other was not really muting the note by sending a noteoff, but sending a velocity of 0 if i well remember or something like that.
to be honest i don't remember , but i needed that to fix something lol

Posted: 24 Nov 2010, 13:16
by ethnix73
There is an inlet for velocity. So you can set different velocities for each note (=column) in toggle mode with an another matrix for example.

This is not the "lighter on cpu" solution but i needed it for an important modification for the base patch for the launchpad, to make it polyphonic...I decided to use different matrix module for note, velo, octave and lenght settings.

Posted: 24 Nov 2010, 13:21
by nay-seven
ok, thanks, that make sense, could be useful