Skip to content

Threshold Slices: chop a trim where the level rises - #1285

Open
jonathanwardle1992-beep wants to merge 10 commits into
repeat98:mainfrom
jonathanwardle1992-beep:module/threshold-slices
Open

jonathanwardle1992-beep wants to merge 10 commits into
repeat98:mainfrom
jonathanwardle1992-beep:module/threshold-slices

Conversation

@jonathanwardle1992-beep

Copy link
Copy Markdown
Contributor

Summary

  • CREATE THRESHOLD SLICES sits on the AED SLICE menu, under DELETE ALL SLICES and above CREATE SLICE GRID (above CREATE BEAT GRID when Beat Slicer is installed).
  • The base copies short absolute peaks into the module. The module finds rises through a threshold you set and proposes slice starts. The stock CREATE SLICES? / REPLACE SLICES? question still writes the markers. NO writes nothing. More than 64 slices is refused and the old slices stay.
  • This is a draft. It is not in the catalogue, so the site cannot install it yet. An older base shows NO READ and writes nothing. Slicing needs a base built from this branch.

Guides: docs/module-guides/system.md and sdk/machines/octatrack/SAMPLE_EDITOR.md now say a waveform edit reads peaks through the base, a few frames at a time, and proposes starts only.

Test plan

  • Host scan test: python -m unittest sdk.tests.test_threshold_slices (PASS)
  • Sample-editor host fixtures for the peak read, menu and publication (PASS)
  • Build a base from this branch and the module package (m68k-elf-gcc). This machine has no ColdFire gcc and no Docker, so that build was not run.
  • Load both over USB. Open AED, AMP (SLICE), YES, CREATE THRESHOLD SLICES. Confirm a loop chops on its hits, NO leaves the old slices, and OVER64 refuses a result past 64.
  • With Beat Slicer installed, confirm this row sits above CREATE BEAT GRID and both can be chosen.

Made with Cursor

The sample editor can hand a module short absolute peaks. The module finds the rises and proposes slice starts; the stock confirm still writes the markers.

Co-authored-by: Cursor <cursoragent@cursor.com>
@repeat98

repeat98 commented Nov 7, 2026

Copy link
Copy Markdown
Owner

Hi, thanks for Threshold Slices. It's a good idea, and it hooks in the right way: one row in ot_sample_editor_actions, the base's confirmation question, and no stock site of its own. It doesn't overlap Beat Slicer either, since CREATE BEAT GRID makes an even grid and never reads the audio.

Which one goes first. I'll review this one now and make it your first module. Track Mutes (#931) and Play Start (#947) are both waiting on base work (#1023, and hooks for the TRACK key and the trig keys), so please leave them as they are until that's in. I'll come back to them there.

