i’ve been messing around with a rewrite of pattern_time
which cleans up its methods a bit and captures some of the things I’ve been baking into cheat codes 2. prompted by @okyeron’s ping and my own feeling of “stuckness”, i figured it’d be good to the WIP state to snag feedback + help cleaning it up and getting it wrapped
this is not release-ready or for general use – expect dragons
proposed scripting function changes
-
:rec_start()
+:rec_stop()
become:rec(state)
, where 1 is start and 0 is stop -
:start()
+:stop()
become:play(state)
, where 1 is start and 0 is stop -
:set_overdub()
becomes:overdub(state)
, where 1 is on and 0 is off - add
:loop(state)
, where 1 is looping playback and 0 is 1-shot playback
proposed scripting variable additions (useful for grid states)
-
.rec_state
returns 1 (recording) or 0 (not recording) -
.play_state
returns 1 (playing) or 0 (not playing) -
.overdub_state
returns 1 (overdub enabled) or 0 (overdub disabled) -
.loop_state
returns 1 (looping playback) or 0 (1-shot playback) -
.record_pending
returns true or false, depending onsync record to clock?
param -
.start_pending
returns true or false, depending onsync launch to clock?
param -
.name
returns the name of the pattern (see param note)
proposed parameter menu additions
when adding a pattern to a script, we’ll use longPatternName = pattern_time.new("name")
, where the “name” is passed to the new PATTERNS param menu.
if pattern time is added to a script, a PATTERNS
param menu is created and inherits the names of the script’s patterns. if no name is provided *
-
sync record to clock? /
*alias*_sync_recording
: use the global clock to sync pattern recording to start on beat and record for a fixed number of beats-
—> rec duration (beats) /
*alias*_rec_duration
: set the number of beats that the clock-synced recording should last (up to 256 beats)
-
—> rec duration (beats) /
-
sync launch to clock? /
*alias*_sync_start
: wait until a clock event before launching pattern playback-
—> timing /
*alias*_launch_timing
: wait till next beat or next bar to launch pattern playback?
-
—> timing /
-
quantization /
*alias*_quantization
: turn quantization on/off
quantization methodology
passive stuff, all working in the background
as a recording is being made (:rec_event
), each entry commits the .time
between itself and the event before it. after this is calculated, that duration is divided by clock.get_beat_sec()
to give us .time_beats
.
after the recording is committed, :calculate_quantum
is automatically called, which rounds the .time_beats
to the nearest eighth note value. this is committed as an entry’s .quantum
.
as the pattern plays back, it is either using the .time
or .quantum
to determine when to move to the next event (using either :next_event
or :quantized_advance
).
active stuff
if :quantize(1)
is executed, then the metro that drives unquantized playback stops and the clock-synced :quantized_advanced
function takes over.
what happens is basically a “runner” system – since our quantum is measured in 1/8th notes, we total how many 1/8th steps an event should last for and a runner keeps apace at an 1/8th note count – so if an event’s duration is 3 quantum, the runner will have to reach 3 before moving onto the next event in the pattern.
what’s wonky?
most of this feels really solid, but i would love some eyes on the quantization stuff. in the above repo, i’ve included a revised copy of earthsea that uses the proposed changes. on the grid: 1,1 is record start; 1,2 is playback; 1,3 is overdub; 1,7 is loop enable; 1,8 is clear.
- if you keep maiden open while recording a pattern, you’ll see a printout of the calculated quantum and time total. oddly, when clamping recording to 8 beats at 120 bpm, you’ll see a record time total of
4.0003619194031
(which is passable) and aquantum total: 8.375
. could use some help debugging this. - quantization also just doesn’t feel right for earthsea, where expressive + dynamic timing is much more critical. 1/16th notes felt ineffective, 1/4 notes a bore, but 1/8th doesn’t 100% gel either…
- things also get wiggly when overdubbing comes into play, since note-ons and note-offs can become confused. i can’t tell how much of this could be mitigated in
pattern_time
and how much should be handled by the script.
also, none of what i’m sharing has to be the baseline – if someone can approach things from a totally different angle with more desirable results, that’d be super! i just could use some extra hands + brains on this challenge and figured sharing some work might help