Welcome to %s forums

BrainModular Users Forum

Login Register

Some scripting probs...

I need help on a Patch
Post Reply
Vincent

Unread post by Vincent » 27 Feb 2007, 03:54

Hello.

I don't know if I'm supposed to post a scripting topic here or in "Patch development".

You know, my mapping obsession?
Well. My script is successfully compiled but as soon as I send a midi note, the tracer says: "[Script Error] : Type Mismatch in 0"
Here is the code:

Code: Select all

/////////////////////////////
// NoteMGR
/////////////////////////////

// This script remaps notes XOR transposes them and/or applies a ratio
//   to their velocity
// It needs a 128 (0 to 127) array where each entry is the incoming note#
//   and each value is the mapped note#
// Plug an Array Editor Module on the 'Map' input to edit mapped notes. 
// By default, the values of
// - entry 0 should be 0
// - entry 1 should be 1
// - entry 2 should be 2
// - [...]
// - entry 127 should be 127
// That must be done or the script won't work.

// If you want note 60 to play one octave below when the whole range is
//   transposed one octave up, try this:
//   LeftLimt = lower note of your keyboard or you want to hear
//   RightLimt = upper note "   "     "     "   "    "   "   "
//   Transpo = 0 (half steps)
//   Octave = 1  (actual octave plus one)
//   Velo = 100% (of your playing velocity)
//          Velocity ratio will NOT be applied to the remapped note (just a
//            choice that can change)
//          Note that on some VSTis, a velocity greater than 127 will be
//            set to 0 or 1!
//   go to the entry#60 of yout Array Editor and change it's value to 48 (60-12)
// ...and play unplayable patterns!

// or, for stochastic purposes...

// don't plug an Array Editor Module on the 'Map' input but an Array (Display or Set)
//   with 'num' set to 128 and try 'Randomize'.
// Remember your global remote for 'Panic'?

/////////////////////////////
// parameters declaration
var Input  : Tparameter;
var nMap   : Tparameter;
var LL     : TParameter;
var RL     : TParameter;
var Oct    : TParameter;
var Trans  : TParameter;
var Vel    : TParameter;
var Output : Tparameter;

// initialisation : create parameters
procedure init;
begin  
 Input  := CreateParam('MidiIn',ptMidi);
 nMap   := CreateParam('Map',ptArray);
 LL     := CreateParam('LeftLimit',ptDataFader);
 RL     := CreateParam('RightLimit',ptDataFader);
 Trans  := CreateParam('Transpo',ptDataFader);
 Oct    := CreateParam('Octave',ptDataFader);
 Vel    := CreateParam('Velo',ptDataFader);
 Output := CreateParam('MidiOut',ptMidi);
 
 SetIsOutPut(Input,false);
 SetIsOutPut(nMap,false); SetMin(nMap,0); SetMax(nMap,127)
 SetIsOutPut(LL,false); SetFormat(LL,'%.0f'); SetMin(LL,0); SetMax(LL,127); SetDefaultValue(LL,36);
 SetIsOutPut(RL,false); SetFormat(RL,'%.0f'); SetMin(RL,0); SetMax(RL,127); SetDefaultValue(RL,72);
 SetIsOutPut(Oct,false); SetFormat(Oct,'%.0f'); SetMin(Oct,-4); SetMax(Oct,4); SetDefaultValue(Oct,0);
 SetIsOutPut(Trans,false); SetFormat(Trans,'%.0f'); SetMin(Trans,-11); SetMax(Trans,11); SetDefaultValue(Trans,0);
 SetIsOutPut(Vel,false); SetFormat(Vel,'%.0f'); SetSymbol(Vel,'%'); SetMin(Vel,0); SetMax(Vel,400); SetDefaultValue(Vel,100);
 
 SetIsInput(Output,false);
end;

// Global variables
var i            : integer;
var nbMidiIn     : integer;
var nbMidiOut    : integer;
var ActualNote   : integer;
var MappedNote   : integer;
var ReceivedMidi : TMidi;
var TranspoVal   : single;
var VeloVal      : double;

