Welcome to %s forums

BrainModular Users Forum

Login Register

2 more scripts: transpose+multiply

Discussions about add-ons, announcements
Post Reply
amiga909
Member
Posts: 324
Contact:

Unread post by amiga909 » 26 Oct 2008, 21:22

based on bSorks code
- midi note transpose with wrap around option
- midi note multiply with wrap around option

tkx for the note closer script in the addon section, btw :)

Code: Select all

//////////////////////////////////////////////////////
// transpose midi note
// 2008-10-24: @bSork, first version 
// 2008-10-26: @amiga909, 'wrap around' added 
//////////////////////////////////////////////////////

VAR pIn, pOut, pTransp, pWrapAround : tParameter;

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

VAR tmp : tMidi;
VAR len, transpose, i, tempTransp : integer;

PROCEDURE Init;
BEGIN

   pIn := CreateParam('midi in', ptMidi); SetIsOutput(pIn, FALSE);
   pOut := CreateParam('midi out', ptMidi); SetIsInput(pOut, FALSE);

   pTransp := CreateParam('transpose', ptDataFader); SetIsOutput(pTransp, FALSE);
   SetFormat(pTransp, '%.0f'); SetMin(pTransp, -127); SetMax(pTransp, 127);

   pWrapAround := CreateParam('wrap around', ptSwitch); SetIsOutput(pWrapAround, FALSE);

   SetArrayLength(transp, 16);
   FOR i := 0 TO 15 DO // A two-dimensional array; [16 channels][128 transpose values]
      SetArrayLength(transp[i], 128);
END; 

// expects a noteOn msg with velocity > 0; outputs the transposed note value [0-127]
FUNCTION calcTranspose (t: integer; wrap: single): integer;
BEGIN
 IF wrap > 0 THEN BEGIN // 
    IF t > 127 THEN 
        result := t - 128
    ELSE IF t < 0 THEN 
        result &#58;= t + 128;  
 END
 ELSE BEGIN
    IF t > 127 THEN 
        result&#58;= 127
    ELSE IF t < 0 THEN 
        result&#58;=0
    ELSE  
        result&#58;=t; 
 END;  
END;

// main
BEGIN
   len &#58;= GetLength&#40;pIn&#41;;
   IF &#40;len > 0&#41;  THEN BEGIN
      transpose &#58;= trunc&#40;GetValue&#40;pTransp&#41;&#41;;
      SetLength&#40;pOut, len&#41;;
      FOR i &#58;= 0 TO &#40;len - 1&#41; DO BEGIN
         GetMidiArrayValue&#40;pIn, i, tmp&#41;; 
         tempTransp &#58;= transpose + tmp.data1; 
         IF  &#40;tmp.msg = 144&#41; AND &#40;tmp.data2 > 0&#41; THEN BEGIN // NoteOn
             tempTransp&#58;= calcTranspose&#40;tempTransp, GetValue&#40;pWrapAround&#41;&#41;;
             transp&#91;tmp.channel - 1&#93;&#91;tmp.data1&#93; &#58;= tempTransp;
             tmp.data1 &#58;= tempTransp;  
             SetMidiArrayValue&#40;pOut, i, tmp&#41;;
         END
         ELSE IF &#40;tmp.msg = 128&#41; or &#40;&#40;tmp.msg = 144&#41; and &#40;tmp.data2 = 0&#41;&#41; THEN // NoteOff
             tmp.data1 &#58;= transp&#91;tmp.channel - 1&#93;&#91;tmp.data1&#93;;  
             SetMidiArrayValue&#40;pOut, i, tmp&#41;;
         END;  
   END
   ELSE BEGIN
      SetLength&#40;pOut, 0&#41;;
   END;
END.

Code: Select all

//////////////////////////////////////////////////////
// multiply midi note
// 2008-10-24&#58; @bSork, first version of midi transpose
// 2008-10-26&#58; @amiga909, midi multiply
//////////////////////////////////////////////////////

