Zero experience - Trying to write a script for multi for round robin of 8 instruments

I'm trying to write a script that will send incoming MIDI notes sequentially to 8 separate instruments in a multi. I keep getting errors. I'd be grateful for pointers.
I started by trying with 2 instruments.
Here's my bad script:
on init
declare $currentInstrument := 0
declare $numberOfInstruments := 2 { Assuming 2 instruments in the multi }
end on
on note
$currentInstrument := ($currentInstrument + 1) % $numberOfInstruments
if ($currentInstrument = 0) then
{ Send note to the first instrument in the multi }
play_note(0, $EVENT_NOTE, $EVENT_VELOCITY, -1)
else
{ Send note to the second instrument in the multi }
play_note(1, $EVENT_NOTE, $EVENT_VELOCITY, -1)
end if
ignore_event($EVENT_ID)
end on
Where is this getting screwed up? (Throughout?) I'd be grateful for any thoughts/corrections.
Comments
-
You can't use play_note in a multi script.
I reckon the best way to do this would be with MIDI channels
1 -
You need to be clear about the difference between Instrument Scripts and Multi Scripts. Instrument Scripts can apply to only one instrument. Multiscripts require some understanding of the MIDI protocol (not rocket science)
You need to programme precisely as in the manual (your syntax for play_note is wrong, as well as its use)
As medusa says, you could have your round robins in different instruments on their own channels with a multiscript, but only if your note-off messages are to be ignored (e.g. one-shot samples) otherwise you'd have to keep track of which note was played on which channel for the note-off, which would be very complicated.
something like
set_event_par($EVENT_ID, $EVENT_PAR_MIDI_CHANNEL . . . .)
with a variable which you increment with each note.
Be a lot simpler to use groups within an instrument. You probably wouldn't even need a script.
1 -
Thanks!
The goal is to arrive at a round robin whereby successive MIDI notes are played on successive instruments. e.g. instead of 1 (piano) 2 (same piano) 3 (same piano) 4 (same piano) etc. it would be 1 (piano) 2 (banjo) 3 (electric guitar) 4 (marimba), or whatever. This would be much like using a MonoPoly in revolving mode or a modular synth with sequential switches.
If you know of a simple way to achieve that I'd be very interested!
The brute force method would be splitting up my MIDI into 8 tracks, but definitely not preferred. I'm sure a good script is possible.
Your "be a lot simpler to use groups within an instrument" is interesting. Guessing wanting different instruments altogether per MIDI note makes that impossible?
0 -
Now I'm trying an instrument specific script to do the same thing. For simplicity I'm just doing a 2-instrument round-robin.
I would put the script in the instrument @ MIDI ch1 and no script in MIDI ch2.
This is the script:
on init
make_persistent($RR_chan)
$RR_chan := 1
end on
on note
if ($RR_chan = 1)
play_note($EVENT_NOTE, $EVENT_VELOCITY, 1, -1) { Route to Instrument 1 on MIDI channel 1 }
$RR_chan := 2
else
play_note($EVENT_NOTE, $EVENT_VELOCITY, 2, -1) { Route to Instrument 2 on MIDI channel 2 }
$RR_chan := 1
ignore_event($EVENT_ID)
end on
It throws off an error @ the last line, "end on". Any ideas? I'd be grateful.
0 -
you are missing an "end if"
0 -
Unfortunately if I add "end if" it throws off an error:
When I removed "end if" it passed that line but threw off an error on the last line:
0 -
read the errors
0 -
You really do need to study the parameters of play_note in the KSP manual. In your script the third parameter (your 1 or 2) is the sample start. In microseconds.
Others may correct me, but I don't think there is any way that a script in instrument 1 can trigger activity in instrument 2. You would have to use a multiscript, which would have the complications I mentioned above unless all your notes are one-shot (when it would be easy). You could set the channel for a note as I suggested, but its note-off must be on the same channel, so you would have to make a record of each note's channel to recall when its note-off is received. You could set up a 127-element array and do it.
Why not do it with groups? No reason why you shouldn't have piano banjo guitar internal combustion engine etc in separate groups in a single instrument - you can copy/paste groups - then give them RR numbers in Group Start Options. If one of your instruments has lots of groups, do the Group Start Options bit (Edit All Groups) before you copy them into the composite instrument.
1 -
Thanks for that feedback. I'm going to take a close look at whether I can make that work for me. Good stuff, much appreciated.
0 -
Actually not as complicated as I thought. Try this (untested) multiscript - assumes 4 instruments (line 11)
on init declare %nofchan[128] :=(0) declare $rr :=0 end on on midi_in if ($MIDI_COMMAND = $MIDI_COMMAND_NOTE_ON) set_event_par($EVENT_ID, $EVENT_PAR_MIDI_CHANNEL, $rr) %nofchan [get_event_par ($EVENT_ID, $EVENT_PAR_MIDI_BYTE_1)] := $rr $rr := ($rr + 1) mod 4 end if if ($MIDI_COMMAND = $MIDI_COMMAND_NOTE_OFF) set_event_par($EVENT_ID, $EVENT_PAR_MIDI_CHANNEL, %nofchan [get_event_par ($EVENT_ID, $EVENT_PAR_MIDI_BYTE_1)] ) end if end on
Paste into empty multiscript slot (KSP button top R of Kontakt window) and click Apply. If I've got it right, notes-off should be dealt with correctly.
1 -
Stephen, you nailed it! That works! Lives up to my hopes too.
Thanks so much, really very appreciated.
0
Categories
- All Categories
- 19 Welcome
- 1.5K Hangout
- 65 NI News
- 797 Tech Talks
- 4.1K Native Access
- 16.8K Komplete
- 2K Komplete General
- 4.4K Komplete Kontrol
- 5.8K Kontakt
- 1.6K Reaktor
- 386 Battery 4
- 854 Guitar Rig & FX
- 434 Massive X & Synths
- 1.3K Other Software & Hardware
- 5.9K Maschine
- 7.4K Traktor
- 7.4K Traktor Software & Hardware
- Check out everything you can do
- Create an account
- See member benefits
- Answer questions
- Ask the community
- See product news
- Connect with creators