Skip to content

Octatrack: SYNTIZ track machine (SAW, PULSE, ENS, TABLE, MORPH, CHOIR), draft - #1028

Merged
repeat98 merged 11 commits into
repeat98:mainfrom
stigmagit:module/ot-wave
Oct 29, 2026
Merged

repeat98 merged 11 commits into
repeat98:mainfrom
stigmagit:module/ot-wave

Conversation

@stigmagit

@stigmagit stigmagit commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Octatrack: SYNTIZ track machine (SAW, PULSE, ENS, TABLE, MORPH, CHOIR), draft

A new track machine for the Octatrack, kept under sdk/drafts/syntiz/ until it is qualified. Choose SYNTIZ in the
machine chooser; a double tap of the track key opens its model list (001 SAW to 006 CHOIR), as Analog BD does
for 808/909, and LEFT goes back to the machine column. The track's own filter, AMP, LFOs and effects follow it,
as for a sample.

Called WAVE until 29 October 2026, renamed after Zac's and the owner's notes: Octabam already has an Octatrack
synth called WAVE. The Part signature WV stays, so projects saved with it still load; the sound is unchanged.

  • SAW: a band-limited saw with an inner detuned pair (DET, UNI) and an outer pair at twice the detune (WIDE).
  • PULSE: a pulse with width (PW), a triangle width sweep (PWM depth, PWS speed) and a detuned pair.
  • ENS: up to four notes of one shape (saw, square, narrow pulse: SHAP) and a chorus (CHOR).
  • TABLE: one of 32 single-cycle tables (512 points, 12 bits, read raw for their grain), a crossfade toward the
    next (MORF) that can sweep by itself (MSWP), and hard sync (SYNC).
  • MORPH: two of those tables mixed (WAV1, MIX, WAV2), the second up to two octaves higher (WID), each with its
    own resolution from 12 bits to 1 (BIT1, BIT2); changing a table crossfades over TIME.
  • CHOIR: ENS with one of the tables for the shape (TABL).
  • Every model: DRIV into an anti-aliased soft clip (first-order antiderivative anti-aliasing, Parker, Zavalishin
    and Le Bivic, DAFx 2016) with a treble emphasis, and RTRG; every model but MORPH: SUB (a square an octave down)
    and SUB2 (a sine two down), silent below 25 Hz.
  • PTCH keeps FLEX's scale and stock's pitch curve, so chromatic keys, scales, locks and LFOs work as on FLEX; OCT
    on SRC SETUP chooses the register (C3 at PTCH 0, OCT -3..+3). SRC SETUP A-D are FINE, OCT, DRIV and RTRG in every
    model. Chromatic and recorded notes therefore span two octaves, as on FLEX (a recorded note is a one-byte PTCH
    lock); the author kept this over a wider PTCH unit that would put the Scale Quantizer and LFO depths on PTCH out
    of step with FLEX.

Original code by the author (@stigmagit). The 32 tables are the author's own, computed from formulas by
tools/make_tables.py; none is taken or fitted from any instrument. No code, table or recording of any other
product, and no Elektron machine names.

How it hooks in

One struct modwerk_machine contributed to ot_machines (order 50), built as a C runtime package
(build.py SOURCES -o syntiz.mwrm --subscribe ot_machines:wave_machine:50): signature WV with the model in its
version byte (1-6), PROTECT and POOL, pages from stock's FLEX record copied at run time with PTCH kept, and its own
render writing the packer's native header and samples as Analog BD and FM Synth do (INTEGRATION.md cites both).
The model list is adapted from Analog BD's engine browser (MIT); LEFT goes through the base's choice_left as
VECTOR's pool choice does (MIT), re-entering stock's pool opener after the two instructions the base displaced,
as VECTOR does. It also sets the base's SETUP_ALL flag (in main since #1017), so SRC SETUP's encoder E edits its
fifth control; older bases ignore the flag. The C identifiers inside (wave_machine, Wave, wave_render) name
the oscillators and were left as they are.

The base parts, in this PR

