Welcome to %s forums

BrainModular Users Forum

Login Register

Writing scripts

I need help on a Patch
Post Reply
Vincent

Unread post by Vincent » 12 Feb 2007, 03:14

Hi.

Could someone give me an example of a "SELECT CASE" routine syntax for my MIDI scripts?
I'm building a stuff that can remap 16 midi notes (maybe more, it's just a question of script lines!) just the way I want.
That would be great.
If I can do it, I send it to you.

Thanks.

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

Unread post by bsork » 12 Feb 2007, 08:51

Here's a bit of code I found here at my work computer. It's from something that Olivier helped me with, and I can't really tell whether this version is his or mine, but the CASE bit should work:

Code: Select all

// parameters
VAR d1 : Tparameter;
VAR d2 : Tparameter;
VAR d3 : Tparameter;
VAR d4 : Tparameter;
VAR d5 : Tparameter;
VAR d6 : Tparameter;
VAR d7 : Tparameter;
VAR d8 : Tparameter;

VAR i1 : Tparameter;
VAR i2 : Tparameter;
VAR i3 : Tparameter;
VAR i4 : Tparameter;
VAR i5 : Tparameter;
VAR i6 : Tparameter;
VAR i7 : Tparameter;
VAR i8 : Tparameter;

VAR o1 : Tparameter;
VAR o2 : Tparameter;
VAR o3 : Tparameter;
VAR o4 : Tparameter;
VAR o5 : Tparameter;
VAR o6 : Tparameter;
VAR o7 : Tparameter;
VAR o8 : Tparameter;

var src1 : integer;
var src2 : integer;
var src3 : integer;
var src4 : integer;
var src5 : integer;
var src6 : integer;
var src7 : integer;
var src8 : integer;

CONST MAX_INPUTS = 8;

// initialisation
PROCEDURE init;
BEGIN  
   d1 := CreateParam('src1', ptDataField); 
   SetIsOutput(d1, FALSE); SetMin(d1, 0); SetMax(d1, MAX_INPUTS); SetFormat(d1,'%.0f'); SetSymbol(d1, '');
   d2 := CreateParam('src2', ptDataField); 
   SetIsOutput(d2, FALSE); SetMin(d2, 0); SetMax(d2, MAX_INPUTS); SetFormat(d2,'%.0f'); SetSymbol(d2, '');
   d3 := CreateParam('src3', ptDataField); 
   SetIsOutput(d3, FALSE); SetMin(d3, 0); SetMax(d3, MAX_INPUTS); SetFormat(d3,'%.0f'); SetSymbol(d3, '');
   d4 := CreateParam('src4', ptDataField); 
   SetIsOutput(d4, FALSE); SetMin(d4, 0); SetMax(d4, MAX_INPUTS); SetFormat(d4,'%.0f'); SetSymbol(d4, '');
   d5 := CreateParam('src5', ptDataField); 
   SetIsOutput(d5, FALSE); SetMin(d5, 0); SetMax(d5, MAX_INPUTS); SetFormat(d5,'%.0f'); SetSymbol(d5, '');
   d6 := CreateParam('src6', ptDataField); 
   SetIsOutput(d6, FALSE); SetMin(d6, 0); SetMax(d6, MAX_INPUTS); SetFormat(d6,'%.0f'); SetSymbol(d6, '');
   d7 := CreateParam('src7', ptDataField); 
   SetIsOutput(d7, FALSE); SetMin(d7, 0); SetMax(d7, MAX_INPUTS); SetFormat(d7,'%.0f'); SetSymbol(d7, '');
   d8 := CreateParam('src8', ptDataField); 
   SetIsOutput(d8, FALSE); SetMin(d8, 0); SetMax(d8, MAX_INPUTS); SetFormat(d8,'%.0f'); SetSymbol(d8, '');

   i1 := CreateParam('in1', ptDataField); SetIsOutput(i1, FALSE);
   i2 := CreateParam('in2', ptDataField); SetIsOutput(i2, FALSE);
   i3 := CreateParam('in3', ptDataField); SetIsOutput(i3, FALSE);
   i4 := CreateParam('in4', ptDataField); SetIsOutput(i4, FALSE);
   i5 := CreateParam('in5', ptDataField); SetIsOutput(i5, FALSE);
   i6 := CreateParam('in6', ptDataField); SetIsOutput(i6, FALSE);
   i7 := CreateParam('in7', ptDataField); SetIsOutput(i7, FALSE);
   i8 := CreateParam('in8', ptDataField); SetIsOutput(i8, FALSE);

   o1 := CreateParam('out1', ptDataField); SetIsInput(o1, FALSE);
   o2 := CreateParam('out2', ptDataField); SetIsInput(o2, FALSE);
   o3 := CreateParam('out3', ptDataField); SetIsInput(o3, FALSE);
   o4 := CreateParam('out4', ptDataField); SetIsInput(o4, FALSE);
   o5 := CreateParam('out5', ptDataField); SetIsInput(o5, FALSE);
   o6 := CreateParam('out6', ptDataField); SetIsInput(o6, FALSE);
   o7 := CreateParam('out7', ptDataField); SetIsInput(o7, FALSE);
   o8 := CreateParam('out8', ptDataField); SetIsInput(o8, FALSE);

