Repository navigation
Effect polish - #112
Closed
spamatica wants to merge 99 commits into
Closed
Effect polish#112spamatica wants to merge 99 commits into
spamatica wants to merge 99 commits into
Conversation
Some refactoring to make it easier to follow the code.
Initial work on integrating a ducking compressor. It is not yet functioning but does compile The sources of SimpleCompressor, which is the base of the ducking compressor, are created by ChunkWare, see more information in the source files license text.
…le block BaseEffectModule gets ProcessMonoBlock/ProcessStereoBlock. The default implementations loop over the existing per-sample ProcessMono/ProcessStereo, so effects work unchanged until they override them. In-place processing is allowed. AudioCallback now runs the active effect over the whole block first and then does the mute/bypass timing and master crossfade per sample. Whether the effect runs is decided once per block; LED brightness is read once per block. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ProcessSample holds the per-sample staging logic shared by ProcessMono. When a caller passes exactly one model block (48 samples) with nothing staged, the model runs directly on the block and returns the result in the same call, removing the one block (about 1 ms) of latency and the staging copies. Other sizes fall back to the per-sample path. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The FIR keeps its own history, so an aligned block of up to 48 samples is convolved directly into the caller's buffer, skipping the staging copies and the one block of latency. Oversized or unaligned calls use the per-sample path. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The reverb stages were already block-capable but compiled with a block size of 1. ReverbController bufferSize is now 4 and the module calls it per block with the wet/dry mix applied per sample. Measured on hardware: 48 was slower than the per-sample original (scratch buffers outgrow the D-cache), 4 was the fastest of 48/16/8/4/2. The block size shifts the internal feedback delay by a few samples, so the sound differs very slightly from the original; level and decay match closely. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Feedback, low-pass frequency and mix gains are computed once per block and the mix uses float instead of double. Output matches the per-sample path to within 1 ulp of float rounding. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Parameter reads, reverb feedback/low-pass setup, overdrive drive setup and the drive-volume compensation are computed once per call instead of once per sample. Expression types are unchanged, so output is bit-identical to the original. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Tone::SetFreq and Svf::SetFreq (cosf/sqrtf and sinf/powf, for both channels) were recomputed every sample. They, the wow/flutter rates, imperfection probabilities, head-mode lookups and drive are now computed once per call. ProcessMono/ProcessStereo and the block overrides share ProcessSamples. Output is bit-identical to the original; measured CPU 63.8% -> 39.5%. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Mix gain and the dry-fallback check are computed once per block. The engine itself still runs one sample at a time (feedback network). Output is bit-identical to the per-sample path. The module is still disabled by default. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Uncomments the two Dattorro sources in the Makefile and the include/instance in loaded_effects.h, as described in Effect-Modules/Dattorro/README.md. NOTE: the Dattorro code is GPL-3.0-or-later. A firmware binary built with this commit must be distributed under GPLv3 (or not distributed). Revert this commit before sending anything upstream. Costs about 4% of SRAM. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
showCPU is turned on: the default effect screen now shows the audio callback's average CPU load as a fraction (0.412 = 41%). disableKnobs (default false) skips reading the knobs and applying them to the active effect, so parameters stay at their defaults and CPU readings are steady. Set it to true while measuring; knob noise otherwise triggers parameter updates. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…cessing work tests/host compiles the real effect modules on a PC against small libDaisy and CMSIS stubs and checks the block path against the per-sample path (Reverb, Dattorro, IR, NAM) or against the original implementation in git (SciFi, Tape Delay, CloudSeed). Run tests/host/run_tests.sh. HANDOFF_block_processing.md records what was built, the measured CPU results, the findings, things to know before building, and candidate next steps. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
libDaisy's Led::Init() never initialises the software-PWM phase (pwm_) and Led's constructor does nothing, so an Led created on the stack starts with leftover stack contents. Depending on the compiler and optimiser that can be huge or NaN, which keeps the LED permanently off (or on); the update does `pwm_ += rate; if (pwm_ > 1) pwm_ -= 1`, so a large value never comes back into range. InitLeds now zeroes the object before calling Init(). Verified on hardware with arm-none-eabi-gcc 13.3, where the LEDs did not work before. This is an upstream libDaisy bug; libDaisy is a submodule so the workaround lives in the project. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ParameterMetaData gets three trailing fields: unit (text appended to the value, e.g. " dB" or ":1"), decimals and showSign. They are exposed through GetParameterUnit/Decimals/ShowSign, copied for effect-chain children and passed to the menu's float value, so a parameter stored in real units can be shown as such instead of a bare number. No effect changes behaviour yet. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…artup The Compressor's parameters are now stored in real units and shown as such: Level -12..+12 dB (default 0), Ratio 1..20 (default 4:1), Thresh -60..0 dB (default -20), Attack 1..100 ms (default 10, knob log), Release 10..1000 ms (default 200, knob log). Init() now applies every parameter. ParameterChanged() only fires on a change and first-boot storage equals the metadata defaults, so previously the DaisySP compressor ran on its own built-in settings while the menu showed 0.5 everywhere (which would have meant a 5 s attack and release). Values are clamped in case old settings (0..1) are loaded. Gain at default: +3.6 dB on a guitar-like signal, +2.1 dB on sines at -12 dBFS peak (was -3.0 dB). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The Compressor's stored parameters changed meaning (0..1 -> real units). The layout hash only covers parameter counts and types, so the version is bumped to force a one-time restore of factory defaults, which also picks up the new Level defaults. Wipes all saved settings and presets on first boot. The header comment now says to bump it for this kind of change too. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…'s Level range Crusher (was 1.0), Dual Echo (was 0.4) and Overdrive (was 0.3) now default their Level to 0.5 like the other effects. Overdrive's Level range maximum goes from 0.20 to 0.36 so the default maps to 0.185 and the effect measures +3.0 dB at -12 dBFS peak (was -1.9 dB on a guitar-like signal). Crusher and Dual Echo gains at default have not been measured yet. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The normalizeVolume factors are 2.38 (Hard Clip), 1.11 (Soft Clip), 1.10 (Fuzz), 0.87 (Tube), 0.79 (Multi Stage) and 2.38 (Diode Clip), so every type gives +2.9..+3.1 dB RMS at default settings for a -12 dBFS peak sine (was -1.0..+3.3 dB, with the default Hard Clip at +0.5 dB). Calibrated by measurement only; not yet checked by ear. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
outputGain is now BE-100 1.70, JCM800 1.08, Ampeg 0.85, Mesa 1.06, 1959BJA 1.50 (was 0.6, 1.1, 1.0, 0.5, 1.0, tuned by ear). Every model measures +3.0 dB (mean of a 110 Hz and a 330 Hz guitar-like note at -12 dBFS peak, IR cab Off); before, they ranged from -6.1 to +4.4 dB. Calibrated by measurement only; the gain depends strongly on input level, so check the real input level against the -12 dBFS reference. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
tests/host/run_level_tests.sh measures each effect's gain at default parameters on the PC (Distortion, NAM models, Overdrive, Compressor so far) against the 0..+6 dB / +3 dB rule, using sine and guitar-like signals at three input levels. HANDOFF_level_calibration.md records the rule, method, results, findings and next steps. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…SRAM) ProcessMono/ProcessStereo call the shared ProcessSamples routine with n = 1, which made GCC (-Ofast, interprocedural constant propagation) emit a second, specialised copy (`[clone .constprop.0]`) of each: 4.8 KB for SciFi and 1.2 KB for Tape Delay. Only the rarely used per-sample path (effect chains, fallback) called the clones; the block path that the audio callback uses runs the generic routine. Marking both routines noclone removes the clones: SRAM 456,960 -> 450,944 bytes (92.97% -> 91.74%). Output is unchanged (still bit-identical to the original in the host tests). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Adds the measured memory map (SRAM is almost all code; SDRAM, RAM_D2 and DTCM contents), why creating effects dynamically would not relieve SRAM, the GCC constprop-clone finding and the noclone fix, and ideas for reducing SRAM further. Updates the SRAM figure to 91.7%. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ault levels to a -37 dBFS reference Display: I/O peak readout in dB on the default effect screen (integer formatting, no float printf on target). Levels: Distortion and Overdrive about +6 dB, NAM about +9 dB (Level default 0.3), Compressor +3 dB (displayed Level offset by 7.5 dB). Level tests now use -49/-37/-25/-12 dBFS inputs with -37 as the reference. Settings format version 14. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… on the default screen Global Settings: runtime-only "Lock Knobs" checkbox (disableKnobs is no longer a compile-time constant; not saved). Default effect screen: CPU readout as a whole percentage in the small font, the "..." placeholder removed, thin line above the readouts. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Show Debug (Global Settings): draws the CPU percentage and the averaged input/output peak level (dB) on the default effect screen. The effect gets the flag from the main loop (SetShowDebug) instead of compile-time constants. The old text-page display takeover that useDebugDisplay used to trigger is now behind the compile-time constant useDebugTextScreen (default off). Both Show Debug and Lock Knobs are now fields of Settings (globalShowDebug, globalLockKnobs, default off) edited directly by their menu checkboxes, so they persist across reboots; the useDebugDisplay and disableKnobs globals are removed. SETTINGS_FILE_FORMAT_VERSION 14 -> 15 (the Settings layout changed; the first boot restores factory defaults). Lock Knobs no longer stops the knobs being sampled, only being applied (and clears their pending-change flags). A saved lock can be active from boot, and the knob cache is only initialised by sampling, so unlocking would otherwise apply uninitialised values to the effect's parameters. Hand-off notes updated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Init() called UpdateMix() before ResetInternalState() had set m_smoothedMix, and the member was not initialised in the constructor, so the wet/dry balance came from an uninitialised value: dry-only with zero memory, silence with NaN bits. ParameterChanged never fires for defaults, so it stayed that way until Mix was touched. The balance was also only recomputed on a Mix change, from the still-trailing smoothed value, so a one-step change ended up at the previous mix. The smoothed values are now initialised in the constructor, Init() resets them from the parameters before deriving the balance, and UpdateMix() runs every sample after the smoothing. The ParameterChanged override only handled Mix, so it is removed. Adds tests/host/test_tape_delay_defaults.cpp (startup state independent of memory contents, startup equals touched-to-default, a one-step Mix change reaches its target; all fail on the old code). The equivalence step in run_tests.sh mirrors the same fix into its copy of the original so it keeps checking only that the refactor changed nothing. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
These effects only configured parts of their state from ParameterChanged(), which never fires for defaults, so they started with their built-in settings while the menu showed the defaults. Spectral Delay: the per-bin delay and feedback tables (Time, Feedback and both modes) started at 100 samples / no feedback. Drum: Timbre, Tone, Decay, MIDI Voice and Beats were not applied, so the voices kept DaisySP's settings. PluckEcho: String Decay was not applied. Init() now applies them once the effect's state exists. Found by the startup-state audit. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
update_models.sh asks (when run by hand in a terminal; --calibrate and --no-calibrate skip the question) whether to calibrate: it measures every model on the host (tests/host/calibrate_nam.sh, calibrate_nam.cpp: the guitar-like test signal at the reference input level, default settings, IR cab Off), sets kOutputGain in each model file so all models give the same level (default +12 dB), and measures again to check. The Makefile and the test scripts run it with --no-calibrate. The NAM level test now expects +12 dB. nam_to_cpp_array.py: fix a line that lost its closing quote (syntax error) and write kOutputGain = 1.0f into new model files. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Output gains from update_models.sh --calibrate (guitar-like test signal at the reference input level, default settings, IR cab Off): Ampeg 1.6560, BE-100 0.4756, JCM800 0.4929, 1959BJA 0.6122, Mesa 0.3682. The level test measures +12.00 dB for all five. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
CHANGELOG.md: the Reverb Delay memory fix, block path and coexistence with Delay, and the NAM level calibration (the models are about 3 dB louder). PERFORMANCE_AND_MEMORY.md section 9: the measured CPU figures and what they mean for chains. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The Delay Time parameter covered 50-4000 ms with a default of 1828 ms. It now covers 50-1500 ms (the delay buffers are unchanged) and defaults to 400 ms. Saved settings store the knob position, so a saved value now plays a shorter time. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
GetBrightnessForLED advanced the LED oscillator, but the main loop calls it only twice per 48-sample block, so the LED ran about 24 times too slowly; the rate was also only set after the Delay Time knob had been moved. The LED phase is now advanced with the audio (per sample or per block, as in the Delay and Tape Delay modules) and the rate is set at start-up. The blink period is two delay times, as in the Delay module. New host test (period at 100, 400, 1000 and 1500 ms, block and per-sample path). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
SECOND_FOOTSWITCH_AND_LED.md: how the second footswitch and the left LED are handled, a table per kind of use for every effect, and a list of inconsistencies to look at later (a level LED that is never updated in eleven modules, CloudSeed's call-counting flash, taps that are ignored). Written from the source; not checked on hardware. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The Time parameter covers 100-2000 ms (it was 4000 ms; the menu step is still 5 ms) and a time saved with an older version is limited to 2 s. Tap tempo limits the interval to 2000 ms and a tap that is not followed by another within 2 s ends the series (it was 4 s). The delay lines are unchanged. The host test now checks delay times up to 2000 ms. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The second footswitch's tap tempo needed two taps and used the interval between them. It now needs three taps and takes the tempo from the interval between the last two (the first interval is usually off); every further tap of the series adjusts it again, and a tap more than 2 s after the previous one starts a new series. The series logic is in Util/tap_tempo.h with a host test; guitar_pedal.cpp uses it. The user manual and the footswitch review say three taps. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The left LED dimmed and brightened with the LFO, scaled by the depth, so it barely moved at low depth and never showed the tempo. It now blinks once per LFO cycle (once per beat after a tempo tap), locked to the LFO and on for about 27% of the cycle like the delay effects, whatever the depth. New host test (60 to 180 BPM, several depths, mono and stereo). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The menu writes its cached value of every parameter back into the effect on each main-loop pass. A parameter changed in the meantime by the effect (a footswitch handled in the audio callback, MIDI, a tempo tap) could be overwritten with the menu's older value, so the Crusher's Pitch Tracking and the Uranus Hold toggles worked only sometimes. The menu now remembers the raw value it last agreed on for each parameter and, if the effect's value differs, takes the effect's instead of overwriting it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… fix Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…, Exciter, Bass Dist, Octa Fuzz, Tape Sat Lighter alternatives to the Distortion and to a NAM model (4-5% CPU each on the pedal). They share a base class (MonoEffectModule) and the DSP pieces in Util/dist_dsp.h (filters, and soft and hard clippers with first-order antiderivative anti-aliasing instead of oversampling). Each effect's output level is matched at the reference input level (+6 dB; +3 dB for the Exciter and Tape Sat). Host tests: the block path equals the per-sample path, bounded output for random parameters, silence in gives silence out, behaviour checks and the default levels. New preset configs/distortions.config, entries in effects.json and effects-memory.json, manual and changelog entries, and HANDOVER_DISTORTION_FAMILY.md. The effect list grows by eight, so the MIDI Program Change numbers shift and saved settings reset once more. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ed Tremolo and Harmonic Tremolo Each has ProcessMonoBlock/ProcessStereoBlock with the same arithmetic as its per-sample path (bit-identical output, new host tests), reading the parameters and setting the filters once per block. Distortion also picks the clipping type and oversampling mode once per block, and its pre-filter cutoff (which follows the input level) is now updated every 8 samples instead of every sample, in both paths: the one change that is not bit-exact against the old code (the default level is unchanged). Measured on the pedal: Distortion Hard Clip 18% to 12% CPU, Overdrive about 4%. On the PC: Crusher 212 to 56 ns per sample, Chopper 65 to 41, Modulated Tremolo 95 to 64, Harmonic Tremolo 110 to 91. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The wet-only LED flash counted calls of the LED function (10,000 per half period), which is called once per audio block, so it stayed on for about 10 seconds and off for 10 seconds. A phase advanced with the audio now gives a sine-curve pulse with a period of half a second, starting bright when wet-only is switched on. New host test (period, range and curve, block and per-sample paths). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…e older effects Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… Preamp Lead level The top of the Drive knob of Preamp Clean, Screamer, Wavefolder and Bass Dist did not reach full saturation (35 dB of gain compression) before full scale. distdsp::topBoost multiplies the drive gain from the middle of the knob up to its end (x39, x5, x13, x10), so the maximum gets there at about -12 dBFS peak. At full Drive the Bass Dist now clips some of a 50 Hz tone; its clean-lows test runs at Drive 0.9. New defaults: Wavefolder Fold 30x, Screamer Drive 6.6, both recalibrated to +6 dB at the reference level. Preamp Lead was level-matched to Crunch at -37 dBFS, where Lead is already saturated and Crunch nearly clean, so on a guitar Lead was about 10 dB quieter. It is now matched to Crunch at -12 dBFS, where both saturate; the level test checks that and explains why. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Defaults are 8 bits, 8000 Hz and a 6000 Hz cutoff (were 32 bits, 48 kHz and 20 kHz, which left the sound unchanged). Level is now -24 to +6 dB around a level-matched default (was a linear 0 to 1, default -6 dB), calibrated to +6 dB like the other distortions, with a new default-level test. The level-test rule in tests/host/README.md said distortion aims for +3 dB; every distortion test uses +6 dB, so the text now says so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pre-filter, the post-filter and the oversampling low-pass were file-level globals, shared by every DistortionModule: two Distortions (in an effect chain, or a Dist Bench stage next to the Distortion on its own) stepped and reconfigured the same filters. They are members now. A single Distortion's output is bit-identical to before (24 configurations: six types, oversampling on and off, per-sample and block path). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…turated Dist Bench: up to four distortion stages in series, each Off or one of Preamp, Screamer, Muff Fuzz, Wavefolder, Exciter, Bass Dist, Octa Fuzz, Tape Sat, Chainsaw, Overdrive and Distortion (oversampling off). Every type gets the same Drive, Tone, Char and Level controls, where 50% is the effect's own default, so a stage at 50% is bit-identical to the effect on its own. Each active stage is trimmed by -6 dB and the bench adds +6 dB. Every stage holds an instance of every type; a type change crossfades over 0.1 s. Player's guide in DIST_BENCH.md. Chainsaw: an HM-2-style heavy metal distortion: soft-clip pre-gain, an asymmetric op-amp clip, diodes to ground, a dead band (back-to-back diodes), then resonant Low (87 Hz) and High (960 Hz and 1.28 kHz) peaks after the clipping. New distdsp::DeadZoneAdaa. Muff Fuzz and Chainsaw are saturated from about -45 dBFS, so matched at the -37 dBFS reference level they were 11 to 14 dB quieter than Crunch played hard. Like the Preamp's Lead they are now matched to Crunch at -12 dBFS; the level test shares one check for the three. tools/effects.py lists each source once (the bench uses the sources of the effects it runs). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deselects every effect, removes the chains and forbids the GPL effects again, to start a selection from scratch. It asks first and writes nothing until the selection is saved; an empty selection cannot be saved (the firmware's effect list would be empty). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every chain of two or more slots gets a "Switches" parameter after its On switches: Normal, or 1+2, 1+3, 2+3 (a chain of two only offers Normal and 1+2). Set to a pair, the right footswitch switches the lower slot and the left one the other, each LED shows its slot, and the chain itself stays on. Tap tempo and the left footswitch's own functions (the shift bank, footswitchTogglesSlots) are given up; the hold gestures (tuner, effect cycling, saving) still work and undo the slot their press switched. It is saved with the chain's presets. BaseEffectModule gets GetFootswitchSlots and a slot interface (count, on, switch, fade level) that EffectChain implements on its On parameters; the slot choice is in Util/chain_switches.h with a host test. The chain's parameter ids after Switches shift by one, and the settings format goes to 20 (an intermediate version had this as a global setting). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Switching the Delay on brought back the repeats of what was played the last time it was on: in a chain a switched-off slot is not processed, so its delay lines stayed frozen (on its own the same happened without Trails). SetEnabled(true) now clears the lines, except while the tail is still ringing (Trails). A whole clear of the four 8 s lines would stop the audio for tens of milliseconds, so they are zeroed a little per sample (about 0.12 s) from the stale end towards the new writes, with the delay's output and feedback muted meanwhile; what is played during the clearing is kept. New host test, which fails on the old code. Selecting another effect now switches the old one off (not when a preset of the same effect is loaded), so coming back to a delay also starts from silence (Tape Delay and Dual Echo too). Delay Time is 50-2000 ms (was 50-4000 ms), default 400 ms (was 2025 ms); Delay Mix defaults to 35% (was 50%). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Booster: Clean, Treble, Mid and Warm types. Spring Reverb: physical-modelling tank of 2 to 6 springs (4 by default) with dispersive allpass chains running at a third of the sample rate, additive Mix, Dwell, Decay, Tone, Drip, Tank, Output and Springs. About 30% cheaper than the previous 2-spring version at the default. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
All documents except README.md and CHANGELOG.md (and the per-effect READMEs beside their code), with effects_config.png. Relative links and the references in comments and tools updated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The layers are accumulated in tiles of four frames of the 48-sample block (after the A2-Lite kernel of squatch-dsp), so each weight loaded serves four frames. Same output (bit for bit without fast-math), same latency, 552 B more history; NAM CPU load 69% -> 65% on the pedal. NAM_A2_TILE4=0 selects the previous kernels. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Up to four phasers in one effect, each with its own Rate, Depth, Feedback, Stages, Center, Wave and Phase, in series or in parallel, mono or stereo. Each phaser makes up its level (default +2 dB on a guitar-like signal) and corrects for its feedback; switching a phaser, the routing, Stereo or the number of stages fades without clicks. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Moved all effect documentation into docs/EFFECTS.md
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.
Merge back all changes from fix branches