Scraped the previous dual channel version for a proper polyphonic version utilizing all 5 voices and note off to ensure no stuck notes.
This version is much better (imo)
Scraped the previous dual channel version for a proper polyphonic version utilizing all 5 voices and note off to ensure no stuck notes.
This version is much better (imo)
You must be logged in to post a comment.
privacy policy | contact us | discord | api | github issues
More details and preview video soon.
This is more ambient (progressions) than the previous version.
It also adds two unique generators for ch.1 and ch. 2 for a more dramatic, evolving effect.
Changes:
Polyrhythmic independent voice counters (v0: 4-16, v1: 6-24, v2: 8-32, v3: 12-48)
Per-voice NoteOff safety replacing shared kill loop
Staggered voice initialization preventing simultaneous firing on load
Here’s the script….
@Description
SPACEDRIFT v1.6.2 (Symmetric UX Edition)
Generative ambient engine featuring dual-axis harmonic symmetry,
dynamic scale matrixing, and variable clock subdivisions.
@End
@EvaluateMarkovProgression
roll = Random 1, 100
currentState = settings[3] // state_slot
if currentState = 1
if roll 30 and roll 60 and roll <= 85
settings[3] = 4 // to vi
else
settings[3] = 5 // to bVI (Symmetric Chromatic Mediant)
endif
elseif currentState = 2
if roll 50 and roll <= 80
settings[3] = 3
else
settings[3] = 5
endif
elseif currentState = 3
if roll <= 70
settings[3] = 1
else
settings[3] = 4
endif
elseif currentState = 4
if roll <= 60
settings[3] = 2
else
settings[3] = 5
endif
elseif currentState = 5
if roll 40
if chords[2] > 72
chords[2] = chords[2] – 12
chords[3] = chords[3] – 12
endif
endif
Log {Matrix State: }, targetState
@End
@UpdateUIFeedback
// Safe string variables for UI display strings
pNote = 48 + (GetKnobValue 0 * 12 / 127)
LabelKnob 0, {Pitch: }, pNote
LabelKnob 1, {Drift Max: }, GetKnobValue 1
LabelKnob 2, {Evolve Chance: }, GetKnobValue 2
LabelKnob 3, {Inv Cap: }, GetKnobValue 3
LabelKnob 4, {Sustain: }, GetKnobValue 4
LabelKnob 5, {Vel Drive: }, GetKnobValue 5
@End
@OnLoad
settings[0] = YES
settings[3] = 1
if Unassigned chords[0]
settings[2] = 75
settings[1] = 24
chords[0] = 48
chords[1] = 55
chords[2] = 60
chords[3] = 64
endif
if Unassigned firedNotes[0]
firedNotes[0] = 0
firedNotes[1] = 0
firedNotes[2] = 0
firedNotes[3] = 0
endif
pulseCounter = 0
nextTrigger = 0
lfoPhase = 0
lfoDirection = 1
SetRootNote 0
SetMetroPPQN 4
ShowLayout 4
SetKnobValue 0, 40
SetKnobValue 1, 64
SetKnobValue 2, settings[2]
SetKnobValue 3, 50
SetKnobValue 4, 110
SetKnobValue 5, 80
LabelPad 0, {EVOLVE: AUTO}
LabelPad 1, {MATRIX: SYMMETRIC}
LabelKnobs {SpaceDrift Generative Engine}
SetShortName {DRIFT}
voicePulse0 = 0
voicePulse1 = 0
voicePulse2 = 0
voicePulse3 = 0
voiceNext0 = 4
voiceNext1 = 8
voiceNext2 = 12
voiceNext3 = 16
Call @EvaluateMarkovProgression
Call @UpdateUIFeedback
@End
@OnShiftDown
Call @EvaluateMarkovProgression
@End
@OnMetroPulse
if lfoDirection = 1
lfoPhase = lfoPhase + 2
if lfoPhase >= 30
lfoDirection = 0
endif
else
lfoPhase = lfoPhase – 2
if lfoPhase = nextTrigger
pulseCounter = 0
subDivRoll = Random 1, 4
if subDivRoll = 1
nextTrigger = 8
elseif subDivRoll = 2
nextTrigger = 12
elseif subDivRoll = 3
nextTrigger = 16
else
nextTrigger = 24
endif
evoChance = GetKnobValue 2
if (Random 0, 127) 127
v = 127
endif
if v = voiceNext0
voicePulse0 = 0
voiceNext0 = Random 4, 16
if firedNotes[0] > 0
SendMIDINoteOff 0, firedNotes[0], 0, 0
endif
firedNotes[0] = chords[0]
SendMIDINoteOn 0, firedNotes[0], v, drift0
SendMIDINoteOff 0, firedNotes[0], 0, (gateLength + drift0)
endif
if voicePulse1 >= voiceNext1
voicePulse1 = 0
voiceNext1 = Random 6, 24
if (Random 1, 100) 0
SendMIDINoteOff 0, firedNotes[1], 0, 0
endif
firedNotes[1] = chords[1]
SendMIDINoteOn 0, firedNotes[1], v, drift1
SendMIDINoteOff 0, firedNotes[1], 0, (gateLength + drift1)
else
firedNotes[1] = 0
endif
endif
if voicePulse2 >= voiceNext2
voicePulse2 = 0
voiceNext2 = Random 8, 32
if (Random 1, 100) 0
SendMIDINoteOff 0, firedNotes[2], 0, 0
endif
firedNotes[2] = chords[2]
SendMIDINoteOn 0, firedNotes[2], v, drift2
SendMIDINoteOff 0, firedNotes[2], 0, (gateLength + drift2)
else
firedNotes[2] = 0
endif
endif
if voicePulse3 >= voiceNext3
voicePulse3 = 0
voiceNext3 = Random 12, 48
if (Random 1, 100) 0
SendMIDINoteOff 0, firedNotes[3], 0, 0
endif
firedNotes[3] = chords[3]
SendMIDINoteOn 0, firedNotes[3], v, drift3
SendMIDINoteOff 0, firedNotes[3], 0, (gateLength + drift3)
else
firedNotes[3] = 0
endif
endif
endif
voicePulse0 = voicePulse0 + 1
voicePulse1 = voicePulse1 + 1
voicePulse2 = voicePulse2 + 1
voicePulse3 = voicePulse3 + 1
pulseCounter = pulseCounter + 1
@End
@OnKnobChange
if LastKnob = 0
Call @EvaluateMarkovProgression
endif
Call @UpdateUIFeedback
@End
@OnPadDown
if LastPad = 0
if settings[0] = YES
settings[0] = NO
LabelPad 0, {EVOLVE: LOCKED}
SetKnobValue 2, 0
else
settings[0] = YES
LabelPad 0, {EVOLVE: AUTO}
SetKnobValue 2, 75
endif
Call @UpdateUIFeedback
endif
@End