// main proc
begin
 nbMidiIn := GetLength(input);  	// get the number of incoming midi codes  
 if nbMidiIn > 0 			// if notes are recieved
 then begin
   TranspoVal := trunc(getValue(Trans)+(getValue(Oct) * 12)); // calculates the total tranpo value
   VeloVal := getValue(Vel) / 100;			// calculates the velocity ratio
   for i := 0 to nbMidiIn-1                         	// loops each note of polyphonic data
   do begin
     GetMidiArrayValue(Input,i,ReceivedMidi);			// get individual midi data
     ActualNote := ReceivedMidi.data1;				// get individual note #
     if &#40;ActualNote >= getValue&#40;LL&#41;&#41; and &#40;ActualNote < getValue&#40;RL&#41;&#41;	// if the individual note is in the range
     then begin
       SetLength&#40;outPut,nbMidiOut&#41;;						// set the new number of output codes
       MappedNote &#58;= trunc&#40;GetDataArrayValue&#40;nMap,ReceivedMidi.data1&#41;&#41;;		// get mapped note #
       if ActualNote = MappedNote						// if the note is NOT mapped
       then
         if &#40;TranspoVal - VeloVal&#41; <> -1 						// if transpo or velo are changed
         then begin
           ReceivedMidi.data1 &#58;= ActualNote + TranspoVal;					// changes transpo
           ReceivedMidi.data2 &#58;= trunc&#40;ReceivedMidi.data2 * VeloVal&#41;;				// changes velocity
         end
       else ReceivedMidi.data1 &#58;= MappedNote;					// else only remap the note
       SetMidiArrayValue&#40;Output,NbMidiOut,ReceivedMidi&#41;; 			// sets output value     
       NbMidiOut &#58;= NbMidiOut + 1;						// reset next number of outgoing midi codes
     end
   end; 
  end 
 else SetLength&#40;outPut,0&#41;; 		// nothing received, nothing sent

end.


/////////////////////////////
// 27-02-2007
// Vincent MICHEL
/////////////////////////////
I hope that my comments are clear and helpful.
My favotite line is this one:

Code: Select all

// That must be done or the script won't work.
Huh-huh... It never works!

There are 3 points where I'm not sure of what I'm doing (3, well...):
1. when I get the note value in the array

Code: Select all

MappedNote &#58;= trunc&#40;GetDataArrayValue&#40;nMap,ReceivedMidi.data1&#41;&#41;;
2. when I check if the note# is in the range

Code: Select all

if &#40;ActualNote >= getValue&#40;LL&#41;&#41; and &#40;ActualNote < getValue&#40;RL&#41;&#41;
then begin
3. Changing in the loop the length of the Midi Data array, does it delete all the data? But this must be a dynamic array, no?

Code: Select all

SetLength&#40;outPut,nbMidiOut&#41;;
But maybe it's elsewhere. It's not easy to debug in the script editor when you're not a master, right?

Anyway, this proc is some kind of test. It's easier to write (and lighter to run) if I just never check if the note# is remapped and always use the array values. Too many imbrications of "If ... then ... else ..."

Well, Bj?rn, I think it's for you...
Sorry!
But I hope you'll use it! It's very useful! I like it! Play huge grooves all across the keyboard with just a few finger impulse!

Vincent

Unread post by Vincent » 27 Feb 2007, 05:10

Hello.

There it is, with less than 1%CPU.
Usine is the best!!!

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

Unread post by bsork » 27 Feb 2007, 08:40

From your second post, I reckon you've finally made it, Vincent. Congrats!
Bjørn S

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

Unread post by senso » 27 Feb 2007, 09:23

Great!
You did a perfect mix beetween modules and scripts.

Just a (stupid) question.
Generally (??), the midi mapping is identical on each octave.

Can't you use a 0..11 (octave) mapper and transpose it, insteed of the 0..127 mapper?

Vincent

Unread post by Vincent » 27 Feb 2007, 15:57

Hello Olivier.
senso wrote:Generally (??), the midi mapping is identical on each octave
You mean, like on the harps? C pedal changing alteration (transposing half steps) of the C on each octave?
Yes, that's true. But the macanism used to buzz!
Well, seriously.
For this feature, you did a module (forgot the name, Transformer, right?) that works without buzzes. And I found some clever MFX on the Web.

