Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/2026-10-27-timestretch-analyzer-gate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Octatrack base: tracks with TSTR set to OFF no longer run the stock time-stretch analysis. Stock runs it for every playing Flex or Static track on every audio frame, even when the track never stretches, at about 1 to 1.4% of the CPU per track. Tracks with time-stretch on, BEAT included, and recorder loops work exactly as before. Thanks to Bryan T for measuring it and Zac Kyoti for mapping it.
2 changes: 1 addition & 1 deletion docs/OCTATRACK_DRIVING.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ error and moves on. macOS `nc -U` hangs up before the reply, so use the script.
|---|---|
| `KEY`, `KEY+KEY`, `KEY*N` | press (holding all but the last); `T1`-`T8`, `TRIG1`-`TRIG16`, `FX1`, `FX2`, `SRC`, `AMP`, `LFO`, `FUNC`, `YES`, `NO`, `UP`, `DOWN`, `LEFT`, `RIGHT`, `PLAY`, `STOP`, `REC`, `CUE`, `PATTERN`, `BANK`, `PAGE`, `PROJ`, `PART`, `AED`, `ARR`, `MIDI`, `SCENEA`, `SCENEB`, `PUSHA`-`PUSHF` (`FUNC+PAGE`: PATTERN SCALE, where LEVEL sets the length) |
| `+KEY`, `-KEY` | hold, let go |
| `encA+3`, `encLEVEL-2`, `fader128` | encoders A-F, LEVEL, the crossfader. Some setup values take several detents a step: MIDI NOTE SETUP's CHAN, BANK and PROG did not move on `encA+3`, and `encA+20` moved CHAN by 6 (21 October 2026); LFO SETUP's WAVE takes about four detents a step. A step is one signed byte: keep it within ±127, as `encB+200` turned WAVE backwards (24 October 2026) |
| `encA+3`, `encLEVEL-2`, `fader128` | encoders A-F, LEVEL, the crossfader. Some setup values take several detents a step: MIDI NOTE SETUP's CHAN, BANK and PROG did not move on `encA+3`, and `encA+20` moved CHAN by 6 (21 October 2026); LFO SETUP's WAVE takes about four detents a step; SRC SETUP's TSTR (encoder E) moved only on a large turn (`encE+40` went OFF to BEAT after seven `encE+2` did nothing, 27 October 2026). A step is one signed byte: keep it within ±127, as `encB+200` turned WAVE backwards (24 October 2026) |
| `w300` | wait 300 ms (rarely needed: the steps below wait for their own result) |
| `pick:T1:FX2:SPRING_REV` | pick an effect by name (spaces as `_`), FX1 or FX2: the chooser opens, LEVEL scrolls the exact rows, YES; done once the track runs it (about 120 ms after YES); fails at once if the loader refuses. A notice on screen eats its first keys and it times out after 5 s: after removing a module the bank names (MISSING MODULES) send `YES` first |
| `part1`-`part4` | switch Parts (PART + an arrow), done once the Part changed |
Expand Down
20 changes: 10 additions & 10 deletions sdk/machines/octatrack/base-binding.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
{
"schema": 1,
"identity": "cd2583c02dc3c47fd388eb4f4e0ec26e2d06e0eba54bb87ea705ab90146fdc1e",
"identity": "5273cecd1f8e1cd49dcc431c2a6dfd5e88b1272f6df7224bfc5564283dbc7951",
"arena": 1089490400,
"pool": 1087529856,
"symbols": {
"modwerk_controller_write_begin": 1084871240,
"modwerk_controller_write_end": 1084871268,
"modwerk_cue_cfg_clamp": 1085060424,
"modwerk_raise_ev_mute_keep": 1085062778
"modwerk_cue_cfg_clamp": 1085060456,
"modwerk_raise_ev_mute_keep": 1085062810
},
"controllers": {
"sidechain-compressor": "48104b9770742324df8d76c3f43031439ad986c0247843524b3a6c053d229e30",
"output-matrix": "4b653212a0f2189e8730ba5f3f3d4a23fa72219385e7fd42ccf8e0557f26f544",
"analog-bassdrum": "9b536a81404546319ac520d05b39e0bfe508bad03453f2828ec421d046c64a70"
},
"variants": {
"tracks-main-cue": "cd2583c02dc3c47fd388eb4f4e0ec26e2d06e0eba54bb87ea705ab90146fdc1e",
"tracks": "23db7ef477dfdea1e6cf7f6da6bfa0bb3d7cb09ab132fd0f8f1627dc7a3f1525",
"tracks-post": "8c6067a0fcca58683b5d704a9274baaf8755026114d6229eb49a26ef87bc121f",
"main-cue": "50e774c66efcca608b3200989822f74dbbbaf546297dde4e334a55d3cbfd39cf",
"main": "3c047763068c077f53038f534879d60015e80969d77a6e353afeff61594e47dc",
"master": "4d4761ffd373b68ed1eae845194510dbab6bc7725bff75532cad4008c4f75c96",
"off": "1f9a475d9acacaeb4916a6a8f1d9f6ecda22b1be0e4eca966c1b2b8641762a91"
"tracks-main-cue": "5273cecd1f8e1cd49dcc431c2a6dfd5e88b1272f6df7224bfc5564283dbc7951",
"tracks": "798af037ac60fcc0c2fad90a841a9d6309939c7f9b361364642f7b27014bed05",
"tracks-post": "033eabde01a695c66c08184b470c8433828571a5df1900c594b435fdd6069a2b",
"main-cue": "f359cf2ad70695a1db0e1254c2a5c41b41c816fc99cbe2db551b5b5eadf53f0f",
"main": "602b97d959d45c3975a93588fe98eaa32d2ce524a1ec16e10572845f1bbf70f3",
"master": "a8db21e2e041efa5b0883818575c0a814c0391cc90b5550af27760f14f7f28fa",
"off": "c5e8c89a828fe70b792e21754cf0f5ee2c54d1636961e2f3719ac7598bbc0cb8"
}
}
3 changes: 3 additions & 0 deletions sdk/machines/octatrack/elekloader/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ export 31-33, volatile journal 34-36, which refuses anything else there): pick a

