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
13 changes: 13 additions & 0 deletions REVIVAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,19 @@ recipes-improvements plan §1 carries the reasoning. Kernel: eight Catch2 scenar
`adsr.ipynb`; wrapper shrunk to Min glue, maxref rewritten (retiring its phantom `int`/`float`
methods), wrapper tests updated. Remaining: in-Max validation.

**15. The improvements wave (2026-08-05).** ✅ **Shipped in parallel** (four worktree agents,
serial integration): kernel side — the vco performance section (vibrato in cents with
per-note-re-armed onset delay, bend; formula-free at last), the vocoder sibilance path and
carrier-dry mix (silent-carrier contract intact at defaults), the harmonizer 16-slot preset
morph, and the delay-pair kernel (`taptools/delay.h`, Hermite taps, DC-blocked feedback,
`interp 0` bit-compat pinned against the Jamoma source). Max side — ladder/diode symbolic
`mode`/`solver` (the min-api enum finding is recorded in the plan §3), noise/verb `seed`
determinism, the sustain `length` setter, crossfade `mode` deprecated in docs, six maxrefs
rewritten, the vco/vocoder/harmony wrapper surfaces grown, and tap.delay~/tap.multitap~
rebuilt (multitap now stereo with per-tap pan; the 0.0-time-signal trap retired as a
documented breaking change). Still open in the plan: 5comb `notes`, the verb `clear`
DC-blocker one-liner, help-patcher refreshes, and the on-Mac validation passes.

Remaining (ongoing, now cross-repo — DSP lands in `tap/taptools`, then bump the submodule pin
here): lift the remaining simple inline-DSP objects' math into kernel headers opportunistically as
they're touched. Control/utility and Jitter objects never move — they are Max message-logic, not
Expand Down
5 changes: 4 additions & 1 deletion docs/tap.crossfade~.maxref.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
</attribute>

<attribute name="mode" get="1" set="1" type="int" size="1">
<description>Determines the algorithm to use. In most cases it is best to use the 512-point lookup table.</description>
<description>DEPRECATED — retained for legacy patcher compatibility only. In the
original Jamoma object this selected between a computed crossfade and a 512-point
lookup table; in the modern port both values compute the identical result, so the
attribute has no effect on the sound. Do not bother A/B-ing it.</description>
</attribute>

<attribute name="position" get="1" set="1" type="float" size="1">
Expand Down
74 changes: 65 additions & 9 deletions docs/tap.delay~.maxref.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,92 @@
<c74object name="tap.delay~" module="msp" category="TapTools, MSP Modifiers">

<digest>
Sample-accurate delay
Feedback delay line
</digest>

<description>
A simple audio delay.
The <o>tap.delay~</o> object is a feedback delay line. The input is delayed by a number
of milliseconds set via the right inlet (signal or float) or the <at>delay</at>
attribute, with a DC-blocked <at>feedback</at> path, an equal-power dry/wet
<at>mix</at> (default 100 — wet-only, matching the original object), and a choice of
fractional Hermite interpolation (<at>interp</at> 1, the default) or the legacy
bit-compatible integer-sample truncation (<at>interp</at> 0). Parameter changes ride
per-sample slews, so they are click-free. NOTE: a signal connected to the right inlet
always drives the delay time, including at 0.0 — unlike the pre-rebuild object, where
a 0.0 signal meant "use the attribute". The optional argument sets the size (ms) of
the delay buffer, which bounds the maximum delay. For multichannel signals, wrap the
object in an mc. operator.
</description>


<!--METADATA-->
<metadatalist>
<metadata name="author">74 Objects</metadata>
<metadata name="tag">TapTools</metadata>
<metadata name="tag">Audio</metadata>
<metadata name="tag">Time</metadata>
<metadata name="tag">Obsolete</metadata>
</metadatalist>


<!--ARGUMENTS-->
<objarglist>
<objarg name="buffersize" type="float" optional="1">
<description>An initial size of the sample buffer memory of the delay.</description>
<description>Size of the delay buffer in milliseconds (default 1000). This bounds the maximum delay time. Applied when the DSP chain starts.</description>
</objarg>
</objarglist>




<!--INLETS-->
<inletlist>
<inlet id="0" type="signal">
<digest>Audio input.</digest>
</inlet>
<inlet id="1" type="signal/float">
<digest>Delay time in milliseconds. A connected signal always wins, including at 0.0.</digest>
</inlet>
</inletlist>


<!--OUTLETS-->
<outletlist>
<outlet id="0" type="signal">
<digest>The delayed audio output.</digest>
</outlet>
</outletlist>


<!--MESSAGES-->
<methodlist>
<method name="clear">
<description>Clear the delay buffer and the feedback-path filter state.</description>
</method>
</methodlist>