I really wanted to act on individual notes. Let me explain why:
In many Giga programs, you have what they call key switches, notes (far) out of the sampled range that change the articulation. Example: on Larry Sayers Upright Bass, you have lots of key switches to change normal layered note in a slap, or an Xnote, or a slide, or a buzz, or an harmonic, and so on. Those key switches can sometimes be assigned to MW, but I have no MW and, if I had one, I would use it for expressive vibrato (real MW).
Another example: I want to add gongs in my synth pad. I put a 32" Chinese gong in GigaStudio but this program has 40 different hits of the same gong all along the keyboard. As I just need a selection of them, I can remap half an octave on my keyboard to have the needed sounds close on my fingers. So the split I use for the gong is very short and leaves room enough for the synth pad. It's simpler than to make a new program with only the needed notes and, if I want to change them, it's very easy.
Well, a last one example, as you'll see, a weird but interesting concept - the pseudo sequencer (or the pseudo groove-box): I want to play on my left hand a "sequencer-type pattern" that runs thru 3 or 4 octaves in very quick jumps while my right hand plays an expressive theme on an other instrument (with key switches!). I remap the notes of the sequence in a practical configuration of keys that gives groove on LH and remap key switches of RH on keys close from the theme but outside the harmonic scale.
Understand?
In these cases, you can imagine that parallel mapping on octaves is not effective.
Since I made a comparison with harp, I'll make another one with some old harpsichords: on Italian or Flemish short keyboards, lower chromatic G, G# ... to B-natural covers a full diatonic octave to go lower in the register.

Changing note mapping is not very easy I recognize. You have to go in the patch and edit a big array. But you can have up to 8 different edits of this array and saved in the Presets, it works fine.
Also, something can be add to reinit the array (0=0, 1=1, 2=2, ..., 127=127).

I hope that my "note mapping" will open new possibilities for you all!

To Bj?rn:
Thanks!
As I think to it today, I see it was really very easy. I am a stupid script writer.
Now, guys, you have to use it for new things in your music!

Thanks for your help, it could not exist without it!
(? suivre...)

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

Unread post by senso » 27 Feb 2007, 16:37