VAR pIn, pOut, pMult, pWrapAround &#58; tParameter;

TYPE tMult = ARRAY OF integer;
VAR mult &#58; ARRAY OF tMult;

VAR tmp &#58; tMidi;
VAR len, i, tempMult &#58; integer;
VAR multiply&#58; double;

PROCEDURE Init;
BEGIN

   pIn &#58;= CreateParam&#40;'midi in', ptMidi&#41;; SetIsOutput&#40;pIn, FALSE&#41;;
   pOut &#58;= CreateParam&#40;'midi out', ptMidi&#41;; SetIsInput&#40;pOut, FALSE&#41;;

   pMult &#58;= CreateParam&#40;'multiply', ptDataFader&#41;; SetIsOutput&#40;pMult, FALSE&#41;;
   SetMin&#40;pMult, 0.125&#41;; SetMax&#40;pMult, 8&#41;; SetDefaultValue&#40;pMult,1&#41;;

   pWrapAround &#58;= CreateParam&#40;'wrap around', ptSwitch&#41;; SetIsOutput&#40;pWrapAround, FALSE&#41;;

   SetArrayLength&#40;mult, 16&#41;;
   FOR i &#58;= 0 TO 15 DO // A two-dimensional array; &#91;16 channels&#93;&#91;128 multiply values&#93;
      SetArrayLength&#40;mult&#91;i&#93;, 128&#41;;
END; 



// expects a noteOn msg with velocity > 0; outputs the multiplyd note value &#91;0-127&#93;
FUNCTION calcMultiply &#40;t&#58; integer; wrap&#58; single&#41;&#58; integer; 
var tt&#58;integer;
BEGIN
 IF wrap > 0 THEN BEGIN
    tt&#58;= 128*&#40;trunc&#40;t/128&#41;&#41;; 
    IF t > 127 THEN 
        result &#58;= t - tt
    ELSE IF t < 0 THEN 
        result &#58;= t + tt; 
 END
 ELSE BEGIN
    IF t > 127 THEN 
        result&#58;= 127
    ELSE IF t < 0 THEN 
        result&#58;=0
    ELSE  
        result&#58;=t; 
 END;  
END;

// main
BEGIN
   len &#58;= GetLength&#40;pIn&#41;;
   IF &#40;len > 0&#41;  THEN BEGIN
      multiply &#58;= &#40;GetValue&#40;pMult&#41;&#41;;
      SetLength&#40;pOut, len&#41;;
      FOR i &#58;= 0 TO &#40;len - 1&#41; DO BEGIN
         GetMidiArrayValue&#40;pIn, i, tmp&#41;; 
         tempMult &#58;= round &#40;multiply * tmp.data1&#41;; 
         IF  &#40;tmp.msg = 144&#41; AND &#40;tmp.data2 > 0&#41; THEN BEGIN // NoteOn
             tempMult&#58;= calcMultiply&#40;tempMult, GetValue&#40;pWrapAround&#41;&#41;;
             mult&#91;tmp.channel - 1&#93;&#91;tmp.data1&#93; &#58;= tempMult;
             tmp.data1 &#58;= tempMult;  
             SetMidiArrayValue&#40;pOut, i, tmp&#41;;
         END
         ELSE IF &#40;tmp.msg = 128&#41; or &#40;&#40;tmp.msg = 144&#41; and &#40;tmp.data2 = 0&#41;&#41; THEN // NoteOff
             tmp.data1 &#58;= mult&#91;tmp.channel - 1&#93;&#91;tmp.data1&#93;;  
             SetMidiArrayValue&#40;pOut, i, tmp&#41;;
         END;  
   END
   ELSE BEGIN
      SetLength&#40;pOut, 0&#41;;
   END;
END.


amiga909
Member
Posts: 324
Contact:

Unread post by amiga909 » 27 Oct 2008, 11:01