END;

VAR i, j: Integer;

// Main
BEGIN
   i := i + 1;
   IF ((i mod (MAX_INPUTS)) = 0) THEN
   BEGIN
     j := j + 1;
     CASE (j mod MAX_INPUTS) OF
       0 : BEGIN j := 0; src1 := trunc(GetValue(d1)); IF (src1 > 0) THEN SetValue(o1, GetValue(src1+MAX_INPUTS-1)); EXIT; END
       1 : BEGIN src2 := trunc(GetValue(d2)); IF (src2 > 0) THEN SetValue(o2, GetValue(src2+MAX_INPUTS-1)); EXIT; END;
       2 : BEGIN src3 := trunc(GetValue(d3)); IF (src3 > 0) THEN SetValue(o3, GetValue(src3+MAX_INPUTS-1)); EXIT; END;
       3 : BEGIN src4 := trunc(GetValue(d4)); IF (src4 > 0) THEN SetValue(o4, GetValue(src4+MAX_INPUTS-1)); EXIT; END;
       4 : BEGIN src5 := trunc(GetValue(d5)); IF (src5 > 0) THEN SetValue(o5, GetValue(src5+MAX_INPUTS-1)); EXIT; END;
       5 : BEGIN src6 := trunc(GetValue(d6)); IF (src6 > 0) THEN SetValue(o6, GetValue(src6+MAX_INPUTS-1)); EXIT; END;
       6 : BEGIN src7 := trunc(GetValue(d7)); IF (src7 > 0) THEN SetValue(o7, GetValue(src7+MAX_INPUTS-1)); EXIT; END;
       7 : BEGIN src8 := trunc(GetValue(d8)); IF (src8 > 0) THEN SetValue(o8, GetValue(src8+MAX_INPUTS-1)); EXIT; END;
      END;
      i := 0;
   END;
END.
My Pascal is more than a bit rusty, but as far as I can remember you should use BREAK instead of EXIT if you want the program to continue after the CASE..END statement.
Bjørn S

Vincent

Unread post by Vincent » 12 Feb 2007, 23:54

Hi Bj?rn.

Thanks for your script.
By just looking at it, I don't really understand it, but I'll paste it in the right place... and see what's happening!
Is it a "select case" routine?

I was wondering, for that script re-mapping MIDI note, if it was possible to create a 16*2 array at the compilation (and each time any value of that array is changed) instead of rechecking all the mapping each time a new Midi Note happens. What do you think?
This mapping question is important for playing key-switches, they are very very useful with certain GIGA sampled instruments. It's also useful when I split my keyboard and want to make "outland incursions". it was very very easy in Reaktor, but here...

Thanks anyway.

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

Unread post by bsork » 13 Feb 2007, 09:01

This is the same as "select case" (what language was that again?) or "switch" in C, only that in in Pascal you write CASE x OF.

Creating two arrays (or a two-dimensional array) at compilation time is quite straight forward - check some of Olivier's scripts. You'll also find good examples of how to handle MIDI in and out in some of them.