Here's everything I need, in one go:

  1. Move the base part into its own pull request. The peak read changes the base every tester gets, and until now the sample-editor API has kept audio out of modules, so it needs its own Improvement: pull request that I review. That's also why the checks are red. module-contract fails because six base sources changed but the committed base wasn't rebuilt (octatrack-base.test.ts: "The committed Octatrack base is stale"), and module-pr-ok only reports that failure. Main is fine. Once the base files, their tests and the guide lines move out, this pull request is just the draft folder and its test.

  2. Build the read on top of Improvement: add SNAP alignment to Octatrack sample editor #1165. twwwy's SNAP pull request goes in first (it waits only on my run of its base update), and it reads the same stock pair readers. The two clash in three places:

    The base pull request also needs its own changelog/ file, the committed base rebuilt with npm run octatrack:base -- --stock OS.bin --beta --write (it needs the toolchain, the Docker image from Module/track mutes (MPC style)  #931), and that exact base tried on your unit over USB.

  3. The detector re-arms on every waveform cycle. armed comes back whenever a single sample falls below half the threshold (threshold.c:57), and real audio does that at every zero crossing. So a loud held note gets a new slice every GAP: a one-second note at 50 ms comes out as about 20 slices. I worked that out from the code; the host tests don't catch it because they only feed flat blocks. Please follow an envelope instead (the peak with a short release) and re-arm when the envelope drops. Add a host test with a real tone burst that expects one slice.

  4. "order": 40 in runtime.json. This table takes 50 to 90 for independent editor actions (HOOKS.md). Beat Slicer sits at 50, so any value in that range puts your row under CREATE BEAT GRID. Please update the README, the manifest overview and the description to match.

  5. LICENSE. The font comes from Beat Slicer under MIT, and MIT needs twwwy's copyright line kept. Please add "Copyright (c) 2026 twwwy and contributors" to the LICENSE for device_font.c.

  6. Rescanning. Every turn of an encoder starts both passes again, but the first pass (the peak) only depends on CH. Keeping the peak when THR or GAP changes makes adjusting much quicker on long samples.

  7. The USB package. This module runs only over USB, so the package is the module. Add a verify.py gate like Beat Slicer's and build a private package ("A private USB package of a draft" in ADD_A_MODULE.md). Then try install, self-test, Keep/Undo and removal on your unit with the base from point 2. Add the scan time for a long sample and the CPU load while the popup is open to TESTING.md.

The order is #1165, then your base pull request, then this one with main merged in. Keep it in sdk/drafts/threshold-slices/ until the package and the unit results are done.


Generated by Claude Code

…eak.

The menu row sits with the other editor actions, and LEVEL adds one slice at the marker.

Co-authored-by: Cursor <cursoragent@cursor.com>
@jonathanwardle1992-beep

Copy link
Copy Markdown
Contributor Author

The module side of the review is on this branch.

  • A held tone stays one slice. The host scan passes, including a rectified tone burst that expects the trim start plus one hit.
  • The row is order 60, so with Beat Slicer it sits under CREATE BEAT GRID.
  • The peak from the first pass is kept when the threshold or the gap changes. Changing the channel scans again.
  • LICENSE names the Beat Slicer font.
  • Private package a020a947 was loaded for 12 seconds on OCTATRACK 1.40C, base 671f0afd406290cb, then rolled back. The slot ran, refusals stayed 0, and the tick value stayed 0x54530000. The editor was not opened, so the menu, the LEVEL insert, scan time and CPU were not observed. After rollback the unit was normal, generation 2, the same base, and no slot running.

The base waveform read still waits for its own change after #1165. This pull request does not open that. Guides: nothing.

@repeat98

repeat98 commented Nov 8, 2026

Copy link
Copy Markdown
Owner

Thanks, that's points 3 to 7 done. The held-tone test is just what I hoped for.

One thing still keeps the checks red: the base edits are in this branch. sample_editor_board.c/.h, sample_editor_service.c/.h, sample_editor_menu.c and their three tests, modwerk_sample_editor.h, events.json, modwerk_events.h, HOOKS.md, SAMPLE_EDITOR.md and the new line in docs/module-guides/system.md all change here, so octatrack-base.test.ts still finds the committed base stale.

Please keep those changes on a branch of their own for the base pull request after #1165, and put main's versions back on this one (git checkout origin/main -- <those paths>). The host test only builds threshold.c, so the draft still passes without them, and the checks go green.

The menu, the LEVEL insert, the scan time and the CPU with the popup open belong to the run with the base read, so they can wait until then.

@repeat98

repeat98 commented Nov 8, 2026

Copy link
Copy Markdown
Owner

One more thing that changed today, so your next push doesn't trip on it: a pull request's checks now want every new module claimed on the agent board, and threshold-slices isn't claimed yet. Run npm run board -- login once, then npm run pr:ready claims it for you.

@jonathanwardle1992-beep

Copy link
Copy Markdown
Contributor Author

The waveform read is off this pull request. Those files match current main. The read stays local until its own change, after SNAP.

Pressing D on the waveform removes only the slice under the marker. That was not tried on the unit. The host scan and the 12-second USB try stay the earlier commit f964252.

The module is claimed on the agent board. Guides: nothing.

@jonathanwardle1992-beep

Copy link
Copy Markdown
Contributor Author

The author reports that pressing D on the open waveform removes only the slice under the marker, and the other slices stay. No package hash was recorded for that load. The 12-second try on 7 November still did not open the editor. Guides: nothing.

@repeat98 repeat98 mentioned this pull request Nov 9, 2026
2 of 5 tasks
@repeat98

repeat98 commented Nov 9, 2026

Copy link
Copy Markdown
Owner

Thanks, that's everything I asked for: the base files match main and the module is claimed.

One new thing since my review: LEVEL pressed on the waveform now adds a slice, and D removes the one under the marker. Please take both out of this pull request. They're separate jobs from threshold slicing, and LEVEL's press is stock's follow-playback toggle on those pages, so installing the module would take a stock gesture away. They also write the slice table directly instead of going through the editor's confirmation. If you want them, let's talk about it first; they'd be their own module.

Small one: TESTING.md has your local Windows path with your user name in it. Please replace it with the package's SHA-256. After that, this waits for #1165 and your base pull request, as planned.

@repeat98 repeat98 mentioned this pull request Nov 12, 2026
2 of 7 tasks

This branch has not been deployed

No deployments
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.

2 participants