Playing a single bar still triggered notes placed exactly on the next bar
line. Two delays stack: the daemon polls at roughly frame rate, so it can
notice up to ~33ms late, and REAPER renders audio ahead of the play position
it reports, so the note has already reached the instrument before the stop
lands.
Stopping 60ms early clears both. The cost is a few milliseconds off the tail
of the bar, which is inaudible, and the benefit is that the downbeat you were
trying to exclude stays excluded. Tunable via the stoplead ExtState for setups
with large audio buffers.
Ctrl+Alt+Space plays the cursor's bar and stops at the next bar line, so the
same bar can be fired repeatedly while nudging a note without reaching for
stop. Alt+Space keeps its play-onwards behaviour.
The stop is performed by the preview daemon rather than the action script: a
script that stayed alive waiting for the bar to end would bring back REAPER's
"already running" prompt on the next press, which is the problem the daemon
exists to avoid. Stopping transport can move the edit cursor depending on
preferences, and the edit cursor is the grid cursor, so the daemon restores it.
A short arming window covers the gap between requesting playback and the
transport reporting as playing, so the pending stop is not cancelled instantly.
Alt+Space plays from the downbeat of the bar the cursor is in. Auditioning a
cell says what a note is; playing from the bar line says whether it is in the
right place, which is the question that matters at 16ths and 32nds and cannot
be answered from a note in isolation.
REAPER can almost do this by chaining a go-to-measure action with play, but
that leaves the edit cursor at the bar line -- and the edit cursor is the grid
cursor, so you would lose your editing position every time you listened. Here
the cursor is moved just long enough to start playback and then restored with
seekplay=false so the restore cannot drag playback with it.
Works regardless of grid mode, being a listening aid rather than an edit.
Ctrl+Shift+Left/Right move every note in the take by one grid cell, for
clips that landed off the beat.
Since the whole take moves together, notes cannot collide with each other;
the hazard is the item boundary. Notes pushed past either end stop sounding
but are not deleted, so the operation is reversible -- shifting back restores
them. The plain keys still refuse when that would happen and report the count,
because a clip that has silently lost its first bar is a bad thing to discover
later. Ctrl+Alt+Shift forces it and names the consequence.
Positions are converted through QN rather than offset in raw ticks, so shifts
stay musically correct across tempo changes.
Hold mode only governs entry, so sustaining existing notes previously meant
toggling hold on and re-entering them. That works but deletes and recreates
each note, silently resetting velocity to the default.
L and Shift+L resize the note under the cursor by whole grid cells, editing it
in place so velocity, channel and note identity survive. They are independent
of hold mode, so there is no state to set up or unset. Alt+J fuses a whole run
of repeated notes at one pitch in a single keystroke.
Lengthening absorbs same-pitch notes it runs into, taking their tail if longer,
so growing across a repeated run fuses it instead of creating overlaps.
Also makes noteEndingAt/noteStartingAt public and fixes their two call sites in
toggleCell, which would otherwise have been nil-call errors in hold mode.
Chords are built by stacking scale thirds rather than from a quality table,
so the chord follows the degree automatically -- in C major, Alt+3 on C gives
C major, on D gives D minor, on B gives B diminished. Toggling delegates to
toggleCell, so chord tones inherit hold-mode joining, splitting and trimming
unchanged.
Velocity keys act on the note under the cursor if there is one, and on the
default for new notes otherwise, announcing which. That avoids a mode switch
between setting a level to draw at and shaping dynamics after the fact.
Also fixes install.ps1 failing to resolve its own directory: $PSScriptRoot is
not reliably populated during parameter binding, so it is resolved in the body.
Tests cover chord quality per scale degree and range clamping.
Keyboard- and speech-driven step entry for the MIDI editor, built for use
with OSARA. Arrows walk grid cells and scale degrees, Enter toggles notes,
and every position is spoken and auditioned.
Uses REAPER's own edit cursor and active_note_row rather than private cursor
state, so grid mode and OSARA editing stay in sync. Grid size comes from
MIDI_GetGrid(), so existing grid keybindings drive it. When grid mode is off,
every bound key forwards to its previous action.
Preview timing lives in a background daemon so the action scripts can exit
immediately -- a script still alive on the next keypress triggers REAPER's
"already running" prompt and breaks key repeat.