thanks.
there was an error in the 2nd script: noteOff detection asked for tmp.data2 instead of tmp.msg
more (hopefully some day bug-free) scripts to follow

.. thinking about a patch that ressembles a yamaha mep-4 (+ a note closer)
Image
used to have fun with this 4xIn/4xOut midi processor from 1986.

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

Unread post by bsork » 27 Oct 2008, 13:15

Not to hijack your topic, Amiga909, but in case anyone's interested here's another way of handling transposed values > 127 or < 0 that will keep the transposed value within the highest, respectively lowest octave (X = note number after transposing):

X > 127: 127 - 11 + ((X -128) MOD 12)

X < 0: ABS((12 + X) MOD 12)

Just a bit too lazy to upload a complete script right now... :)
Bjørn S

woodslanding
Member
Posts: 1327
Contact:

Unread post by woodslanding » 28 Oct 2008, 07:09

Hey, thanks Bsork! This will make it into my script. it looks like this creates 'foldback', llike in hammond organs....

I would probably implement it within the range of the piano keyboard, rather than 0 to 127.
Custom Ryzen 5900x MATX build, Win10, Fireface UFX, touchscreen
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify

moody33
Member
Posts: 338
Contact:

Unread post by moody33 » 28 Oct 2008, 17:44

Hi all !

Very interesting topic !

I had try some month ago to build a patch that keep note on/off into a specific range, even if the midi input range is out off this range, without great success. As I don't understand english very well, I have to ask you some question related to this topic.

- What means Wrap around? I don't understand this function.
- I think that bsork answer to my desire patch ( keep note on/off into a specific range ) with this comment :

X > 127: 127 - 11 + ((X -128) MOD 12)

X < 0: ABS((12 + X) MOD 12)

But where I have to copy this in a script?

If you have the time could you show me how to do a simple script with the following features:

- 2 input to specify the lower and higher notes . If the input is below or above this range, midi ouput is modulate. For example, i want a range between note number 36 and 60. If the input note is above 60 , the ouput have to stay between 48 (60-12=48) and 60. If the input is lower than note 36, then, the output have to stay between 36 and 48 (36+12=48)
- In also need an option that let choose if the modulator is engage or not. For example, always with a range of 36 to 60, I don't want notes below note number 30 takes in consideration. I want them ignored ( note 31 is modulated, but note 25 is ignored) So the idea is a second range input ( low and high) that specified a range of notes ( below or above the first range selector) to be ignored.

I'm really sorry for my bad english. I wish you understand my request, and I hope that a genius can create this script cause I've not good results with patching and I really understand nothing to scripting.

Thanks you in advance.

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

Unread post by bsork » 28 Oct 2008, 22:35

The wrap around function in Amiga909's scripts lets notes transposed above 127 be moved to the "bottom"; ie 128 becomes 0, 129 becomes 1, etc, and the other way around for notes transposed below 0. If not turned on, notes above 127 are set to 127, and below 0 to 0.

As for your request, I don't feel like a genius, but I'll see what I can do (unless - as always - someone else is quicker than me).
Bjørn S

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

Unread post by bsork » 29 Oct 2008, 10:56

Hi Moody33, I've created a script and a (sub-)patch and uploaded it in the add-ons/MIDI Tools: "Midi Transpose With Octave Foldback".

I ended up using slighty different math than what I outlined above. Mind you, the patch is NOT TESTED AT ALL, but the script compiles. I don't think I will have any time for testing it myself before tomorrow nigth, so if you can download it and test it for me that would be fine.

Of course, if anyone else want to have a go at it - please do!
Bjørn S

moody33
Member
Posts: 338
Contact:

Unread post by moody33 » 29 Oct 2008, 11:34

Bsork, you're the best !
Thanks you very much .
I'll take a look today.

moody33
Member
Posts: 338
Contact:

Unread post by moody33 » 29 Oct 2008, 11:45

Sorry Bsork, but I have to let you know that your script don't seems to works. It seems to modulate the midi input very randomly, and don't seems to take in consideration the range values. I wish that you could debug it cause I cant' !
Thanks you again.

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