You can hardcode the mapping or get the data at runtime, but I don't see how you could drop checking all the input values in one way or another before sending out the remapped values. You could however avoid a loop to find the right element of the array by for example using an array of 128 elements, and then use the note number (or whatever value you're checking) directly to get the right output value. The array doesn't have to be of length 128 if you instead apply some math and/or if/case statements to find the right element, but anyway it's possible that you could do what you want with only one array(?).
Bjørn S

Vincent

Unread post by Vincent » 15 Feb 2007, 00:02

Thanks Bj?rn,
It seems to me that you know what your talking about much more than I do...

Well, I'm working with small steps. I think I first have to well know how to manipulate arrays with that new language form me.
So, here are two script modules, I don't know how to write them and there is a bug (or more!) somewhere. They are not complete, but it's enough to see what it means.
Could anybody have a look at them:
1. "Ctrls To Array"

Code: Select all

// Ctrls To Array
// Vincent Michel
// 14-02-2007

//////////////////////////////////////////////////////
// Paramters declaration
//////////////////////////////////////////////////////
var in_1 : Tparameter;
var in_2 : Tparameter;
var in_3 : Tparameter;
var in_4 : Tparameter;
var in_5 : Tparameter;
var in_6 : Tparameter;
var in_7 : Tparameter;
var in_8 : Tparameter;

var ArrayOut    : Tparameter;

//////////////////////////////////////////////////////
// initialisation procedure
//////////////////////////////////////////////////////
procedure init;
begin  
 in_1 := CreateParam('MinPos',ptDatafader);
 in_2 := CreateParam('MaxPos',ptDatafader);
 in_3 := CreateParam('VSTi',ptDatafader);
 in_4 := CreateParam('Preset',ptDatafader);
 in_5 := CreateParam('Vol',ptDatafader);
 in_6 := CreateParam('Pan',ptDatafader);
 in_7 := CreateParam('Oct',ptDatafader);
 in_8 := CreateParam('Velo',ptDatafader);
 SetIsOutput(in_1,false); SetMin(in_1,0); SetMax(in_1,127); SetSymbol(in_1,''); SetDefaultValue(in_1,0);
 SetIsOutput(in_2,false); SetMin(in_2,0); SetMax(in_2,127); SetSymbol(in_2,''); SetDefaultValue(in_2,127);
 SetIsOutput(in_3,false); SetMin(in_3,0); SetMax(in_3,16); SetSymbol(in_3,''); SetDefaultValue(in_3,0);
 SetIsOutput(in_4,false); SetMin(in_4,0); SetMax(in_4,127); SetSymbol(in_4,''); SetDefaultValue(in_4,0);
 SetIsOutput(in_5,false); SetMin(in_5,0); SetMax(in_5,127); SetSymbol(in_5,''); SetDefaultValue(in_5,48);
 SetIsOutput(in_6,false); SetMin(in_6,-100); SetMax(in_6,100); SetSymbol(in_6,' %'); SetDefaultValue(in_6,0);
 SetIsOutput(in_7,false); SetMin(in_7,-4); SetMax(in_7,4); SetSymbol(in_7,''); SetDefaultValue(in_7,0);
 SetIsOutput(in_8,false); SetMin(in_8,0); SetMax(in_8,200); SetSymbol(in_8,'%'); SetDefaultValue(in_8,100);


 ArrayOut := CreateParam('Out',ptArray);
 SetIsInput(ArrayOut,false);

end;


//////////////////////////////////////////////////////
// Main proc
//////////////////////////////////////////////////////
begin
  SetLength(ArrayOut,8);
  SetDataArrayValue(ArrayOut,0,in_1);
  SetDataArrayValue(ArrayOut,1,in_2);
  SetDataArrayValue(ArrayOut,2,in_3);
  SetDataArrayValue(ArrayOut,3,in_4);
  SetDataArrayValue(ArrayOut,4,in_5);
  SetDataArrayValue(ArrayOut,5,in_6);
  SetDataArrayValue(ArrayOut,6,in_7);
  SetDataArrayValue(ArrayOut,7,in_8);
end.
2. "Array To Ctrls"

Code: Select all