<!--ATTRIBUTES-->
<attributelist>
<attribute name="delay" get="1" set="1" type="float" size="1">
<description>Delay time in milliseconds, slewed (click-free). Clamped to the buffer size. Ignored while a signal is connected to the right inlet. Default 0.</description>
</attribute>
<attribute name="feedback" get="1" set="1" type="float" size="1">
<description>Feedback amount (0..0.99). The feedback path is DC-blocked and capped so the loop always decays. Default 0.</description>
</attribute>
<attribute name="mix" get="1" set="1" type="float" size="1">
<description>Dry/wet mix in percent (0..100), equal-power. 0 is bitwise dry, 100 bitwise wet. Default 100, matching the old wet-only object.</description>
</attribute>
<attribute name="interp" get="1" set="1" type="int" size="1">
<description>Interpolation mode: 1 (default) reads fractional delays with a 4-point Hermite; 0 restores the legacy bit-compatible integer-sample truncation.</description>
</attribute>
</attributelist>


<!--SEEALSO-->
<seealsolist>
<seealso name="delay~"/>
<seealso name="tapin~"/>
<seealso name="tapout~"/>
<seealso name="tap.multitap~"/>
<seealso name="tap.comb~"/>
</seealsolist>


</c74object>
9 changes: 5 additions & 4 deletions docs/tap.diode~.maxref.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,12 @@
<attribute name="gain" get="1" set="1" type="float" size="1">
<description>Output gain in dB.</description>
</attribute>
<attribute name="solver" get="1" set="1" type="int" size="1">
<description>Nonlinear solver for the coupled diode equations: 0 = fast
(secant-linearized solve plus one corrective pass, the default), 1 = exact
<attribute name="solver" get="1" set="1" type="symbol" size="1">
<description>Nonlinear solver for the coupled diode equations: fast
(secant-linearized solve plus one corrective pass, the default) or exact
(re-linearization iterated to convergence). Audibly different only when drive and
resonance are both pushed hard.</description>
resonance are both pushed hard. Accepts the symbol or the index (fast = 0,
exact = 1); queries report the symbol.</description>
</attribute>
<attribute name="oversample" get="1" set="1" type="int" size="1">
<description>Internal oversampling factor (1, 2, or 4; default 2). Higher factors
Expand Down
35 changes: 35 additions & 0 deletions docs/tap.harmony~.maxref.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,27 @@
and the parameter slews.
</description>
</method>
<method name="store">
<arglist>
<arg name="slot" type="int" optional="0" id="0" />
</arglist>
<description>
Store the current parameters (intervals, levels, dry, glide, formant) in a
preset slot (1..16).
</description>
</method>
<method name="recall">
<arglist>
<arg name="slot" type="int" optional="0" id="0" />
<arg name="morph-time" type="float" optional="1" id="1" />
</arglist>
<description>
Morph all parameters to a stored preset (1..16). Every continuous parameter
glides to the stored values over the morph time in milliseconds (default: the
<at>interp</at> attribute); the formant flag snaps at recall start. A recalled
preset holds until the DSP chain restarts, which re-applies the attribute values.
</description>
</method>
</methodlist>


Expand Down Expand Up @@ -105,6 +126,20 @@
Default 1024.
</description>
</attribute>
<attribute name="interp" get="1" set="1" type="float" size="1">
<description>
Default preset-morph time in milliseconds used by the <m>recall</m> message
when no morph time is given. Default 500.
</description>
</attribute>
<attribute name="bypass" get="1" set="1" type="int" size="1">
<description>
Pass the input through unprocessed (no harmonizer latency). Default 0 (off).
</description>
</attribute>
<attribute name="mute" get="1" set="1" type="int" size="1">
<description>Silence the output. Default 0 (off).</description>
</attribute>
</attributelist>


Expand Down
16 changes: 9 additions & 7 deletions docs/tap.ladder~.maxref.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,16 @@
modeling transistor mismatch. 0 is symmetric (odd harmonics only); raising it adds
even-harmonic warmth. May produce slight signal-dependent DC when engaged.</description>
</attribute>
<attribute name="solver" get="1" set="1" type="int" size="1">
<description>Nonlinear feedback solver: 0 = fast (linear zero-delay prediction plus one
corrective saturation pass, the default), 1 = exact (Newton iteration to convergence).
Audibly different only when drive and resonance are both pushed hard.</description>
<attribute name="solver" get="1" set="1" type="symbol" size="1">
<description>Nonlinear feedback solver: fast (linear zero-delay prediction plus one
corrective saturation pass, the default) or exact (Newton iteration to convergence).
Audibly different only when drive and resonance are both pushed hard. Accepts the
symbol or the index (fast = 0, exact = 1); queries report the symbol.</description>
</attribute>
<attribute name="mode" get="1" set="1" type="int" size="1">
<description>Filter response via pole mixing: 0 = lp24, 1 = lp12, 2 = bp12,
3 = bp24, 4 = hp12, 5 = hp24.</description>
<attribute name="mode" get="1" set="1" type="symbol" size="1">
<description>Filter response via pole mixing: lp24, lp12, bp12, bp24, hp12, or hp24.
Accepts the symbol or the index (lp24 = 0, lp12 = 1, bp12 = 2, bp24 = 3, hp12 = 4,
hp24 = 5); queries report the symbol.</description>
</attribute>
<attribute name="oversample" get="1" set="1" type="int" size="1">
<description>Internal oversampling factor (1, 2, or 4; default 2). Higher factors
Expand Down
81 changes: 57 additions & 24 deletions docs/tap.multitap~.maxref.xml
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml-stylesheet href="./_c74_ref.xsl" type="text/xsl"?>