Unread post by bsork » 29 Oct 2008, 11:50

Ok, sorry about that - it's been done in a hurry. You will have to wait then.
Bjørn S

moody33
Member
Posts: 338
Contact:

Unread post by moody33 » 29 Oct 2008, 11:52

Sure I can wait for this awesome script ! No problem!

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

Unread post by bsork » 29 Oct 2008, 12:12

Well I did have a look at the code, and had mixed plus and minus calculating the "octave foldback" in the upper range. Ooopsss...

Could you have another go at it ?
Bjørn S

moody33
Member
Posts: 338
Contact:

Unread post by moody33 » 29 Oct 2008, 12:22

Test: the same note number is always sending ( note 9 by default). Don't works..snif

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

Unread post by bsork » 29 Oct 2008, 23:20

I got some tiime tonight after all, so I've uploaded yet another version. Seems like I did a lot of small, typical programming errors this time. Sorry, but it will happen again ;)

This time I've done some testing, and seems ok to me, but the behaviour of the octave foldback together with the extra restriction of what notes to output can be somewhat confusing the first time it's encountered, I guess...

Try it and let me hear your comments!
Bjørn S

moody33
Member
Posts: 338
Contact:

Unread post by moody33 » 30 Oct 2008, 01:09

Bsork..I don't know to how to say... THANKS YOU VERY MUCH !
I've test it a bit and It seems to works very well.
I've notice only one thing, but it's normal and totally logical : if the range is below one octave, the script don't take care and modulate within a range of one or two octave around the specified range. It's logical and I'm happy to see that the script don't give strange results in this case. Really great script . It solved my problem so far! Perfect !

Finally, you're a genius !

amiga909
Member
Posts: 324
Contact:

Unread post by amiga909 » 30 Oct 2008, 05:12

you could try to do it without a script?
this little experiment patch here does not allow to change low and hi limits in real time (because of hanging notes problem).
further its not rescaled as moody specified.
ImageImage

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

Unread post by bsork » 30 Oct 2008, 08:32

@moody33: Yes, I know that it behaves a bit strange with small ranges, but it's a logical consequence of the features that doesn't make too much sense when the ranges get too small. That was partly what I was referring too when I said it was "somewhat confusing". It had gotten late, and I didn't want to elaborate the point... :) Anyway, I don't think this patch is very useful for very small ranges anyway - after all it's about transposing and thus "enlarging" the playable range.

@amiga909: You can restrict ranges and transpose without a script, but as you mention hanging notes are a problem if parameters are changed between NoteOn and NoteOff. I guess there are ways of getting the exact same behaviour as the various incarnations of the transpose script using only modules, but it wouldn't be easy, and I suspect that the result would end up as rather more complex to customize or debug than what is essentially a quite simple script.

Usine patching is as we all know very much about creating data flows, but the inherent problem of MIDI notes is that they consist of two essentialy non-related messages, so the NoteOff has to refer back to something earlier on in the flow one way or another, which can be tricky.
Bjørn S

moody33
Member
Posts: 338
Contact:

Unread post by moody33 » 30 Oct 2008, 12:01

Thanks you Amiga, but I've already build a patch like this. Bsork's script is exactly what I need and is so far better than patching. In patching mode , we have to build a "send all note off" when value are changed as bsork explain.

Moody.

amiga909
Member
Posts: 324
Contact:

Unread post by amiga909 » 31 Oct 2008, 05:08

added mep-expand to the midi tools.
probably not bug-free its good fun.

here a mp3 example
www.thaumat.org/_permShare/mp3/mep.dry.mp3
www.thaumat.org/_permShare/mp3/mep.wet.mp3

pretty weird ;)

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

Unread post by bsork » 31 Oct 2008, 06:28

:cool:
Bjørn S

Post Reply

Who is online

Users browsing this forum: No registered users and 9 guests