// Array To Ctrls
// Vincent Michel
// 14-02-2007

//////////////////////////////////////////////////////
// Paramters declaration
//////////////////////////////////////////////////////
var ArrayIn    : Tparameter;

var out_1 : Tparameter;
var out_2 : Tparameter;
var out_3 : Tparameter;
var out_4 : Tparameter;
var out_5 : Tparameter;
var out_6 : Tparameter;
var out_7 : Tparameter;
var out_8 : Tparameter;

//////////////////////////////////////////////////////
// initialisation procedure
//////////////////////////////////////////////////////
procedure init;
begin  
 ArrayIn := CreateParam('In',ptArray);
 SetIsOutput(ArrayIn,false);

 out_1 := CreateParam('MinPos',ptDatafader);
 out_2 := CreateParam('MaxPos',ptDatafader);
 out_3 := CreateParam('VSTi',ptDatafader);
 out_4 := CreateParam('Preset',ptDatafader);
 out_5 := CreateParam('Vol',ptDatafader);
 out_6 := CreateParam('Pan',ptDatafader);
 out_7 := CreateParam('Oct',ptDatafader);
 out_8 := CreateParam('Velo',ptDatafader);
 SetIsInput(out_1,false); SetMin(out_1,0); SetMax(out_1,127); SetSymbol(out_1,''); SetDefaultValue(out_1,0);
 SetIsInput(out_2,false); SetMin(out_2,0); SetMax(out_2,127); SetSymbol(out_2,''); SetDefaultValue(out_2,127);
 SetIsInput(out_3,false); SetMin(out_3,0); SetMax(out_3,16); SetSymbol(out_3,''); SetDefaultValue(out_3,0);
 SetIsInput(out_4,false); SetMin(out_4,0); SetMax(out_4,127); SetSymbol(out_4,''); SetDefaultValue(out_4,0);
 SetIsInput(out_5,false); SetMin(out_5,0); SetMax(out_5,127); SetSymbol(out_5,''); SetDefaultValue(out_5,48);
 SetIsInput(out_6,false); SetMin(out_6,-100); SetMax(out_6,100); SetSymbol(out_6,' %'); SetDefaultValue(out_6,0);
 SetIsInput(out_7,false); SetMin(out_7,-4); SetMax(out_7,4); SetSymbol(out_7,''); SetDefaultValue(out_7,0);
 SetIsInput(out_8,false); SetMin(out_8,0); SetMax(out_8,200); SetSymbol(out_8,'%'); SetDefaultValue(out_8,100);
end;


//////////////////////////////////////////////////////
// Main proc
//////////////////////////////////////////////////////
begin
  SetValue(out_1, GetDataArrayValue(ArrayIn,0));
  SetValue(out_2, GetDataArrayValue(ArrayIn,1));
  SetValue(out_3, GetDataArrayValue(ArrayIn,2));
  SetValue(out_4, GetDataArrayValue(ArrayIn,3));
  SetValue(out_5, GetDataArrayValue(ArrayIn,4));
  SetValue(out_6, GetDataArrayValue(ArrayIn,5));
  SetValue(out_7, GetDataArrayValue(ArrayIn,6));
  SetValue(out_8, GetDataArrayValue(ArrayIn,7));
end.
Purpose:
On one side, I have 3 keyboard splits (or 2 or only one!).
On the other side, I have 8 instruments ( "" "" "" ).

