Generate sequence of different MIDI notes from the same message

Kulu Orr

2012-09-19 22:52:21

Hi,

I don't quite know the limitations of MT, so perhaps someone more knowledgeable than I might enlighten me.

The situation I have is a stream of repetitive MIDI messages coming in, all identical (e.g., same key pressed over and over again on a MIDI keyboard). This stream has to be mapped onto a pre-defined array of MIDI mesages, one at a time, in a looping fashion - starting over after the last one has been reached (e.g., playing the notes of a major musical scale, advancing one note each time the keyboard key is pressed, going back to the first note after 7 keystrokes).

This repeats until another MIDI message comes in (the "change" command - a pre defined message), followed by another stream of repetitive MIDI messages, the same as before. However, the "change" message caused the incoming messages to now be mapped to a different pre-defined array of MIDI messages (for the sake of the example - now the repetitive keystrokes should be mapped onto the musical notes of a minor scale, in looped succession).

If MT supports relatively complex scripts, with looping and conditional statements, then this would not be a hard script to code. However I do not know if MT has these capabilities.

Any ideas? Do you think this could be implemented using MT?
If not, do you have any clue for me what tool might be relevant?

Thanks a lot in advance!
Kulu Orr.

florian

2012-09-20 11:55:44

(I have just started replying to your email, when I saw this thread here)
This is possible in MT. It does have mini-scripting ("Rules"), that allows conditionals and basic variable manipulation.
However, it does not have arrays (yet), so implementing your requirements is possible, but requries a bit of typing to set up.

Let IN1 be the regularly coming MIDI IN message. In this example, I use a controller message #1 with value 0: B0 01 00, and for IN2 I use the same with value 01: B0 01 00.
It sends out OUT1(1), then on next IN1 it sends OUT1(2), etc. until OUT1(MAX), until which it restarts at sending OUT1(1).
Let IN2 be the message that switches from OUT1 to OUT2, and vice versa. For this example, I assume the arrays OUT1 and OUT2 have 4 items.

1) For every IN1 incoming message, increase a counter "g0" (a global variable in MT).

Code: Select all

Translator 0: "increase array index g0"
Incoming: MIDI <IN1>
Rules:
 g0=g0+1
 if g0>4 then g0=1
Outgoing: <none>
2) I assume that you cannot express the OUT arrays as mathematical formulas, which would be easy in MT with Rules for shifting, scaling, reversing, etc. So for arbitrary series of numbers, you can emulate an array with a series of IF conditionals. For matter of example, let OUT1 be an array with [40, 43, 45, 49]. Then we have this translator for OUT1:

Code: Select all

Translator 2: Send out OUT1
Incoming: MIDI <IN1>
Rules:
 if g0==1 then pp=40
 if g0==2 then pp=43
 if g0==3 then pp=45
 if g0==4 then pp=49
Outgoing: 90 pp 7F
This will send a note 40, then note 43, and so on for every IN1 message. pp is a local variable that is usable within one translator.

3) Switch using IN2
For this, use a second global variable g1, which remembers the current "layer": 0 for OUT1 or 1 for OUT2.

Code: Select all

Translator 1: "toggle layer index g1"
Incoming: MIDI <IN2>
Rules:
 g1=g1+1
 if g1>1 then g1=0
Outgoing: <none>
Now at any given time, we know which layer we're in by checking g1 (at start, it's initialized with 0). We only need to make sure, we use OUT1 and OUT2 accordingly. Replace the translator above and add as follows. I assume OUT2 to be [50, 55, 60, 63].

Code: Select all

Translator 2: Send out OUT1
Incoming: MIDI <IN1>
Rules:
 if g1!=0 then exit rules, skip Outgoing Action
 if g0==1 then pp=40
 if g0==2 then pp=43
 if g0==3 then pp=45
 if g0==4 then pp=49
Outgoing: 90 pp 7F

Translator 3: Send out OUT2
Incoming: MIDI <IN1>
Rules:
 if g1!=1 then exit rules, skip Outgoing Action
 if g0==1 then pp=50
 if g0==2 then pp=55
 if g0==3 then pp=60
 if g0==4 then pp=63
Outgoing: 90 pp 7F
This is one way for how this can be done. There are some things missing:
- send note off (when?)
- allow OUT1 and OUT2 to be of different length

You can try this with the trial version of Midi Translator.

Regards,
Florian

Kulu Orr

2012-09-20 13:15:37

Wow, this must have been the most amazingly helpful reply I have ever received on a forum ever...
I will study all the information you have been so gracious to provide and see if I can implement it.
Thank you so much for your time and effort!
Kulu.

Kulu Orr

2012-09-20 23:32:57

Well, I know that's not why you did it, but I'm happy to say that it was worth your while to sit and write that comprehesive reply - I just bought MT Pro and wouldn't have done so if you hadn't shown in such detail how my needs can be addressed by it (I was actually already trying to get in touch with a Java programmer in order to get him to write me some
MjDj MIDI Morph modules!).
So thanks again!
Kulu.

florian

2012-09-21 02:00:18

you're very welcome! I'd hate to become detached of the actual users of my software, and it's important to guide people how to use the software (it's not always self-explaining...). And often, the tasks are interesting to find a solution for, too!
Florian

Kulu Orr

2012-12-06 11:07:57

Hi,
I've been working on and advancing my projec, however now I have come across an obstacle I can not seem to pass: I need to define several sets of 25 MIDI notes that my incoming note (always the same note) should be mapped to sequentially: First time it is hit it will be mapped to output-note number 1, second time it is hit it will be mapped to output-note number 2, etc.
However there is a limit on the number of variables I can use - there are only 10 local variables and not too many globals either.
Any advice for me how this might be implemented?
Thanks,
Kul.

florian

2012-12-06 11:30:31

Hi,

I'd implement it the same way as outlined above in my first reply, steps 1) and 2). Just change step 1) to let g0 go up to 24 instead of 4. Then in step 2), extend the series of "if g0=0" to "if g0=24".

Thanks,
Florian

Kulu Orr

2012-12-06 18:09:34

Oh, I see! g0 can go up to g(any number)!
What is the limit? Is g100 also allowed?
Thanks!

DvlsAdvct

2012-12-07 00:22:30

Hi Kulu

the global variables can only go from g0-g9, but they can also go from ga-gz

This works on g, h, i, j, k, l, m, n, allowing for 288 global variable options.

Global variables, however, can equal an unlimited amount, so g0 can = extremely high numbers. Does that make sense? So if you need to map variables sequentially, g0 can easily = 25.

Kulu Orr

2014-01-25 00:49:45

Hi Florian,

Well, it's been a while since you helped me immensely with your excellent software and with your great advice.
And I promised to send you he results when my project is finished.

You can watch it here on YouTube, it's about 10 minutes long -
http://youtu.be/53I8waT6UJA
(don't forget to watch on HD and have your speakers on...)
Or here if you prefer Vimeo -
https://vimeo.com/84117097

All the sounds you hear, except the vocals, have your software to thank, as all the hardware (control surfaces I bounce ball off) to software (Ableton live DAW) interface is managed by BMT.

Thank you so much! Both for your excellent program as well as yo your valuable and generous advice!

Kulu

mschnell

2014-01-26 10:22:37

Great !!

Other "Artists" just use Native Instrument "Machine" for generating a lot less impressive loop based oeuvres with much less artistic additional effort and visual expression.

-Michael

florian

2014-02-09 14:35:02

Hi Kulu, as already said to you, I think it's a fantastic performance and a great, fresh, concept.
Thanks,
Florian