Post by nooniens on Feb 9, 2019 14:06:33 GMT
These scripts are in a sense similar to the ”one finger orchestra” scripts, but yet quite different. The idea here is to have one stream of MIDI being ”modulated” by another. The modulated stream could for instance contain some arpeggiator pattern, strumming pattern or just something random stugg (e.g Rozeta Collider) from any external or internal MIDI source.
The modulating stream defines the chords to apply, using 1 to four notes (that are played ”close in time”). The chords can be defined using the following methods:
- 1 note played: Chord with that note as base. Major or minor depending on scale (see below)
- 2 notes: Minor (if 3 semi-notes apart) or major (4 semi-notes apart) with the lowest as base. If the two notes are less than three semi-notes apart, it will set the scale fortbe one finger mode
- 3 notes: Builds a chord of these three. Duplicate the lowest one octave higher
- 4 notes: Use these four as the chord (allows e.g 7th and sus4 chords)
The modulating stream could also come from any source, a sequencer track, or a keyboard. One script (identifier) is fed with the modulating stream. It sets the current chord notes as global variables
The modulated stream is fed into a script (mapper) that modulate it based on the current chord (read through the global variables). The input stream is assumed to only contain the notes of the Cmaj7 chord (any other note gets mapped to the closest note below it in that chord). The current chord replaces the notes of the Cmaj7.
So, if the input stream is C E G B, and the current chord is Am the output will become Am C E Am(+1 octave). If the input stream moves up one octave, so will the output. If the current chird moves up an octave, the output stream will as well.
One way of using this is to set up some kind of looping patterns in one or several (just use the mapper script again) sequencer tracks, and the chord progression in another (regular track or e.g Rozeta Cells). The patterns are sent through the mapper script while the progression is sent through the identifier. You can also control the chord progression using a keyboard.
This started off as a fun experiment, but it worked far better than expected. Useful? I let others judge, but I have fun playing with it..
"Identifier" script (used to identify the current chord):
The modulating stream defines the chords to apply, using 1 to four notes (that are played ”close in time”). The chords can be defined using the following methods:
- 1 note played: Chord with that note as base. Major or minor depending on scale (see below)
- 2 notes: Minor (if 3 semi-notes apart) or major (4 semi-notes apart) with the lowest as base. If the two notes are less than three semi-notes apart, it will set the scale fortbe one finger mode
- 3 notes: Builds a chord of these three. Duplicate the lowest one octave higher
- 4 notes: Use these four as the chord (allows e.g 7th and sus4 chords)
The modulating stream could also come from any source, a sequencer track, or a keyboard. One script (identifier) is fed with the modulating stream. It sets the current chord notes as global variables
The modulated stream is fed into a script (mapper) that modulate it based on the current chord (read through the global variables). The input stream is assumed to only contain the notes of the Cmaj7 chord (any other note gets mapped to the closest note below it in that chord). The current chord replaces the notes of the Cmaj7.
So, if the input stream is C E G B, and the current chord is Am the output will become Am C E Am(+1 octave). If the input stream moves up one octave, so will the output. If the current chird moves up an octave, the output stream will as well.
One way of using this is to set up some kind of looping patterns in one or several (just use the mapper script again) sequencer tracks, and the chord progression in another (regular track or e.g Rozeta Cells). The patterns are sent through the mapper script while the progression is sent through the identifier. You can also control the chord progression using a keyboard.
This started off as a fun experiment, but it worked far better than expected. Useful? I let others judge, but I have fun playing with it..
"Identifier" script (used to identify the current chord):
# Identify 4-note set scale, short hand
IF LOAD
ASS G40 = 00
ASS G41 = 00
ASS G42 = 00
ASS G43 = 00
ASS L0 = 40 # Global variable index keeping 1st of the 4 notes
ASS G3F = 0 # Scale index (0 = C)
ASS L10 = 00 02 04 05 07 09 0B # Scale notes
ASS L20 = 04 03 03 04 04 03 03 # Second note
ASS L30 = 07 07 07 07 07 07 06 # Third note
ASS L40 = 0C 0C 0C 0C 0C 0C 0C # Fourth note octave
END
9X XX 00 = 8X
IF MT == 90
IF T00 > 30 # If 30ms has passed since last, assume this is the first note to arrive
ASS L0 = 40
END
ASS GL0 = M1 # Add the current note to the 4-note array
ASS K1 = L0 # Sort the notes in ascending order
IF K1 > 40 +L
MAT K0 = K1 - 1
IF GK1 < GK0
ASS I0 = GK1
ASS GK1 = GK0
ASS GK0 = I0
END
ASS K1 = K0
END
MAT K2 = L0 + 1 # Fill with 1st note + 1 octave (normally overwritten later, unless only 3 fingers)
IF K2 < 44 +L
MAT GK2 = G40 + 0C
END
IF L0 == 40 # Single note received, calculate scale chord with this as base
MAT K3 = M1 % 0C
ASS K4 = 10 # index
IF K4 < 17 +L
MAT K6 = LK4 + G3F # Adapt to the current scale (add n semitones)
MAT K7 = K6 % 0C
IF K3 == K7 # Found a scale note
MAT K5 = 10 + K4
MAT G41 = M1 + LK5
MAT K5 = 20 + K4
MAT G42 = M1 + LK5
MAT K5 = 30 + K4
MAT G43 = M1 + LK5
END
MAT K4 = K4 + 1
END
END
IF L0 == 41 # Two notes received, calculate chords based on these. Also set the refereence scale for one-note mode !
MAT K10 = G41 - G40 # How far are these apart ?
IF K10 == 4 # Assume a Major chord !
MAT G41 = G40 + 4
MAT G42 = G40 + 7
MAT G43 = G40 + 0C
END
IF K10 == 3 # Assume a Minor chord !
MAT G41 = G40 + 3
MAT G42 = G40 + 7
MAT G43 = G40 + 0C
END
IF K10 == 0C # If an octave difference, it sets the scale
MAT G3F = G40 % 0C
END
END
MAT L0 = L0 + 1 # Advance counter
IF L0 > 43 # If 4 already received, start all over
ASS L0 = 40
END
SET LB0 G40 +N
SET LB1 G43 +N
END
"Mapper" script (used to map the input stream to the current chord):# Map to current 4-note
IF LOAD
ASS J0 = 01 # If set to 1, then "round down to nearest 4-tone"
ASS I00 = 00 04 07 0B # Index tones for input stream (Cmaj7)
END
IF M0 <= A0
9X XX 00 = 8X
ASS L0 = M1 # Incoming note value
IF M0 != 90
ASS L2 = JL0 # For note off and aftertouch set the same note value as for note on
ASS M1 = L2
END
IF M0 == 90
ASS L1 = L0
ASS K0 = 0 # Set Octave to 0
IF K0 <= 0A +L # Loop over octaves
MAT K1 = K0 * 0C # Base of current octave
ASS K2 = 00 # First index tone
IF K2 < 04 +L # Loop over index tones
MAT K3 = K1 + IK2 # Note value for this index tone
IF L0 >= K3 # We are at or above..
MAT K4 = K0 - 5 # Relation to reference octave (5)
IF J0 > 0
ASS K5 = 0
END
IF J0 == 0
MAT K5 = L0 - K3 # semitones above index tone
END
MAT K6 = K2 + 40 # reference to find current 4-note
ASS K7 = GK6 # Get the nth of the current 4-note
MAT K8 = K4 * 0C # Octave transpose
MAT K9 = K8 + K5 # tranpose semitones
MAT L1 = K7 + K9 # The transposed note
END
MAT K2 = K2 + 1 # Loop increment index tone
END
MAT K0 = K0 + 1 # Loop increment octave
END
ASS M1 = L1 # Change output
ASS JL0 = L1 # Remember output (avoiding stuck notes and enabling aftertouch)
END
END