From each split start values, including Midi data (min and max split range, Instrument Destination, # preset or PC, Lvl, Pan, velocity, and so on).
To each instrument (or non-plugin instruments) arrive many values, including of course MIDI data!
Can you imagine the way it looks? I'd bet that a spider lost itself.

So my idea was to "join" in an array whole groups of data, one array per keyboard split, then a central module-submodule-subsubmodule splits arrays, dispatch and then re-join arrays, this time one per instrument.
Well, just an idea. 'cause I can't do it!

Thanks to the doctor that tells me what's wrong in my code.

BTW:
bsork wrote:There are a couple of pitfalls in Usine that are easy to fall into... Many times I've wondered why more or less nothing happens when I edit some values in a patch. And of course; either the track or the the whole audio engine is off...
Oh yes... do we have sometimes the same bug?
bsork wrote:I've noticed however, that sometimes when I'm programming a patch I have to exit the edit mode, maybe choose another patch, and then go back into edit mode again, in order for the interface elements to be updated.
I've noticed those things... Many very small things that confuse the beginner I am!
Synchronize works OK for my quantized delay, as a matter of fact.

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

Unread post by bsork » 15 Feb 2007, 09:07

Well Vincent, I've made a copy of your scripts and see if I can take a look at them tonight. Right now I'm at work, and it seems my brain ain't workin' properly, so I have a hard time understanding what you mean in your description - feel free to rephrase...
Bjørn S

Vincent

Unread post by Vincent » 15 Feb 2007, 16:00

Well, sorry, Bj?rn!

I just meant: too many wires crossing my patches.
The idea was to regroup the data going by those wires in ONE array using ONE wire.
I think you'll understand as soon as you see my script patches in your Usine.
Thank you!

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

Unread post by bsork » 15 Feb 2007, 21:57

Nothing to be sorry about, Vincent!

I've been looking at your scripts a little while now and there are a couple of things to be fixed:

Move the SetLength in script 1 from the main part to init, you don't need that statement to executed more than once. Also you should set the length of the input array to 8 in script 2, but I'm not sure whether you'll notice any difference. It's good programming practice though.

The other thing is that you've forgotten to get the data from the inputs. You'll have to write something like SetDataArrayValue(ArrayOut, GetValue(in_1));

You don't have to use the script module to achieve these things, though. Try doing the same thing with the data/steps module. It can output an array (it's at the bottom of the module - you'll have scroll with the down arrow), and the first 16 values have separate inputs. The only "drawback" is that the you'll have to set mutual min/max values for all the inputs in steps, and edit the real min/max values and precision for each fader.

I must admit I'm curious of how these patches will work. Do you mind giving a short explanation - maybe with a little example - of how you're planning this to behave?

Good Luck!
Bjørn S

Vincent

Unread post by Vincent » 16 Feb 2007, 23:42

Hi Bj?rn,
bsork wrote:I must admit I'm curious of how these patches will work. Do you mind giving a short explanation - maybe with a little example - of how you're planning this to behave?
I'm curious too...

I'm not sure I understood clearly the concept of Usine.
"Tracks of Patches", easy to say when you have build it yourself!
For me, "tracks of patches" means generally light patches that serve only once or twice. Exactly the opposite of what I'm doing.
OK, I'll try a short explanation:
At one of the beginnings is my midi keyboard (other inputs concern vocals and electric bass). And, as I'm the keyboardist and the bassist (and the guy who works on vocals effects), I do almost everything.
So that midi keyboard can be splitted; each split can play a different VSTi: Arturia Moog, NI-Absynth, NI-FM8, NI-Reaktor with two synth in it, I hope Reason, my very favorite: GigaStudio 3 and, finally, one or two Usine's excellent sample-players with strange stuffs of mine (percs and/or sophisticated samples), plus some small tracks (grooves, 2nd, third voices...) that may be samples again in fact, as Usine's sampler can read directly from the hard drive.
There you are!
As you can see, it's very heavy.

My first idea is to make a patch that can do all this (plus vocs and bass FX) by just choosing between different combinations with the conductor, my computer keyboard or the midi controllers of my midi kb (and not overloading the CPU...)
So, those array patches serve to group wires: all the controls coming from the first split, all the controls coming from the second... route them to the central dispatch patch... And then all the controls going to the first VSTi, all the controls going to the second, and so on.
You see?
I'm not sure I can do that with Usine (or with my computer...)

In the other hand, I'll have to think about tracking patches...
That would mean that the workspace will be made specially for a given live program, but could not be used for compositional works neither for jams... Example, if Moog and GigaStudio are in the same patch, I cannot play the Moog (on left hand) with FM8 (on right hand). If I understand correctly, that I'm not sure!

Or something else: put each VSTi in separate tracks? But how to handle from one track to another all my arrays coming from the keyboard splits?

Well, I have to experiment, I don't know Usine enough to see now exactly what I have to do.

And I hope my English is not very too much bad! Sorry for that!
When I'll be good in Usine, I'll do a francophone Usiners forum.
It looks here just like at Quebec: everybody speaks French, but to be kind, everybody talks in English!
Well let us be European. I like that.

Thanks for your advices concerning my scripts, I'll rewrite that immediately... and see if I can use Usine's patches instead.

bmoussay
Member
Posts: 130
Contact:

Unread post by bmoussay » 17 Feb 2007, 12:57

Hi Vincent,

Just my 2 cents:

I have two midi keyboards, each of them sending to one patch.
Each of these patches contains several VSti with a simple routing circuit allowing to bybass, send program changes, send keyboard datas to a particular VSTi or not (allowing to play a single VSTi, layer a few of them, or play one, latch, deactivate keyboard, and play another one with the same kb).
Of course, I can store and recall presets, either wih the conductor, or with the preset module.
I havent't tried to deal with keyboard splits, but I imagine you could build a simple circuit with midiin -> midi filter (notes, PB) -> and some conditions about the note number range to pass or not the midi data. Then your "one keyboard" becomes "two or more keyboards", depending on the split ranges you've chosen, and then send this data to any destination.
You could have such a circuit either in the same patch as the VSTis or in a patch of it's own sending to midi busses (these really allow powerful routing).
Well, hope this can help.
Rgds,

B.

Vincent

Unread post by Vincent » 17 Feb 2007, 20:54

I Benjamin!
bmoussay wrote:Just my 2 cents
But cents of ?.
bmoussay wrote:I imagine you could build a simple circuit with midiin -> midi filter (notes, PB) -> and some conditions about the note number range to pass or not the midi data. Then your "one keyboard" becomes "two or more keyboards", depending on the split ranges you've chosen, and then send this data to any destination.
This is exactly how I did.
But a little bit more complicated... A keyboard split is not only notes but also Vol, Pan, progCh, % of velocity... For one keyboard, it's simple wiring. For three, it's three times the simple wiring, but not three times simpler!
bmoussay wrote:You could have such a circuit either in the same patch as the VSTis or in a patch of it's own sending to midi busses.
Yes! Great!
What is a midi bus, not the same as midnight bass, right?
I feel you gave me the solution there: midi busses. I have to find that.

You helped me, sure.
Thanks. You all are genius!

Vincent

Unread post by Vincent » 18 Feb 2007, 02:57

Hi Usiners.

I did an "up to 16 note mapper". It's a crazy wiring machine.
I've found on Internet many interesting MIDI VST plug-ins (MFX), but not this one.
Useful if you play VSTis with keyswitches or if you want any key not in the scale to do something else than playing a note you don't need.

It's there for 7 days, if anyone wants to have a look or use it, or improve it...
It seems that in "virtuoso movements", there can happen some strange behavior. That cannot happen to me!

Just a small explanation how to use it:
- type a note # in one of the 1 inputs
- type another note # in the 2 input just below
- you can do that for the 16 1 inputs
- if you enter twice the same 1 value, only the first one (on top) will be computed!
---------------------------------
...well. Sorry, my friends. I've been testing that marvelous patch.
It's made with 16 sub-patches and each of them eats 2.15% CPU mini...
I don't understand, they are so small!
Don't try it, guys, or don't forget to save your project before!

User avatar
senso
Site Admin
Posts: 4424
Location: France
Contact:

Unread post by senso » 18 Feb 2007, 11:52

you are crazy men!
works fine.
Maybe, just add few comments on the patch?

Vincent

Unread post by Vincent » 18 Feb 2007, 12:40

Crazy crazy, well forget it.
OK, I'll add some comments and post a new version.
I use it a lot, even for unplayable patterns, do you think it's a useful stuff ?
Last version there.

Vincent

Unread post by Vincent » 18 Feb 2007, 23:55

Hi.
Senso wrote:works fine.
Of course it can, with 32% CPU (top left corner of the patch)!!!!!!
How can it be possible?
And, BTW, I need three of them...
Can anybody tell me, will it be better (much, much better, I mean) if I try to write a script (and first learn how to do)?

Thanks!

Post Reply

Who is online

Users browsing this forum: No registered users and 24 guests