ok,
Thanks for the response
I understand now (some time I'm slow...)

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

Unread post by bsork » 27 Feb 2007, 16:44

Just glad to be of help, Vincent, and I really think you're far from being a "stupid script writer".

You should've known how many mistakes I've been through when writing my scripts. Some of them just plain silly - often because I tend to write PL/SQL commands instead of Pascal. PL/SQL is the language I'm using the most at work, and it's very much alike Pascal. It's often easier to switch between languages that look different; for instance between C and Pascal. IMO, of course...

Thanks for describing how you use that remapping, I must admit I wondered why on earth you'd want to remap the whole keyboard, but now it makes sense. Guess that being a lousy keyboard player like myself, advanced ways of using the black-and-whites aren't what comes to mind first.
Bjørn S

Vincent

Unread post by Vincent » 27 Feb 2007, 17:02

... also useful for short midi keyboard-controllers.
... and why not remap keys for Usine's global or patches remote?
What do you think?
Vast is the number of new possibilities!
Just imagine and just do!

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

Unread post by senso » 27 Feb 2007, 19:36

... and why not remap keys for Usine's global or patches remote?"
What do you mean?

You're going to be a master.
Hope I will follow...

Vincent

Unread post by Vincent » 28 Feb 2007, 05:01

I mean...
OK, this is only theory, 'cause I don't really know where is catch your midi remote. If it's at the very beginning of the chain of events (eg. before midi data can be processed by patches), that cannot work!
I'll try it and tell you, but you already know, joker.
Stupid non-working example: remap some notes to #1, #2 and #3 midi notes (not very used, right?) then assign these notes to activate/deactivate track 1, 2 and 3 (but not the one where is your patch), mode set to "toggle". As you can save array maps in presets, you can activate tracks 1 to 3 with eight different set of notes.

Give me time and there will not be anything (specially stupid-looking things like my Midi Note Mapper) that I had not try.
You won't follow and that's better. As you know, my organic CPU is a little overclocked, even burnt. But here, in the mountains, ventilation is excellent! Just like in Sweden, I think, hey Bj?rn? (needs Alt+0248 on our keyboards)
I've been many times in Stockholm for my ex-job. Do you know, Olivier, that in this very beautiful country ladies open the doors and men only have to smile and pull the baby-carriage? Can you imagine, they think we are THINGS!
That was some kind of "patching" question, indeed, but not for Usine. Sorry.
Bsork wrote:It's often easier to switch between languages that look different; for instance between C and Pascal
Just the same with girls. I mean with musical instruments.
Bj?rn, do you develop patches? In C++ or Delphi? Which editor do you use? Are there free one? I wanna learn this. Usine deserves it (in fact, my music does too).

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

Unread post by bsork » 28 Feb 2007, 09:21

Well Vincent, I could have been offended now. A lot of Norwegians dislike being mistaken for Swedes (or Danes) - a bit of a national inferiority complex based on our mutual Scandinavian history, I guess. Something like Canadians being taken as Americans... But I don't mind.

FYI, the letter ? (o-slash) is used in Norway and Denmark only (well maybe on Iceland and the Faroe Islands as well, I don't know), while ? is used in Swedish, German and some other languages. I'm afraid I don't have any internationally known "real" namesakes, but the two Swedes Bj?rn Borg (former tennis ace) and Bj?rn Ulveus of ABBA springs to mind.

An anecdote about my name - totally unrelated (like most of this post) to Usine or music: I once made a hotel reservation in the UK with a handwritten fax, and had written my name in capital letters. I, like a lot of other "continental" Europeans, write the letter J and the number 7 with a line across, but the British don't. The hotel interpreted the J as a Z and the ? as I, which gave me the new and I think fairly "exotic" name Bzirn. The had gotten my last name right, though - that doesn't always happen in Norway.

Back to topic: I develop patches, but just Usine stuff. (I suppose you're not thinking about "patches" as in a synth patch/program/preset.) I earn my living as a developer working with database (Oracle) stuff, and use different editors, but my favorite text editor is called Lemmy. Whether it's named after the Mot?rhead front person I don't know, but it's a Windows version of the Unix "vi" editor. Unless you're already familiar with vi and like it, it is of no use I think. The learning curve of the old-fashioned vi is quite steep: I remember swearing a lot and yelling things like "HOW CAN A PROGRAM BE SO USER UNFRIENDLY!!! GRRRR!!!" when I had to start using it.

When editing Usine scripts, I mostly use the built-in editor since the programs are fairly small anyway, and just copy the whole thing over to Lemmy when it's practical with some more functionality. Free text editors are a dime a dozen on the net, AFAIK.
Bjørn S

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

Unread post by senso » 28 Feb 2007, 09:37

I'm not sure it's easy to use an external script editor in Usine.
Looking for a solution.

Sens?

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

Unread post by bsork » 28 Feb 2007, 12:05

I don't think you should put too much effort into that, ?livier. The scripts in Usine aren't normally that big, and anyway using Copy/Paste or opening the text files in some other text editor when needed isn't that much of a hassle.

However - Find/Replace or just Find would be nice...
Bjørn S

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

Unread post by senso » 28 Feb 2007, 13:31

i'm llooking on find/replace

Vincent

Unread post by Vincent » 28 Feb 2007, 17:06

Hi Olivier,

Yes, Find/Replace, great!
Generally Ctrl-F, or Ctrl-H, or Ctrl-F3, with F3 for next occurrence, but you know that.
You see why I hesitate to suggest improvements: You're already working to them with your own ideas.
I was thinking about external editors for waves, midi tracks and scripts... Make Usine light and quick. I was also thinking about a "live mode" where the whole editing engine is unloaded (except Presets, arrays, things like that). But well, it's your Usine and I'm glad we can share it!

Hi Bzirn!
Sorry! I re-read my post and well, I don't know why I mixed up, because I knew you were from Asker, Norway. Sorry. Never been in Norway.
I was thinking of Usine patches, not patches for synths. I'm too bad for sound-design.

Let's come back to my Midi Note Mapper. There's a bug.
If you downloaded it, you saw that it was built with two parts: a. filters the keyboard split with modules (or plugin), then b. remaps or transpose notes with script.
Part a does not work properly with polyphony: Notes supposed to be stopped sometimes are not - and the related NoteOFF message does not follow. That makes stucked notes that you cannot stop unless you press 'Panic'.
So, I'll have to change things again.
I have to implement the range filter in the script, in the loop (my first idea)
My question:
In the loop, I check if note # is in the range limits, if it is I add (and eventually process) it to the outgoing data array.
But I cannot manage to resize properly that array. Why?
It seems that data already in the array is destroyed each time a new line is added?
I'm used to Visual Basic where there is an explicit difference between Redim and Redim Preserve (reset length of an array without destroying data already in it). If SetLength is equiv to Redim, what id the equiv for Redim Preserve?
Well, I'm not sure I'm clear??

Arghhhh. I'll have no sleep until it works, I swear.

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

Unread post by bsork » 01 Mar 2007, 09:48

Without really testing the script, there's only one thing that I've found that may cause problems, and that is that you're not checking whether the message received really is a Note On or Note Off and not a Pitch Bend. That - and the possible problems with using modules to limit the range. Remember that Note Offs come in two flavours: a Note On (msg = 144) with velocity = 0, or the "proper" Note Off (msg = 128).

As long as you're limiting the range outside of the script, you should just set the length of the output to the same as the input length since no messages are added or subtracted, just altered. If however you're limiting the outputted range, you will of course need to add a counter to keep track of how many messages that are really sent.

I don't know anything about VB or how the SetLength really behaves, but as I've mentioned elsewhere, I've found it useful to start by zeroing the output midi array length before adding the data and set the proper length at the end.

...and here's another person that is not up to program DSP...
Bjørn S

Vincent

Unread post by Vincent » 01 Mar 2007, 17:34

Hi Bj?rn,

Thanks for your comments.
Yes, I should check that about the Pitch Bend. I had noticed that two different flavor of Note Of (with Reaktor), but mine, in Usine, is the proper one (I even thought to use the other one, not to change the array length).

As you'll notice if you play some impros with the patch, range limiting outside the script does not work properly, even with the midi plugin. So, I'll have to do it in the loop (and I think it's better this way).
Anyway, if I knew that language, I would say it's so simple! But I just learn.
I'll try what you suggest: 1. zeroing the output midi array; 2. add data; 3. set the proper length. But in the things I already did, it seemed to me that setting the length at the end was destroying the data. I certainly was wrong somewhere... I'll ask that more directly to Olivier.
bsork wrote:...and here's another person that is not up to program DSP...
...sorry, I'm afraid I don't understand! My very splitted english!

Thanks for your answers, Bj?rn, I would be stopped without them.

Vincent

Unread post by Vincent » 02 Mar 2007, 03:13

Well, ?livier, how are you today?
(Things become weirder and weirder... makes me think to that huge dog who became Id?fix great friend, but from Denmark this one...)

And, second very short question, could you indicate me a script where data are added in an array by an incremental loop (or gimme an example)?
Important: the array length cannot be fixed before the loop because that loop is to check if the elements will be added or not. It must be dynamic.

Th?nks Olivier!

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

Unread post by senso » 02 Mar 2007, 09:33

It's not advised to modify the length of an array in the main loop procedure: it cost a lot of CPU.

so I recommand some thing like

Code: Select all

var A &#58; array of single; // the array
var NElements &#58; integer; // number of elements in the array
CONST MAX_SIZE = 1000; // max size of the array

initialization
setArraylength&#40;A,MAX_SIZE&#41;;
NElements &#58;= 0;
...
mainloop&#58;

// add a new value
if &#40;NElements<MAX_SIZE&#41;
then begin
  A&#91;NElements&#93; &#58;= ...
  NElements &#58;= NElements+1;
end;

Vincent

Unread post by Vincent » 02 Mar 2007, 23:38

Well, that must be a secret. I'll never know...
Recapitulation: set a big array, fill it with data. And then? Reset it to the right length?
What will think my Midi output with three notes ON and three notes OFF in a 127-array?
I'll try. Right now. Go.
Thanks, Olivier!
I tell you I'll do it.

BTW, I'm happy to use-Usine.
That will be great for sure.

Post Reply

Who is online

Users browsing this forum: No registered users and 299 guests