<c74object name="tap.multitap~" module="msp" category="TapTools, MSP Modifiers">

<digest>
A self-contained multitap delay
A self-contained stereo multitap delay
</digest>

<description>
The <o>tap.multitap~</o> object
is like a set of <o>tapin~</o> and <o>tapout~</o> objects, but all contained within one external for
improved efficiency.
The <o>tap.multitap~</o> object is like a set of <o>tapin~</o> and <o>tapout~</o>
objects contained within one external. The input is recorded into one shared buffer
and up to 99 taps are summed to a stereo output pair, each tap with its own delay time
(<at>delay</at>, ms), gain (<at>gain</at>, dB), and equal-power pan (<at>pan</at>,
-1..1). A center-panned tap (the default) feeds both outlets equally, so the old mono
output is simply the mix of the two. Taps read with fractional Hermite interpolation
(<at>interp</at> 1, the default) or the legacy bit-compatible integer-sample
truncation (<at>interp</at> 0), and every per-tap parameter is slewed (click-free).
Pure feedforward: no dry path, no feedback, no master gain — gain staging is the
patch's job. The optional argument sets the buffer size in ms.
</description>


<!--METADATA-->
<metadatalist>
<metadata name="author">74 Objects</metadata>
Expand All @@ -22,41 +29,67 @@
<metadata name="tag">Time</metadata>
</metadatalist>


<!--ARGUMENTS-->
<objarglist>
<objarg name="buffersize" type="float" optional="1">
<description>Sets the initial buffersize in ms. The default is 2000ms.</description>
<description>Size of the delay buffer in milliseconds (default 1000). This bounds the maximum delay time. Applied when the DSP chain starts.</description>
</objarg>
</objarglist>


<!--INLETS-->
<inletlist>
<inlet id="0" type="signal">
<digest>Audio input.</digest>
</inlet>
</inletlist>


<!--OUTLETS-->
<outletlist>
<outlet id="0" type="signal">
<digest>Summed delay taps, left.</digest>
</outlet>
<outlet id="1" type="signal">
<digest>Summed delay taps, right.</digest>
</outlet>
</outletlist>


<!--MESSAGES-->
<methodlist>
<method name="clear">
<description>Clear the delay buffer.</description>
</method>
</methodlist>


<!--ATTRIBUTES-->
<attributelist>
<attribute name="taps" get="1" set="1" type="int" size="1">
<description>
The number of taps in the multitap delay.
</description>
<description>The number of active delay taps (1..99). Default 1.</description>
</attribute>
<attribute name="delay" get="1" set="1" type="float" size="100">
<description>A list of delay times in milliseconds, one per tap, slewed by the kernel.</description>
</attribute>
<attribute name="delay" get="1" set="1" type="int" size="1">
<description>
Sets the delay time for one of the taps.
The first int specifies the tap, the second number specifies the delay time.
</description>
<attribute name="gain" get="1" set="1" type="float" size="100">
<description>A list of gains in dB, one per tap, slewed by the kernel. Default 0 dB.</description>
</attribute>
<attribute name="gain" get="1" set="1" type="int" size="1">
<description>
Sets the gain for one of the taps.
The first int specifies the tap, the second number specifies the gain.
</description>
<attribute name="pan" get="1" set="1" type="float" size="100">
<description>A list of equal-power pan positions (-1 hard left .. 1 hard right), one per tap, slewed by the kernel. A center-panned tap (0, the default) feeds both outlets equally; the endpoints are exact — a hard-panned tap is absent from the far outlet.</description>
</attribute>
<attribute name="interp" get="1" set="1" type="int" size="1">
<description>Interpolation mode for all taps: 1 (default) reads fractional delays with a 4-point Hermite; 0 restores the legacy bit-compatible integer-sample truncation.</description>
</attribute>
</attributelist>


<!--SEEALSO-->
<seealsolist>
<seealso name="tap.delay~"/>
<seealso name="tapin~"/>
<seealso name="tapout~"/>
</seealsolist>


</c74object>
Loading
Loading