Polish batch (verb~/sustain~/filecontainer/filter~) + max-test runtime harness#31
Merged
Conversation
Completes the REVIVAL.md polish items and stands up a runtime (in-Max) test harness. Full Catch suite now 24/24 green; all four new/changed externals compile. Polish items: - tap.verb~: added the deferred internal oversampling stage. New `oversampling` attribute (1/2/4/8, default 1 = true bypass, bit-identical to before). Factor >1 runs the reverb cores at host_sr*factor with an anti-imaging upsample and a 4-stage one-pole anti-aliasing downsample. Deviation: the legacy `downsample` ran the core at a LOWER rate with no antialiasing; inverted here to genuine oversampling per the roadmap (documented in-file). Default sound unchanged. - tap.sustain~: graduated from EXPERIMENTAL single-voice to a 5-voice round-robin/oldest-first bank (`voices` attr 1-5) with per-voice equal-power `rise` fade-in. Reference page digest corrected (was copy-pasted boilerplate). DSP feel still wants a Max audition. - tap.filecontainer: ported (was unported). No SQLite vendoring needed - like the original it drives Max's built-in `sqlite` object via the C API (object_new_typed CLASS_NOBOX + execstring). Schemas, BLOB import/export, all messages reproduced; temp-folder + moddate on std::filesystem (moddate restore best-effort). Docs/help restored from legacy. - tap.filter~: new unified multimode filter. TDF-II biquad on the RBJ cookbook coefficients (same set as tap.biquadcalc); `mode` attribute<symbol> (GCC-clean) selecting lowpass/highpass/bandpass(x2)/ notch/allpass/peaking/low+high-shelf; signal- or float-driven frequency; q/gain; per-vector recompute with per-sample smoothing. New maxref + test. Unit tests: added for verb~ (oversampling bypass bit-identical), filter~ (RBJ coefficients vs analytic refs), sustain~ (multi-voice + rise). Suite 21 -> 24 green. Runtime test harness (new): Cycling '74 max-test vendored as a submodule under runtime-tests/, with max-test-config.json, a make_maxtest.py patcher generator, two starter *.maxtest.maxpat examples (tap.prime control-rate, tap.radians~ audio-rate), and a README. This is the path to closing the "runtime validation in Max" gap (the Catch tests use a mock kernel; max-test loads real objects in Max). Needs a licensed Max install, so it's a local on-Mac gate, not CI. CLAUDE.md/REVIVAL.md updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012rTpfSz5htDrscQKG9uQib
The standalone "Max Runtime" was discontinued in Max 7; since then unlicensed Max runs (and edits) patchers indefinitely, with only saving disabled after the 30-day demo. The max-test runner only runs patchers, so no paid license is needed. Reframe the README + REVIVAL.md CI notes: a Max *install* is required (unlicensed is fine to run), and CI is feasible on a self-hosted macOS runner gated by Max's GUI/activation rather than by licensing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012rTpfSz5htDrscQKG9uQib
Audited the roadmap against the actual repo state. Several entries still read as "to-do" for work that's since shipped — corrected so the doc no longer undersells progress: - §3: tap.sustain~/vocoder~/spectra~/nr~ marked done (were "revive? yes"). - §5: tap.filter~ "open thread" resolved (it's built); fourpole~/filter~ repatriation row updated. - §7: tap.verb~ "not yet included limiter/oversampling" note reconciled (both done); tap.delay maxref-trim note marked done (batch 2). - §2: added a status banner (all of §2 is ported; filecontainer uses Max's native sqlite, not the pruned ttblue); fourpole~ "will re-cut" -> done. - Header date -> 2026-06-18. Added §9 "Remaining open items" consolidating everything genuinely still open: runtime validation in Max (incl. verifying the example max-test patchers), missing/provisional help patchers (sustain~, filter~, the spectral trio), the still-open resurrection candidates, tap.colorspace repatriation, the GCC-clean pass, the buffer.record~ optimization, and release engineering. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012rTpfSz5htDrscQKG9uQib
…ared bpatchers Two of §9's open items: the help patchers and the GCC-clean pass. GCC-clean pass (the whole tree now builds under Linux/GCC): - tap.crossfade~ / tap.pan~ stored shape/mode as attribute<enum class>, which GCC rejects (min-api's atom::operator== has no enum overload; clang accepts a templated conversion GCC won't). Switched to attribute<int> with named index constants — the help-patcher umenu-index path is preserved exactly. Also renamed the `number` message member (was shadowing the `number` type -> -Wchanges-meaning). Both now compile under GCC. - Added unit tests for both (testable for the first time): they guard the curve selection — equal-power cos/sin, linear, and pan's square-root — confirming the int-attribute refactor preserves behavior. Help patchers: - New help/tap.filter~.maxhelp and help/tap.sustain~.maxhelp, authored from the maxref + existing templates, with controls whose attribute/message names match the sources (filter: mode/frequency/q/gain/clear; sustain: voices/rise/fade/length/clear + bang capture). Valid JSON, patchline integrity checked. Authored headless — want a first open-in-Max check. Restored shared help assets (pre-existing prune gap): the help patchers reference shared bpatchers that were dropped when the package was pruned. Restored from legacy: - help/tap.badge.maxpat (referenced by 50+ help patchers) - help/tap.jit.ali.kernel-assist.maxpat Still missing: tap.help.dac~.maxpat (9 refs, no recoverable source — noted in REVIVAL.md §9). demosound.maxpat is a stock Max abstraction. REVIVAL.md §9 updated (help patchers + GCC pass marked done; shared-asset gap documented). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012rTpfSz5htDrscQKG9uQib
2f5711c to
ece5785
Compare
The 9 help patchers that reference tap.help.dac~.maxpat had a broken bpatcher (the asset was dropped in the prune). The repo history only preserved an older gain~/meter~ pass-through form — not the live.meter~/ dac~ version, so this is rebuilt to spec on the same 2-in/2-out interface the host patchers expect: - 2 signal inlets (L/R) and 2 pass-through outlets - a horizontal stereo live.meter~ (one per channel) - a local dac~ with a toggle for per-patcher audio on/off - text labels Valid JSON, patchline-integrity checked (0 dangling). All TapTools shared bpatchers now resolve (demosound.maxpat is a stock Max abstraction). Wants an open-in-Max verification. REVIVAL.md §9 updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012rTpfSz5htDrscQKG9uQib
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Knocks out the remaining REVIVAL.md polish items and stands up a runtime (in-Max) test harness. Every new/changed external compiles and the Catch suite is 24/24 green.
Polish items
tap.verb~— oversampling. Newoversamplingattribute (factors 1/2/4/8). Default 1 is a true bypass, bit-identical to before. Factor >1 runs the reverb cores athost_sr × factorwith an anti-imaging upsample and a 4-stage one-pole anti-aliasing downsample.tap.sustain~— multi-voice + rise. Graduates from EXPERIMENTAL single-voice to a 5-voice round-robin/oldest-first bank (voicesattr 1–5), each voice with its own capture buffer/loop/fade and a one-shot equal-powerrisefade-in. Reference-page digest corrected (was copy-pasted boilerplate).tap.filecontainer— ported (was unported). No SQLite vendoring needed: like the original it drives Max's built-insqliteobject via the C API (object_new_typed(CLASS_NOBOX, "sqlite", …)+execstring). Schemas, BLOB import/export, and all messages reproduced; temp-folder + file-moddate handling reimplemented onstd::filesystem(moddate restore is best-effort). Docs/help restored fromlegacy.tap.filter~— new unified multimode filter. Transposed-Direct-Form-II biquad on the RBJ Audio EQ Cookbook coefficients (same set astap.biquadcalc);modeis anattribute<symbol>(GCC-clean, notenum class) selecting lowpass/highpass/bandpass(×2)/notch/allpass/peaking/low-+high-shelf; signal- or float-drivenfrequency, plusq/gain; per-vector coefficient recompute with per-sample smoothing to avoid zipper noise. New maxref + unit test (16 assertions vs. analytic RBJ references).Unit tests
Added for
tap.verb~(1× bypass is bit-identical, resampler stays finite),tap.filter~(coefficients vs. analytic refs, DC/HF response, mode switch),tap.sustain~(multi-voice engagement + rise). Suite 21 → 24 green.tap.filecontaineris runtime-only (its DB needs a live Max).Runtime test harness (closes the "validate in Max" gap)
max-test(MIT) as a submodule underruntime-tests/, plusmax-test-config.json, amake_maxtest.pypatcher generator, two starter*.maxtest.maxpatexamples (tap.primecontrol-rate,tap.radians~audio-rate), and aREADME.md.test.assert/test.sample~/test.terminate, automatable over OSC with the bundled Ruby runner.Needs you, on a Mac (not blocking this PR)
.maxtest.maxpatpatchers in Max once to confirm the assert/terminate wiring (they were generated headless), then use them as the template for the rest.tap.filecontainerround-trip (especially the best-effort moddate restore).Verification
CLAUDE.md/REVIVAL.mdupdated (polish items done, runtime-test harness, licensing note).🤖 Generated with Claude Code
https://claude.ai/code/session_012rTpfSz5htDrscQKG9uQib
Generated by Claude Code