As agreed on #1031 and on Discord, the base changes for this machine ride with it, in one base rebuild:

  • 996abd9d: WV 1-15 among the base's known PROTECT machines, folded in from the closed Improvement: Octatrack base keeps a WAVE track's bytes at boot #1031, its comment
    corrected (it said 1-3). The boot's battery restore no longer refuses a bank with SYNTIZ tracks before SYNTIZ
    reloads (beta finding 24).
  • 71f6c59a: room for eight contributed machines in the chooser, not just a fifth. You asked for one more
    row; the author would like the next machines (another is planned) not to need a base rebuild each. It is one
    number: ot_machines' room 8 in events.json (regenerated) and ROWS 13 in machine_registry.c, kept in
    step by a new test; the host registry test fills the eight rows and checks a ninth is not read. The chooser
    already scrolls and its counts and clamps follow the number of machines (Fix: Octatrack base, the double-tap TRACK machine list scrolls #922), so nothing else changes. Cost:
    4 bytes a row in two tables, 8 more words of event rows, 16 bytes of stack where the registry lists the
    machines (the render included). If you'd rather keep it to five, it is the same two numbers.
  • 96fa9aa5: the beta base regenerated, and the base-bound packages bound to its identity, their bytes unchanged
    (npm run octatrack:module-packages -- --check: identical).

What it needs before it leaves sdk/drafts/

  • The signature and PROTECT declared in the module's own recipe, with the test reading them there instead of the
    set it names today (your suggestion on Improvement: Octatrack base keeps a WAVE track's bytes at boot #1031). The draft has no recipe yet; it comes with the move out of drafts.
  • Hardware: the frame guard's CPU reading in a busy pattern (npm run device -- guard, a development base), the
    level against a FLEX sample, LEFT on this source's build (da5f1e78; the unit ran 7517cd6b, before LEFT),
    MKI.
  • The inventory lists the module by its id, syntiz: build.py titles a C runtime package by its output file's
    name.

How it was checked

  • Host (TESTING.md): 5,376 extreme renders over the six models under UBSan/ASan with no report; levels, DC,
    aliasing; pitch within 1.5 cents of stock's curve for PTCH, FINE and OCT; every knob byte reaching its control;
    MORPH at MIX 0 and 127 equal to TABLE playing WAV1 and WAV2, sample for sample; each model added left the
    earlier models' renders byte-identical. After the rename the host checks pass again.
  • ColdFire instructions a 16-sample frame under qemu cfv4e (tools/count_cf.sh), defaults / heavy: SAW 1,931 /
    4,044, PULSE 2,453 / 4,074, ENS 3,274 / 6,372, TABLE 2,027 / 3,155, MORPH 2,005 / 3,032, CHOIR 3,082 / 4,810.
    Counts, not time on the unit.
  • Emulator (ot_emu, private test bases of main + Fix: Octatrack base, SRC SETUP's encoder E and the double-tap window for module machines (SETUP_ALL, LIST flags) #943 + WV known): install over emulated USB; the machine in
    the chooser; the six pages; the list of six; LEFT back to the machine column and RIGHT into the list again; C3
    at 130.86 Hz, FINE and OCT; sequenced notes for every model.
  • After the rename, emulator (test base f49116e4…, main + WV 1-15; package da5f1e78): SYNTIZ in the
    chooser, "MACHINE:SYNTIZ" over the model list, the SRC footer "SRC PULSE > SYNTIZ" whole (the first try,
    "SYNTIZ PULSE", cut the label), C3 at 130.86 Hz as before.
  • Beside the four other machines, emulator, this branch's base: POLY8, Analog BD, VECTOR, FM Synth and SYNTIZ
    installed together over emulated USB with no refusal; the machine list scrolls to SYNTIZ on the last row and YES
    assigns it. Base tests: sdk/tests/test_machine_events.py (10 tests, the eight-row registry test and the
    ROWS-room test among them) pass; npm run pr:ready Ready.
  • Hardware, the author's MKII, 28 October 2026, under the name WAVE: SAW, PULSE and ENS on a RAM-booted private
    test base beside FM Synth 0.1.2. Then the private test base b30d9b09 (main + Fix: Octatrack base, SRC SETUP's encoder E and the double-tap window for module machines (SETUP_ALL, LIST flags) #943 + WV 1-15) flashed by
    the author; the six models (7517cd6b) tried and accepted over USB beside FM Synth; reported by the author:
    they work and he likes the sound; a project saved with TABLE, MORPH and CHOIR tracks came back whole after a
    power cycle, the machine reloading from the card (npm run device -- missing: nothing).
  • Hardware, the author's second MKII, 29 October 2026, under the name SYNTIZ: Elektron's OS until then, the same
    private test base b30d9b09 flashed from the card; SYNTIZ (da5f1e78) and FM Synth kept over USB; reported by the
    author, playing it with a friend: it works very well; a project saved with SYNTIZ tracks came back after a power
    cycle (missing: nothing).

What the guides lacked or got wrong

Fixed in this PR, docs/module-guides/machines.md: how many machines the chooser takes (eight now, and where
that number lives), and that the parameter page's footer gives " > " 18 characters, measured
when "SYNTIZ PULSE" cut the label. Earlier gaps found on this machine went in with the Docs: PR #1027 (merged
29 October): a machine's own render, driving ot_emu --interactive, small ranges, and the loader README on a C
runtime package's id and title.

🤖 Generated with Claude Code

… draft

A track machine with six models in a list on a double tap of the track key; the
track's filter, AMP, LFOs and effects follow it. Original integer engine for the
ColdFire, 32 single-cycle tables of the author's own formulas, pages built from
stock's FLEX record at run time, its own render as Analog BD and FM Synth do.
Host, ColdFire counts, emulator and the author's MKII: sdk/drafts/wave/TESTING.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Zac-Kyoti

Copy link
Copy Markdown
Contributor

Hi Stigmagit! Just a friendly heads-up that Sam Banks (Octabam) uses the name "Wave" for one of his Octatrack synth mods. Thought you'd want to know. Cheers!

@repeat98

Copy link
Copy Markdown
Owner

Thanks, this is a lovely draft: the anti-aliased output stage, the 32 tables from your own formulas, and the render notes you wrote up in #1027 along the way.

Three things before it leaves sdk/drafts/:

  1. The name. As Zac said, Octabam already has an Octatrack synth called WAVE (a CHOMPI WAVE port on FX2), so two different "WAVE"s would be confusing. Please pick another name now, while it's only a draft: the folder, the WV signature if you like, and the title.
  2. The base parts ride with the module. Improvement: Octatrack base keeps a WAVE track's bytes at boot #1031 (WV in known[]) and the fifth ot_machines row are base changes for this machine, so they go in with WAVE's module PR, in one base rebuild. More on that on Improvement: Octatrack base keeps a WAVE track's bytes at boot #1031.
  3. A CPU reading on a unit (npm run device -- guard on a development base, in a busy pattern), and LEFT checked on this source's build (896d7f8d), before it's qualified.

None of these block keeping the draft here.

@stigmagit

Copy link
Copy Markdown
Contributor Author

Thanks Zac and Jannik! For the name, would WAVES or WAVZ be distinct enough from Octabam's WAVE, or would you rather have a clearly different one? I'd keep the WV signature either way, so saved projects still load.

Once it's settled I'll rename the folder and the title, fold #1031's commit and the fifth ot_machines row into this PR when it leaves drafts, fix the "WV 1-3" comment, and do the guard reading and LEFT on 896d7f8d.

@repeat98

Copy link
Copy Markdown
Owner

Thanks! I'd go for a clearly different name: WAVES or WAVZ would still read as the same machine in a search, a chooser or a forum post. Pick anything of your own that says what it does. Keeping the WV signature is fine, so saved projects still load.

Your plan for when it leaves draft sounds right: the rename, #1031's commit and the fifth ot_machines row folded in, and the "WV 1-3" comment. I'll close #1031 so nothing waits on it separately.

stigmagit and others added 2 commits October 29, 2026 11:24
The folder, the module id (syntiz.mwrm), the chooser label, the model
list's title and the SRC footer, which now reads "SRC <model> > SYNTIZ"
so the label is not cut. The Part signature WV and the sound are
unchanged; TESTING.md keeps its dated records under the old name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@stigmagit stigmagit changed the title Octatrack: WAVE track machine (SAW, PULSE, ENS, TABLE, MORPH, CHOIR), draft Octatrack: SYNTIZ track machine (SAW, PULSE, ENS, TABLE, MORPH, CHOIR), draft Oct 29, 2026
@stigmagit

Copy link
Copy Markdown
Contributor Author

Renamed to SYNTIZ: the folder (sdk/drafts/syntiz), the module id and the title. WV is kept, so saved projects still load. Thanks both!

stigmagit and others added 8 commits October 29, 2026 12:39
The boot's battery restore keeps a SYNTIZ track's twelve bytes while the
module is not yet reinstalled (beta finding 24). Folded in from the
closed repeat98#1031, with its comment corrected (it said WV 1-3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
POLY8, Analog BD, VECTOR and FM Synth filled the four ot_machines rows,
so SYNTIZ could not install beside them. The table's room goes to 8
(events.json, regenerated) and the registry's ROWS to 13; a test keeps
the two in step, and the host registry test fills all eight rows and
checks a ninth is not read. machines.md says so, and notes the SRC
footer's 18 characters measured on SYNTIZ.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hine rows (npm run octatrack:base -- --beta --write, octatrack:module-packages)

The base-bound packages are bound to the new base identity; their bytes
are unchanged (octatrack:module-packages -- --check: identical).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…M Synth

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r USB, power cycle)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ated base files from main, regenerated next)
…wn and eight machine rows (npm run octatrack:base -- --beta --write, octatrack:module-packages)

The base-bound packages are bound to the new base identity; their bytes
are unchanged (octatrack:module-packages -- --check: identical).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@repeat98
repeat98 merged commit aead46e into repeat98:main Oct 29, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants