Repository navigation
Conversation
…current base The module work of synth-2.20 brought onto main 1bbc8b4, with upstream/ re-vendored from the author's release 2.21 (v2.21 = 9e4d34a), byte for byte, including the two new panel_transaction.inc.s files. As agreed with Jannik on repeat98#555, the bundled quantizer's seven hooks on MIDI and sample tracks (qz_mknob, qz_mplock, qz_mkey, qz_mnote, qz_mprev, qz_atrig, qz_heldmark) and the LFO SETUP names hook po_lfdname (0x4003bff2, which meets the base's 0x4003bff4) are left out of the module; FM tracks keep their quantizing in the engine. SEQUENCER adds SCALE, ROOT and GLIDE only. 2.21's own manifest now links the PLAYBACK page in DRAM (repeat98#895), so the wrapper's page unit and resolver detour are gone. The wrapper counts the bundled quantizer as present, so the author's panel transaction is assembled in both units, and exports sy_state from the poly unit for it (poly.s exports it only with SY DRUM in the remix). Machine record: LIST (the author's 2.18 double tap to the machine list), the five row clamps and fm_chooser_col replaced by the base's ot_machines sites; stock guards, import record and source pins regenerated.
README, TESTING, release notes and changelog for the author's 2.21: the chord and first-chord fixes, the eight hooks left out (repeat98#555), SEQUENCER with SCALE, ROOT and GLIDE, LFO SETUP's FLEX names (repeat98#589), the machine record's flags. The six captures retaken from the TEST5 image are byte-identical; ot-track-rows.png is gone. hardwareStatus untested: the TEST4 report was for the 2.20 cut. The SEQUENCER row count's pea is built from its opcode and count.
…; captures re-bound to the source
…ames the 2.21 engine
…500 per semitone)
…ntizer source, sy_state exported by poly.s); rows stay SCALE ROOT GLIDE
…ons describe the install beside it and pin be2810f
…entical) and re-bound; TESTING records the build beside Scale Quantizer
… on an FM SYNTH track whose FOLLOW is OFF (po_start stores T_SCALE = 0 for a track with the AUDIO SCALE OFF bit); limitation text: a project's AUDIO_SCALE_OFF now covers FM SYNTH tracks too
…entical) and re-bound; TESTING records TEST7 / TEST2 and the FOLLOW OFF fix
…hared_supply rule is merged (owner, repeat98#555, 30 October); the author's MKI report of TEST7 and of the pair's TEST2 (30 October 2026), hardwareStatus reported without a qualification object; release notes carry the marked compatibility note; captures re-bound to the source
…m the public v2.21 record; hardware limitations trimmed to what was stated
…ild again, listed under the ot_machines contribution's replaces (owner, repeat98#555, 30 October); the synth port's source pins follow the 3531b8e re-vendor Since the base's repeat98#1080 ot_machines owns the whole 8-byte site 0x4003bff2 and asks mw_page first, the owner's note of 30 October on repeat98#555 applies: a card build, which has no base, keeps the author's detour, and the package drops it for the table (build.py replaced(): a table detour that starts inside an owned site). So po_lfdname leaves _DROPPED, its guard moves from _READ_ONLY to the declared guards (stock-guards.json as the 2.20 cut had it; digests only), and machine-ports.json lists it under replaces. On an FM SYNTH track FUNC + LFO now names the PLAYBACK entries PTCH RATO INDX FINE FDBK DEC (repeat98#589); FLEX tracks keep PTCH STRT LEN RATE RTRG RTIM. The other seven dropped hooks stay out. machine-ports.json's sources: manifest.py re-pinned for this change, and the three vendored files the 3531b8e re-vendor changed without re-pinning (upstream/quantizer/manifest.py, quantizer.s, upstream/synth/poly.s), so test_ports_are_bound_to_the_sources_they_were_reviewed_against passes again; machine-recipes.json's five pins of the port file follow. modules:compat -- synth: the same 3 problems as before, none at 0x4003bff2.
…hook back in the card build (TEST8, pair TEST3); hardwareStatus untested again for this image, the TEST7 report kept TESTING: the owner's 30 October words on repeat98#555 quoted with the date; the image table TEST8 (alone, 483,780 B f726d4e5..., MAIN d2d250a6...) and TEST3 (with Scale Quantizer, 483,800 B e1b54ae1..., MAIN 779917c4...), TEST7 / TEST2 kept as superseded rows with the author's MKI report of 30 October as their record; the emulator evidence: FUNC + LFO on an FM SYNTH track lists PTCH RATO INDX FINE FDBK DEC (MKI and MKII, both images), a FLEX track PTCH STRT LEN RATE RTRG RTIM, the engine's index word T_I moves under LFO 1 on INDX, fm014's 46-screen walk equals TEST7's but the five PMTR screens, the author's own remix at 3531b8e still 3f5e00ee...; seven hooks left out, not eight. README, octamod.module.json (the LFO-names limitation removed; hardwareStatus untested for TEST8 with the TEST7 report in TESTING, as the TEST4 report was kept), release notes and the players' changelog (repeat98#589), the two release tests' pins. Media: the six captures from TEST8 are byte-identical to TEST7's; re-bound to MAIN d2d250a6... and to this source (capture.json sourceSha256).
…YNTH track's level is the engine's and the slot's GAIN attribute is ignored, so a sample loaded into the track's slot leaves the level unchanged; the synth port's poly.s pin and the recipes' pin of the port file follow; beside Scale Quantizer the module stays a declared conflict (the owner, repeat98#555, 31 October)
…) and the pair withdrawn (the owner, repeat98#555, 31 October: a module may not hook into another module's code, rows, tables or files); Scale Quantizer stays a declared conflict in one sentence; hardwareStatus untested for TEST9, the TEST7 report of 30 October kept
…EST9, upgrade file 296f9c0e, 483,768 B); the USB package's lagReason written for players (repeat98#1133) The author flashed OCTATRACK_MODWERK_FMSYNTH_TEST9.bin (sha256 296f9c0e..., MAIN cd7c72c8...) on his MKI on 1 November 2026 and reported its test sheet passing. The record: tests.hardwareStatus untested -> reported, a tests.gates line, tests.summary and the last limitation updated, a "Hardware report — 1 November 2026 (TEST9)" section in TESTING.md naming the sheet's checks and what was not recorded (play time, readings, MIDI gear; the optional FOLLOW OFF step not confirmed), README's Tests and measurements, and the two release tests' hardwareStatus expectation (sdk/tests/test_synth_release.py, src/catalog/synth-release.test.ts). The TEST7 report of 30 October 2026 stays as that image's record; TEST8 was not tested on a unit. No tests.qualification object: this cut measures neither cycles nor memory. The branch was rebased onto main 4ce910b after the pass; the card build's inputs did not change between 00ecaf5 and 4ce910b, so the image is unchanged and not rebuilt. octatrack-module-packages.json: the synth package's lagReason (lagsBehind 0.1.4-experimental) rewritten for players, as repeat98#1133 asks: the module page and the sync dialog show it.
…eased 2.22 line (bb784c4) whose files these are; the vendored READMEs are that commit's source.revision moves from v2.21 (9e4d34a) to bb784c413d86cc6ef2a895f7291af46cb851065f, the commit of the author's Octatrick 2.22 line (on v2.21) whose synth/ and quantizer/ files upstream/ carries. The manifest docstring, README, TESTING and the capture record name it, and the quantizer rows commit by its release id 8f6f564; the author's working commits of 29-31 October (990eff8, be2810f, 3531b8e, 2fba0e5) carry the same code and differed from the release line only in README wording. upstream/synth/README.md and upstream/quantizer/README.md are bb784c4's files, so every vendored file is that commit's byte for byte. The port's manifest.py pin and the recipes' pin of machine-ports.json follow the docstring; media/capture.json's sourceSha256 is re-bound to the native source. No code byte changes. tests.evidenceRevision stays 73490ef, the Modwerk commit the evidence files name.
|
Thanks Tim, and for the careful check table. Two answers:
Generated by Claude Code |
|
Tim, I owe you an answer here, and the ground has moved under this one, so both at once. The card builder is retired. Since today (#1451, #1453) the Octatrack pages build no card firmware any more, and the composer, the native comparison and the pair table are gone from the repository. Every Octatrack module now ships as a package for the Modwerk base, and nothing else. That decision is about the whole platform, not about FM Synth, but it hits this pull request hardest: 0.1.4 was cut as a card build with USB staying at 0.1.2, and there is no card build to publish it through now. What that means for the open items:
The way forward I'd suggest:
I know this is a lot of careful work to put on hold, and I'm sorry it took me ten days to say so. |
|
Thanks Jannik, no need to be sorry, and the card decision is fine with me. I'd like to go straight for 0.1.4 as a package for the base rather than a slim package first. Here is what I found and what I'm building. Your two questions
What I'd need from you
No rush on any of it. I'm building and testing locally first. |
|
Thanks Tim, going straight for 0.1.4 as a package is fine with me, and packing the lock rows to 2 bytes and taking lanes on first use is exactly what I hoped for. In order:
If posting needs stock's send routine as something the base exports, rather than a call into stock, say which and I'll add it to the same pull request. The late claim: not for now. All modules share one 768 KiB pool on the Octatrack. Every published module installed at once already comes to about 430 KiB, and FM at about 128 KiB plus 288 KiB on top would no longer fit beside them. A claim that fails halfway through a set is the worst moment to find out. Please go with the in-package pool and the message when it's full. Once players have it, we'll see how many lanes real projects use, and if 260 isn't enough we'll look for memory outside the pool. Euclid is mine to fix. Those 5 bytes at Scale Quantizer: yes. Send 0.1.5 without the two panel sites first; once it's in, drop FM's catalogue conflict with it. This pull request: yes, please close it and open a new one from current The shared scale (#1145): yes, send it now. Claim its hook index on the agent board first. |
FM Synth 0.1.4: the author's 2.21 engine; MIDI quantizing moves to Scale Quantizer
The FM Synth re-cut as its own PR off current main, as agreed on #555 on 31 October and confirmed there on 1 November ("Route 4 for now": the two modules stay declared as conflicting, FM Synth re-cut and Scale Quantizer split sent as their own PRs). It supersedes #555's content. The MIDI-track quantizing of the earlier 0.1.5 content is out, as agreed on 29 October: FM Synth keeps its bundled quantizer to what FM tracks need, and MIDI tracks, the trig-time snap of sample tracks and the chromatic keyboard's mark go to Scale Quantizer 0.1.4 (its own PR, next). Main has
synth0.1.2; this is0.1.2-experimental->0.1.4-experimental. I'd use0.1.5-experimentalfor FM Synth + SY DRUM, after your base PR for severalot_machinesrecords per module and the SETUP field.The branch is off current main
501d8a42, nineteen commits: the module folder, the machine adapters (machine-ports.json,machine-recipes.json,machine_ports.py: the dropped detours),sdk/catalog.json, the import record, the two FM release tests, a new SDK test (test_machine_events.py),scripts/module-source.test.mjs, the module changelog, the package lag, the record of the hardware pass below and, last, the upstream pin moved to the commit of my released 2.22 line. It is an author update of a module I am registered for.What is in
The author's Octatrick 2.21 engine and machine list (
upstream/synth,upstream/quantizer, byte for byte), on the 0.1.4 wrapper:0x40065c7c3 -> 6).machine-ports.json): the chooser commit'sadmit_track/assign/ui_tick, LIST, the base's ten chooser clamps andfm_chooser_colunderreplaces;ev_trig_mutedraised (Improvement: Octatrack base answers "is this trig muted?" for machines, and redraws FX SETUP when a module page comes on #912).bb784c4, 31 October; the fix section below).po_lfdname(0x4003bff2), the LFO SETUP names hook, is in the card build and listed under theot_machinescontribution'sreplaces, as you suggested on 30 October after Fix: Octatrack base, LFO SETUP's PMTR list names a machine track's own parameters #1080: a card build has no base and keeps the detour, and the USB package drops it for the table (there is no 0.1.4 package today). FUNC + LFO on an FM SYNTH track lists PTCH RATO INDX FINE FDBK DEC ([synth] Wrong LFO1&2 destination names #589); FLEX tracks keep PTCH STRT LEN RATE RTRG RTIM.machine-ports.json'ssourcesare re-pinned for it (and for the three vendored files the342c533re-vendor had changed), sotest_machine_eventspasses;modules:compat -- synthis unchanged (3 problems, none at0x4003bff2).What is out
qz_mknob,qz_mplock,qz_mkey,qz_mnote,qz_mprev,qz_atrig,qz_heldmark) are dropped from the module (manifest.py_DROPPED); the image keeps those spans stock. They are Scale Quantizer's.The FOLLOW OFF fix and the slot GAIN fix
upstream/is pinned to mybb784c413d86cc6ef2a895f7291af46cb851065f, released with Octatrick 2.22 (v2.22 =73686de, on v2.219e4d34a;bb784c4on342c533on4d25490on8f6f564, the commits of the release line; my working commits of 29-31 October,990eff8/be2810f/3531b8e/2fba0e5, carry the same code and differ from them only in README wording, and the vendored READMEs are the released ones): 2.21's engine, the quantizer source with the TRACK / FOLLOW rows that Scale Quantizer 0.1.4 carries,poly.sexportingsy_state, and two engine fixes.342c533(30 October): an FM SYNTH track whose per-track scale bit (#SEQUENCER_AUDIO_SCALE_OFF) is set now plays SCALE OFF's pitches; before,po_startread the scale mask without the track's bit, so only the ROOT transpose was dropped and the keys were still snapped (btst %d2,QZ_AUDIO_OFF_AT/beq/moveq #0,%d0afterjsr SCALE_AT, soT_SCALEis 0 for that track: 12 bytes, registers only, no project-format change).bb784c4(31 October): an FM SYNTH track's level is the engine's. The stock frame builder copies the assigned slot's GAIN attribute (the per-track word0x80001850 + 2t, the slot record's linear gain, 2048 = 0 dB) into halfword 29 of the track's DSP voice record every frame and the DSP applies it every frame; an FM SYNTH track is a FLEX-kind track with no sample, so a sample loaded into its slot (its.ot's GAIN, +12 dB after CLEAR SLOT) moved the FM level by that much on the sounding note, which I heard on my MKI.sy_render's sample-free path now writes 2048 into that halfword on every call for a chosen FM SYNTH track (registers only, no stock site; it runs after the writer and before the eDMA ship), so the slot's GAIN attribute is ignored on an FM SYNTH track; a sample track keeps the stock word, and a track that leaves FM SYNTH for FLEX takes its slot gain again at once. The pin is public with the Octatrick 2.22 push of octatrick-modules, which precedes this PR.sdk/imports/synth-9e4d34a.jsonstill records thev2.21files; five vendored files differ from that record (upstream/quantizer/README.md,manifest.py,quantizer.s,upstream/synth/README.md,poly.s), sotest_source_identities_and_complete_noticesfails until the import record is refreshed atbb784c4.Compatibility
compatibility.conflictsnames Analog BD and Scale Quantizer, as on main and as agreed on #555 (31 October, 1 November): FM Synth bundles its own copy of the quantizer, both modules would patch the same sites, and a module may not hook into another module's code, rows, tables or files. The marked note is inrelease-notes.jsonandsrc/community/module-changelogs/synth.json. Beside POLY8 this version still does not build (POLY8's composition record covers 0.1.2's chooser sites, #941).The USB package stays 0.1.2 with a declared lag (
lagsBehind: 0.1.4-experimentalinoctatrack-module-packages.json), itslagReasonnow written for players as #1133 asks ("Over USB this installs 0.1.2-experimental: 0.1.4's engine needs more memory than a USB package can be given today, so 0.1.4 comes as a card build; USB installs 0.1.2, without 0.1.4's step and scene locks, chord and envelope fixes and level change (#777)"). The engine's four DRAM regions (2 MiB step-lock work table, 32 KiB scene table, 2.5 KiB + 256 KiB migration buffers) and the units' generated includes are refused in a runtime package. The slim USB package you allowed on #777 (0.1.2 plus theev_trig_mutedask and the stock LFO 3 depth read) is not in this PR; it comes separately.Evidence
Images from the native exporter (
scripts/export-composition-proofs.py --vendored-sdk --static-stock --modules synth), rebuilt byte-identical at the documentation commits:00ecaf52; tested on my MKI, below)296f9c0e79086445419a47e167d706c0346c2f6e40f8fd12d314affd7fe02deccd7c72c82229ffa1f4089cb11337cea30563ec3a83fea0094bce1d265fb7f9d0po_lfdnameback; not tested on a unit)f726d4e540ba7a7e138be99fef91a957123dbf6881a46a589fb09d1f3aeb99add2d250a66ccadba18defb7b72f7c7981fc1aacbbd9f6e535c96ea4ce5853b142po_lfdnamedropped; tested on my MKI on 30 October)26ace38846b8c806324fe06559c74f8ca2f5a8ea49d46632879d5210b1885f94265308da8e8e62a9daa7538b6f886198170578005737cd96cd3b16e06f586589TEST8 is TEST7 plus the hook: the MAIN OS differs in 6 bytes, all inside the 8-byte site, and the runtime is byte-identical (the routine was linked all along). TEST9 is TEST8 plus the level fix: the branch head before the fix, rebased onto
00ecaf52, rebuilds TEST8 byte for byte, and TEST9's MAIN OS differs from TEST8's in 192 bytes of the stock section, every one a jump or reference target into the appended DRAM runtime moved by 40 or 42 bytes (the poly unit grew by the fix's 42 bytes), plus the runtime itself.Base: the branch was rebased from
00ecaf52ontoc4515136on 1 November (the image rebuilt there twice, byte-identical), then onto4ce910bband, the same day, onto501d8a42, after the hardware pass. Betweenc4515136and501d8a42main changed 34 files: 31 undersdk/analog-rytm-mkii/modules/_submissions/,sdk/machines/analog-rytm-mkii/README.mdand two underchangelog/; the diff over the card build's inputs (the module folder,sdk/octabam/{platform,tools,dsp,licenses},scripts/export-composition-proofs.py, the module adapters,scripts/octatrack-module-packages.py,build_core.py) is empty, so the TEST9 image is unchanged; it was nevertheless rebuilt once from the branch head (21fd2357) on 1 November through the same exporter: byte-identical (every output file). This is the check #1138 proposes, done by hand.Emulator (ot_emu, 29-31 October, builder and an independent verifier; the TEST9 image re-walked on 31 October): the level fix, in my own flow with my
guitar.wav/guitar.ot(+12 dB), on the MKI panel: T1 FM SYNTH playing trigs, T5 FLEX,guitar.wavloaded into slot 1 from T5's slot list through the browser: the slot record reads +12 dB and the per-track word 8153, halfword 29 of T1's DSP record reads 0 dB at every snapshot, and MAIN rms stays at -31.2 dBFS (TEST8 at the same point: -19.2), after STOP / PLAY and on a held MIDI note (-30.0 before and after); a 40 ms watch of every write to that halfword shows the stock writer's +12 dB followed by the engine's 0 dB on every frame; FM SYNTH on T2 with the sample into slot 1 unchanged and into slot 2 unchanged; T1 switched to FLEX takes the slot's +12 dB word again, switched back to FM SYNTH reads 0 dB and the old level. The carry-over on TEST9: the 46-screen walk, the LFO SETUP names (MKI and MKII), INDX under LFO 1, the chords, the first chord after power-on (MKI and MKII), the AUDIO_SCALE_OFF project, the SEQUENCER rows, a MIDI track's NOTE C 3 -> C#3, and a save and power-cycle of an FM SYNTH track with VOIC 4 and SCALE MAJOR, all as on TEST8; the six media captures byte-identical to the 2.21 cut's and re-bound to this cut's MAINcd7c72c8. Details and the gate table are in TESTING.md.Hardware
I flashed TEST9 (the image above, 483,768 B,
296f9c0e…) on my Octatrack MKI on 1 November 2026 and ran its test sheet: every item passed. The record is inoctamod.module.json(tests.hardwareStatusreported, atests.gatesline) and TESTING.md ("Hardware report — 1 November 2026"):guitar.wavwith its +12 dB.otloaded into slot 1 from track 5's slot list: the FM level unchanged at the load, on the next notes, after STOP / PLAY, and on a held note, a chromatic key and a MIDI note); FUNC + LFO on the FM SYNTH track lists PTCH RATO INDX FINE FDBK DEC then the AMP entries, a FLEX track still PTCH STRT LEN RATE RTRG RTIM, and INDX under LFO 1 moves the brightness; stock kept (a FLEX track playsguitar.wavat its +12 dB, track 1 switched to FLEX on slot 1 plays it at +12 dB too, back to FM SYNTH the FM level is what it was); FM SYNTH the sixth row of FUNC + SRC, a trig played without a sample; E PHRYGN, VOIC 4, chromatic mode: the same four keys together ten times and then fast one after the other give the same four notes; PROJECT 261028 power-cycled with PLAY pressed at once gives a chord on the first step; SEQUENCER shows the three stock rows then SCALE, ROOT and GLIDE only, no TRACK or FOLLOW row; with C MAJOR a MIDI track's NOTE steps C to C#.tests.qualificationis added, because the contract wants cycle and memory figures beside it and this cut measures neither.TEST7 (MAIN
265308da…, the same engine without the LFO-names hook and the level fix) passed the same way on my MKI on 30 October 2026; that report stays in TESTING.md as the record of that image. TEST8 was not tested on a unit.Checks and known CI items
Run on 1 November 2026 at the record commit, on main
4ce910bband again on501d8a42formodules:check,module:doctor,licenses:check, the changelog test andnpm run check(the same results), in this checkout without the owner's records, before and after the record commit, andmodules:check,module:doctor,licenses:checkand the changelog test once more at the branch head21fd2357(the same results):npm run modules:check -- --base 501d8a42synth: owner-approved update does not cover this module version(sdk/synth-build-approval.jsoncovers 0.1.2; the owner's record).npm run module:doctor -- synthconflicts), board claim; the USB package line reads the declared lag; ✗ module rules (the owner record above), packages (the committed packages lack 0.1.4), native comparison and package fingerprint (module:verify -- synth --os <OS>after the records), cross-compatibility (the 3 below).npm run modules:compat -- synth0x4002b654),fl_io_dispatch(0x4008485e) on the base's own job hook, POLY8's composition record (0x400786c8).npm run modules:pairsPOLY8 composition seam drift: synth detours 0x400786c8(the owner'scomposition.jsonrecord).npm run licenses:checknpm run sdk:imports:checknpm run sdk:checktest_module_compat(16 +test_repository_passes: the Euclid copy above; the same at the branch head before this commit),test_source_identities_and_complete_notices(the five vendored files past the publicv2.21import record, above),test_experimental_release_does_not_claim_hardware_or_timing(now at its version assertion: the approval record covers 0.1.2),test_changed_quantizer_layout_is_not_silently_supplied_by_fm(the POLY8 seam drift). The errors: thefm_runtimeadapter tests (native binutils and the pinned Elekloader checkout, not on this machine;fm_runtime.py's update for 0.1.4's sources is mine, separately).npx vitest run scripts/changelog.test.mjsnpx vitest run src/catalogmodule-qualification.test.tsandsynth-release.test.ts(two) stop at the owner record above;native-comparisons.test.tswantsmodule:verify -- synth --os <OS>for the new code.npx vitest run scripts/module-source.test.mjsmodule-build.jsonidentity is not this source tree's (the packages are not rebuilt for 0.1.4; the same before this commit).test_machine_eventssdk/tests/test_machine_events.pyat the branch head).npm run check -- --base 501d8a42(the full app suite) stops atmodules:check, the owner record above, as on #555;prepare,licenses:checkandmachines:checkpass before it. The stock scan over every file this branch authors finds no run of 16 or more stock bytes; the linked runtime holds only Modwerk's displaced instructions, copied from the developer's own OS at build time.How to test
.otcarries a GAIN other than 0 dB into slot 1 from track 5's slot list: the FM level does not change, not on the load and not after STOP / PLAY.The guides
Nothing lacking for this cut. The check I'd like on every PR is #1138 (say whether the card image's inputs changed since the tested build), which I did by hand above.
docs/module-guides/(machines, andsequencing.md), and TESTING.md lists what I did not test. An effect module holds one effect.Owner review, not automatic publication: this version names addresses 0.1.2 never used, and the owner records (
sdk/synth-build-approval.json, POLY8's composition signature) are yours.Validation commands and results: see "Checks and known CI items" above.
Related to #557, #710, #751, #589.