Post by nic on May 3, 2019 18:53:50 GMT
Incoming MIDI messages, are of course, at the heart of StreamByter; they come in, are processed and go out.
All rules in a script that are not enclosed in an 'if load' block are evaluated in order against the current MIDI message. So each time a message comes in, it is passed through the rules.
The current MIDI message is available to a script in the 'M' variable array, which can be of any length of 8 bit bytes. Most messages are 1 to 3 bytes in size, so quite small. The exception to this is a sysex message which will be larger. Non sysex messages have a fixed length depending upon the type of message. Note, controller, pitchbend, aftertouch will always be 3 bytes long. Program change and channel pressure messages are 2 bytes. Clock ticks and other realtime messages can be just 1 byte. The first byte in the message will be in M0, 2nd byte in M1 and so on.
As well as the 'M' array, there are a some special variables that are complementary to it:
MT - the type of message (80, 90, A0, B0, C0, D0, E0, F0) - this is the status nibble in MIDI
MC - the MIDI channel of the message (0-F) - this is the channel nibble in MIDI
ML - the length of the MIDI message
You can use these special variables anywhere you would use any other value. You can set an ALIAS for the M array and special variables. If you use the standard includes, then a number of useful aliases are already created for you.
Most often you will want to do things when you see messages that match some sort of criteria, although there is nothing stopping you from doing something for every message received.
Here are some examples of IF rules (without bodies, they are just examples) for detecting certain types of messages:
if M0 == B0 # controller message on channel 1
if M0 == B0 0C # controller number 12 (decimal) on channel 1
if M0 == B0 0D 7F # controller number 13 (decimal) on channel 1
Here are the same examples using the textual names and decimals with the standard factory includes:
if load
set include factory standard_includes
end
if midi_msg_data == midi_msg_cc
if midi_msg_data == midi_msg_cc $12
if midi_msg_data == midi_msg_cc $13 $127
Thus, to detect a specific MIDI message, you just need the relevant if clause(s) against the M variable array.
If you wish to change the message as it passes though, you simply use ASSIGN (or MATH) to the requisite M array position. This example fixes the velocity of all notes on channel 2 to 80:
if MC == 1 # is it on channel 2?
if MT == 90 # is it a note?
# set the velocity of the note
# 3rd byte (M2) of a note on message
# is the velocity value
assign M2 = $80
end
end
If you wish to block a message you use the BLOCK rule. This example demonstrates blocking all clock ticks:
if M0 == F8
block
end
All rules in a script that are not enclosed in an 'if load' block are evaluated in order against the current MIDI message. So each time a message comes in, it is passed through the rules.
The current MIDI message is available to a script in the 'M' variable array, which can be of any length of 8 bit bytes. Most messages are 1 to 3 bytes in size, so quite small. The exception to this is a sysex message which will be larger. Non sysex messages have a fixed length depending upon the type of message. Note, controller, pitchbend, aftertouch will always be 3 bytes long. Program change and channel pressure messages are 2 bytes. Clock ticks and other realtime messages can be just 1 byte. The first byte in the message will be in M0, 2nd byte in M1 and so on.
As well as the 'M' array, there are a some special variables that are complementary to it:
MT - the type of message (80, 90, A0, B0, C0, D0, E0, F0) - this is the status nibble in MIDI
MC - the MIDI channel of the message (0-F) - this is the channel nibble in MIDI
ML - the length of the MIDI message
You can use these special variables anywhere you would use any other value. You can set an ALIAS for the M array and special variables. If you use the standard includes, then a number of useful aliases are already created for you.
Most often you will want to do things when you see messages that match some sort of criteria, although there is nothing stopping you from doing something for every message received.
Here are some examples of IF rules (without bodies, they are just examples) for detecting certain types of messages:
if M0 == B0 # controller message on channel 1
if M0 == B0 0C # controller number 12 (decimal) on channel 1
if M0 == B0 0D 7F # controller number 13 (decimal) on channel 1
Here are the same examples using the textual names and decimals with the standard factory includes:
if load
set include factory standard_includes
end
if midi_msg_data == midi_msg_cc
if midi_msg_data == midi_msg_cc $12
if midi_msg_data == midi_msg_cc $13 $127
Thus, to detect a specific MIDI message, you just need the relevant if clause(s) against the M variable array.
If you wish to change the message as it passes though, you simply use ASSIGN (or MATH) to the requisite M array position. This example fixes the velocity of all notes on channel 2 to 80:
if MC == 1 # is it on channel 2?
if MT == 90 # is it a note?
# set the velocity of the note
# 3rd byte (M2) of a note on message
# is the velocity value
assign M2 = $80
end
end
If you wish to block a message you use the BLOCK rule. This example demonstrates blocking all clock ticks:
if M0 == F8
block
end