### Status page

`status.s` also gates stock's time-stretch helper task (`mw_ts_gate`): it skips a track whose TSTR is OFF, since only
time-stretch reads its splice search and only BEAT reads its transient markers.

`status.c` measures, all the time, the ColdFire's load (main's idle spin, timed on DTIM3, `status.s`), each
DSP core's mean and peak load (core 0's own idle count, core 1's counted wait for core 0, `dsp_receiver.asm`),
each core's code arena, the delay-buffer blocks and the module pool. CUE + PROJ shows it as a dialog (NO closes it),
Expand Down
4 changes: 3 additions & 1 deletion sdk/machines/octatrack/elekloader/build_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,9 @@ def check_zero_state(elf, moved, layout, mapping, bootstrap):
(0x40047a3c, 6, '9b2c003ba4d776237ad71bef15451bfea4447f2acca77ef6922dcea6ac52ca78', 'mw_wide_dial'),
# Modwerk's: main's idle spin counts the ColdFire's idle time (status.s, status.c). Its last init call only:
# stock's spin stays, where ot_emu parks main again after a bench call.
(0x4001fc96, 6, '2edb8c17ea73bf5ecd097ec929f3bfd6f8a74c81b11080d0d74efd55bec6b416', 'mw_idle'))
(0x4001fc96, 6, '2edb8c17ea73bf5ecd097ec929f3bfd6f8a74c81b11080d0d74efd55bec6b416', 'mw_idle'),
# Modwerk's: the time-stretch helper task skips a track whose TSTR is OFF (status.s).
(0x40098b2c, 8, 'e3b2889593533c76e33bdee43526078d47b0b1c53b99a6d93d9ff1118e752203', 'mw_ts_gate'))
# --dsp-loader: the knob routine of an audio track's main pages (0x40055008) names the default stepper 0x4003240c by
# `lea 0x4003240c,%aN` for a live turn; the base repoints that operand at fxpage.s's mw_knob_step, which restages a
# module page's turned knob before it (a select then steps as stock's do from the first visit). Address, the lea's
Expand Down
19 changes: 18 additions & 1 deletion sdk/machines/octatrack/elekloader/status.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
| The ColdFire's idle time (status.c): main runs the init list, then spins at 0x4001fc9c for good, and that
| spin is the idle task (Octabam's KERNEL.md: the lowest priority, run when nothing else wants the CPU).
.text
.global mw_idle
.global mw_idle, mw_ts_gate

| 0x4001fc96, main's last init call. Displaced: jsr 0x40098a2c; this spin never returns to stock's (0x4001fc9c,
| left in place: ot_emu parks main there again after a bench call, its detoured-park convention).
Expand All @@ -20,3 +20,20 @@ mw_idle:
bhi.s 1b
add.l %d1,modwerk_idle_counts
bra.s 1b

| 0x40098b2c, the time-stretch helper task (0x40098a5c, prio 1), per track right after it copied the voice
| to 44(sp). The frame posts it every frame, and for each playing track it runs the splice search 0x4009871c
| (each trig bumps voice +144) and the transient detector 0x400985ac, whatever the track's TSTR. The renderer
| reads the splice result only with time-stretch on and the markers only in BEAT, so a track whose resolved
| TSTR (voice +24 = 68(sp)) is OFF skips both. The trig's reset requests stay pending, so the first pass after
| TSTR is back on catches up as stock does after a jump. Found by Bryan T, mapped by Zac Kyoti.
| Displaced: movea.l (%a3),%a0 ; cmpa.l 188(%sp),%a0 ; beq.s 0x40098b5e.
mw_ts_gate:
tst.b 68(%sp)
beq.s 1f
movea.l (%a3),%a0
cmpa.l 188(%sp),%a0
beq.s 2f
jmp 0x40098b34
2: jmp 0x40098b5e
1: jmp 0x40098cc8 | the next track
6 changes: 3 additions & 3 deletions sdk/tests/test_table_admission.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ def test_production_boundary_links_strong_helper_and_fixed_empty_reservations(se
'-fno-jump-tables', '-fno-asynchronous-unwind-tables', '-fomit-frame-pointer',
'-ffunction-sections', '-fdata-sections', '-Wall', '-Wextra', '-Werror',
'-I' + str(glue), '-I' + str(ADAPTER), '-I' + str(ROOT / 'sdk/runtime/loader'),
'-I' + str(ROOT / 'sdk/runtime/upload')]
'-I' + str(ROOT / 'sdk/runtime/upload'), '-I' + str(ROOT / 'sdk/machines/octatrack/include')]
sources = [entry, glue / 'runtime.c', *[ADAPTER / (name + '.c') for name in
('machine_admission_runtime', 'machine_admission', 'machine_contributors', 'machine_declarations',
'machine_lifetime', 'machine_parts', 'table_admission', 'table_declarations')]]
'machine_lifetime', 'machine_parts', 'sample_editor_actions', 'table_admission', 'table_declarations')]]
objects = []
for source in sources:
obj = work / (source.stem + '.o')
Expand Down Expand Up @@ -90,7 +90,7 @@ def test_private_actual_loader_undo_and_original_list_reset(self):
'-fno-jump-tables', '-fno-asynchronous-unwind-tables', '-fomit-frame-pointer',
'-ffunction-sections', '-fdata-sections', '-Wall', '-Wextra', '-Werror',
'-I' + str(glue), '-I' + str(ADAPTER), '-I' + str(ROOT / 'sdk/runtime/loader'),
'-I' + str(ROOT / 'sdk/runtime/upload')]
'-I' + str(ROOT / 'sdk/runtime/upload'), '-I' + str(ROOT / 'sdk/machines/octatrack/include')]
objects = []
for source in [glue / 'runtime.c', *[ADAPTER / (name + '.c') for name in
('loader_table_driver', 'table_admission', 'table_declarations', 'machine_lifetime',
Expand Down
4 changes: 2 additions & 2 deletions src/engine/assets/octatrack-base-sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"sdk/machines/octatrack/elekloader/boot.s": "c12eaa3cdc4d642e4ba86f72a77b2bd6869c8106b81f3b6a02d04176de06b739",
"sdk/machines/octatrack/elekloader/boot_anim.c": "191960aa25ebd605ad7be5e77dd00c243f2bd8619e7caf34c657ef0feeb7e743",
"sdk/machines/octatrack/elekloader/boot_anim.s": "c1abdf728b67ee9a1b5509b197edc6592c17baf35200634311765686e4ab839d",
"sdk/machines/octatrack/elekloader/build_core.py": "5faf4341d4a0c90871daaaf626952d2140ab3b809ace0aac2ee2f3120a0c94c8",
"sdk/machines/octatrack/elekloader/build_core.py": "e38186c1cbdec694d344dd1e3d6597f92b4b64544e74bc2668e383cd2dbf06e2",
"sdk/machines/octatrack/elekloader/build_ports.py": "43f0645a0ba0afa24ac98134bac858bb64cd22b598237b7491f9222483e265f7",
"sdk/machines/octatrack/elekloader/build_stub.py": "3c33c68977054ae6d0ebae9fdf6ae308eae7b05cf18260ffea5561d9baa00ef3",
"sdk/machines/octatrack/elekloader/check_flash_safety.py": "4c9392befe1fb28cf6a40ccd967ed486eb6f147b0a4176d7e16e6fea1d830cbd",
Expand Down Expand Up @@ -70,7 +70,7 @@
"sdk/machines/octatrack/elekloader/slots.h": "66acbc424a221cf3a74d60d51e912e887df318bc438ba038724efbb0e0aa3acb",
"sdk/machines/octatrack/elekloader/status.c": "beb839085760fccd235c61e95d58948c6c393d7f96f28f35890a79bcfeb2b5f3",
"sdk/machines/octatrack/elekloader/status.h": "2a1ad4ae2140bce80815a334fdfcc8e41cd088518f0f2107a5d99ea7eb8e1774",
"sdk/machines/octatrack/elekloader/status.s": "5741056e9ba8ee0b395454ab6674891fe0de49f7bc903b8b8cd5b1dc83f81389",
"sdk/machines/octatrack/elekloader/status.s": "9385d6a425e37c948a22c9a947d02d7a737fad6d6f89656011f0a7ae7d12b6ae",
"sdk/machines/octatrack/elekloader/stock_dsp_worst.py": "3705e5b086a896fe48f30661eb52053b34ff4c51bf9e5bfc26a4d1bad6df3500",
"sdk/machines/octatrack/elekloader/stub.c": "e5c312a66d8c3909cb7657548d771c05c16f6f70046160aeb571b1a383b209db",
"sdk/machines/octatrack/elekloader/stub.s": "79261292ef92d45412de86d454206044cbe14d7e1e9921744e6d4f5487994911",
Expand Down
2 changes: 1 addition & 1 deletion src/engine/assets/octatrack-base-variants.json

Large diffs are not rendered by default.

Loading
Loading