MIDI clock sync + note output over USB/BLE (v0.18.0)
Add a MIDI Sync settings card (before the binding cards) with Send and Receive MIDI clock toggles, both off by default and persisted. Send: a dedicated thread emits clock (0xF8) at 24 PPQN plus Start/Stop on the transport edges to every attached MIDI device (USB + Bluetooth), and — because a sequencer should drive gear, not just its tempo — also forwards the tracks' note-on/off on each cell's MIDI channel. Notes are queued from the audio thread through a lock-free ring and drained by the send thread, mirroring the mono-per- track cell lifecycle; stop/pause/panic release everything so external notes never hang. (Per-channel Arpeggiator/Transposer are internal FX and aren't reflected.) Receive: MidiInput now forwards real-time bytes to the clock module, which follows an external clock — Start/Continue starts the transport, Stop pauses it, and the pulse rate drives the tempo (a tempo + transport follow, not a sample-locked slave). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,11 @@ class SizzleApp : Application() {
|
||||
val gamepadInput: GamepadInput by lazy { GamepadInput(inputRouter) }
|
||||
val midiInput: MidiInput by lazy { MidiInput(this, inputRouter) }
|
||||
|
||||
/** MIDI clock sync (send/receive) over USB + Bluetooth MIDI. */
|
||||
val midiClock: space.rcmd.android.sizzle.input.MidiClock by lazy {
|
||||
space.rcmd.android.sizzle.input.MidiClock(this)
|
||||
}
|
||||
|
||||
/** Persists the input binding maps across restarts (DataStore-backed). */
|
||||
val bindingStore: BindingStore by lazy { BindingStore(this) }
|
||||
|
||||
@@ -80,6 +85,8 @@ class SizzleApp : Application() {
|
||||
// single small read; blocking briefly at cold start keeps the input maps
|
||||
// authoritative from the first keypress rather than racing an async load.
|
||||
runBlocking { bindingStore.loadInto(keyboardInput, gamepadInput, midiInput) }
|
||||
// Feed incoming MIDI real-time (clock / start / stop) to the clock sync module.
|
||||
midiInput.onRealtime = midiClock::handleRealtime
|
||||
installCrashAutosave()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user