Sidechain Feedback VCA — User Guide
Buffer-domain feedback resynthesis driven by a controller Sound: pitch can steer a moving resonance, intensity shapes calibrated in-loop and post-loop VCAs, selectable excitation restores articulation when desired, and every iteration is re-levelled to a stable working peak.
What this does
Sidechain Feedback VCA v0.6.1 uses one selected Sound as a controller for an iterative resonant resynthesis process. It extracts a pitch representation and a relative intensity envelope, builds an excitation buffer from noise, the controller, or both, then repeatedly filters and feeds the whole buffer back into a new whole-buffer pass. A calibrated output VCA restores the requested audible sidechain depth after the iterative stage.
The v0.6 gain structure deliberately separates level stability from timbre. Every iteration is re-levelled to a fixed working peak of 0.6; Base_Feedback, Damping_Factor, Drive, filter bandwidth and iteration count therefore shape the spectrum and nonlinear character without allowing uncontrolled exponential growth from pass to pass.
Iterations is an outer computational axis: each pass processes the entire Sound. “Buffer-domain feedback resynthesis” is the accurate description.
Dry_Wet = 0, the direct controller waveform is absent from the rendered path. With Controller into the loop or Both, the controller itself excites the iterative process, so its attacks, rhythm and pitched content influence the wet signal even when the final dry mix is zero.
Quick start
- Select exactly one Sound in the Praat Objects window.
- Run
Sidechain_Feedback_VCA.praat. - Dialog 1 sets the preset, excitation source, resonance tracking, circuit controls, sidechain depth, dry/wet and harmonic-air exciter.
- Dialog 2 sets the spatial mode, multichannel policy, output-level policy, fades, random seed, visualization, playback and debug logging.
- Click Continue. The script analyses the controller, builds the excitation, runs the whole-buffer iterations, applies the audible sidechain VCA, spatializes, performs dry/wet and exciter processing, applies the output policy and leaves the final Sound selected.
Controller analysis
Pitch analysis
Multichannel controllers are converted to mono for pitch analysis. Praat's Pitch contour is interpolated and smoothed; unvoiced gaps are sample-and-held from the last usable value, while only a leading gap falls back to the file mean. The contour is then resampled to the audio sampling rate.
If no pitch is detected, the file-level mean falls back to 100 Hz. If the file is too short for the Pitch/Intensity analysis windows, pitch also falls back to 100 Hz and the intensity envelope is held at 1.
Fixed resonance versus pitch-contour tracking
Two resonance modes
Fixed (mean F0): the filter centre is the single value mean_Pitch + Frequency_Offset_Hz, with random centre drift between iterations when Analog_Instability > 0.
Follow pitch contour: the script constructs an audio-rate trajectory from F0(t) + Frequency_Offset_Hz and uses it to drive a heterodyne band-pass. The trajectory is clamped to a safe range below Nyquist. Per-iteration multiplicative drift is additionally capped when necessary so the tracked carrier plus filter width remains below Nyquist.
The tracking filter mixes the current buffer down with the integrated pitch phase, low-passes its in-phase and quadrature components, then mixes them back up. This makes the resonance centre move with the controller rather than using one FFT band for the whole file. Tracking costs an additional filter pass per iteration and is therefore slower than Fixed mode.
Intensity envelope
The dB-to-0…1 mapping is performed on the original low-rate Intensity-derived signal before resampling to audio rate. This avoids ringing caused by resampling very large dB discontinuities and then clipping the overshoot.
The mapping is intentionally relative to the loudest moment in the selected file. It follows dynamics within that file rather than absolute level between files. If the analysed maximum is below −150 dB, the envelope is held at 0.
Two calibrated sidechain paths
Input_Sensitivity no longer acts as a signed linear multiplier. It sets an accumulated in-loop modulation depth in dB; dividing that depth by the iteration count prevents the envelope from being exponentiated by repeated passes. Sidechain_depth_dB is a separate post-loop gain contour and is the main control for audible sidechain depth.
With positive depths, the loudest envelope value (1) is unity gain and quieter values are attenuated. Negative values invert that relationship: quiet portions are boosted relative to the loudest moments.
Excitation
The iterative loop must start from an explicit signal. v0.6.1 provides three choices:
| Excitation source | Behavior |
|---|---|
| Noise seed only | Creates Gaussian noise, filters it around the effective resonance region, scales it to peak 0.5, duplicates it to stereo, and uses it as the loop seed. This is the closest option to the earlier no-input aesthetic. |
| Controller into the loop | Copies the controller, converts non-stereo material to mono then stereo, scales it to peak 0.5, and uses it as the loop excitation. Attacks, rhythm and pitched content therefore enter the iterative circuit directly. |
| Both | Builds both paths. The noise is additionally shaped by 0.3 + 0.7*env(t), then noise and controller excitation are mixed 50/50 and the combined excitation is re-scaled to peak 0.5. |
In tracking mode the noise-seed band is derived from the actual offset/clamped resonance trajectory; in Fixed mode it is derived from the nominal resonance centre. The final seed edges are clipped to 20 Hz…Nyquist.
Buffer-iteration process
Per-iteration operation
Drive = 0 is a genuine linear bypass of the nonlinear stage. For every Drive value above 0, the arctan waveshaper is active; increasing Drive increases its curvature and lowers the asymptotic soft-clip ceiling.
Analog_Instability changes the band between whole-buffer passes, not continuously over playback time. In Fixed mode it jitters the centre in Hz and the bandwidth. In tracking mode the F0 trajectory itself moves over audio time, while each iteration can additionally multiply that trajectory by a small drift factor; unsafe upward drift is capped against Nyquist and reported.
Because each non-silent iteration is re-levelled to peak 0.6, the pre-relevel peak and RMS are diagnostic measures of how the loop would have grown or shrunk on that pass. The re-level is intentionally part of the v0.6 musical design.
Parameters & presets
Dialog 1 — Circuit & Resonance
| Parameter | Default | Meaning |
|---|---|---|
| Preset | Custom | Custom or one of four retuned v0.6 recipes. Named presets override only the circuit parameters listed in the preset table. |
| Excitation_Source | Both | Noise seed only, Controller into the loop, or Both. |
| Resonance_Tracking | Follow pitch contour | Fixed mean-F0 resonance or audio-rate F0-following heterodyne resonance. |
| Base_Feedback | 0.8 | Gain of the filtered return branch before per-pass re-levelling. |
| Input_Sensitivity | 0.5 | Sets accumulated in-loop sidechain depth: Input_Sensitivity × 30 dB. Negative values invert the envelope relationship. |
| Envelope_range_dB | 40 dB | Relative dB range below the file's loudest intensity mapped to 0…1. |
| Damping_Factor | 0.92 | Gain of the current unfiltered buffer in each pass. |
| Iterations | 24 | Number of whole-buffer passes. This is a computational/timbral depth, not elapsed feedback time. |
| Drive | 0.45 | 0 = linear bypass; values above 0 activate increasingly strong arctan soft saturation. Custom values outside 0…1 are rejected. |
| Frequency_Offset_Hz | 0 | Added to mean F0 in Fixed mode and to the F0 trajectory in tracking mode. |
| Bandwidth_Hz | 180 Hz | Nominal resonance width; per-pass width can drift with Analog Instability. |
| Analog_Instability | 0.05 | Amount of random pass-to-pass frequency/width drift. Custom negative values are rejected. |
| Sidechain_depth_dB | 24 dB | Audible post-loop VCA depth. Positive attenuates quieter envelope values; negative inverts the dynamics relationship. |
| Dry_Wet | 0.3 | 0 = generated/iteration path only; 1 = dry controller path only before any post-mix exciter and final output stage. |
| Exciter_position | After dry/wet mix | Run the harmonic-air exciter after the final mix or on the wet path only. |
| High_Freq_Add | 0.3 | Amount of RMS-matched synthetic harmonic air. Values ≤0 disable the exciter. |
Named presets
| Preset | Base | Sensitivity | Damping | Iterations | Bandwidth | Instability | Drive |
|---|---|---|---|---|---|---|---|
| Gentle Resonance | 0.50 | 0.30 | 0.90 | 18 | 260 Hz | 0.03 | 0.25 |
| Aggressive Feedback | 0.95 | 0.70 | 0.80 | 30 | 120 Hz | 0.08 | 0.70 |
| Deep Iteration | 0.75 | 0.40 | 0.95 | 60 | 300 Hz | 0.02 | 0.35 |
| Unstable Burst | 0.95 | 0.90 | 0.75 | 26 | 90 Hz | 0.18 | 0.85 |
Base_Feedback, Input_Sensitivity, Damping_Factor, Iterations, Bandwidth_Hz, Analog_Instability and Drive. They do not override excitation source, resonance-tracking mode, envelope range, frequency offset, sidechain depth, dry/wet, exciter controls, spatial/output settings or random seed.Dialog 2 — Spatial, Output & Debug
| Parameter | Default | Meaning |
|---|---|---|
| Spatial_Mode | Stereo Wide | Mono, Stereo Wide, Rotating, or Pseudo-Binaural (Delay/Filter). |
| Stereo_spread_percent | 1.2% | Detune percentage for Stereo Wide. Values above 95% are capped at 95% and reported. |
| Interaural_delay_ms | 0.68 ms | Right-channel delay in Pseudo-Binaural mode, rounded to integer samples with a minimum of one sample. |
| Multichannel_policy | Downmix to mono, then duplicate | Controls how a >2-channel controller is handled for the dry path; Refuse more than 2 channels aborts the run. |
| Output_mode | Match loudness (RMS target, peak-guarded) | Legacy staged peak normalization, final-only peak normalization, preserve level, or RMS matching with a peak guard. |
| Target_RMS_dBFS | −20 dBFS | RMS target used only by Output mode 4. |
| Output_Gain | 1.0 | Positive master gain applied after normalization/RMS matching and after edge fades. |
| Fade_ms | 15 ms | Half-cosine fade-in and fade-out. Values ≤0 disable fades; positive fades are capped at one third of the Sound duration. |
| Random_seed | 0 | Positive = reproducible random draws; 0 or below = unpredictable initialization. |
| Draw_visualization | On | Draws the measurement-based v0.6.1 diagnostic page. |
| Play_result | On | Plays the final selected Sound. |
| Debug | Off | Writes selected per-stage and per-iteration diagnostics to the Info window. |
Dry/wet mixing and harmonic-air exciter
Dry/wet
The wet result is mono only in Spatial Mode = Mono; every other spatial mode produces stereo. The dry controller is converted as needed to match that output channel count.
For controllers above two channels, Multichannel_policy controls the dry-path conversion. Use the first two channels extracts channels 1 and 2 for a stereo dry result; the default downsamples the dry controller to mono and duplicates it when stereo is required. Refuse more than 2 channels stops the script before processing.
Fade_ms ≤ 0, Output_Gain = 1, and a spatial/channel configuration that leaves the dry signal's channel layout unchanged.Harmonic-air exciter
The v0.6 exciter is a band-limited cubic waveshaper rather than the old ring-modulation whistle. It generates harmonically related high-frequency energy and RMS-matches that component to the signal before applying High_Freq_Add.
The exciter's high-pass reference uses the nominal resonance centre (mean F0 + offset), not the moving pitch contour. Low-passing to Nyquist/3 before cubing keeps the third-order products inside the available band.
Spatial modes
Four post-processing modes
Mono: converts the wet stereo loop to mono.
Stereo Wide: creates a detuned twin-resonance treatment around the nominal resonance centre.
Rotating: converts the wet path to mono, then pans that single signal at 0.2 Hz with a constant-power cosine/sine law.
Pseudo-Binaural (Delay/Filter): uses asymmetric filtering plus an integer-sample right-channel delay. It is not an HRTF renderer.
Stereo Wide
The detune percentage is capped at 95%. Effective centres are constrained below Nyquist and the filter edges are clipped to 20 Hz…Nyquist. This is a post-processing twin-resonance effect based on the nominal mean-F0 centre; it does not itself follow the time-varying tracking contour.
Rotating
Because both channels are derived from one mono wet source, cos²(theta) + sin²(theta) = 1 gives a true constant-power pan law. The phase uses time relative to the Sound's start, so changing a Praat object's absolute xmin does not change where the rotation begins.
Pseudo-Binaural (Delay/Filter)
The left channel is Hann-band-filtered approximately 50…3000 Hz, limited by Nyquist. The right channel is delayed by round(Interaural_delay_ms/1000 * samplingRate) samples (minimum one sample), then filtered approximately 200…6000 Hz, also limited by Nyquist. The Sound duration is preserved: zeros enter at the beginning of the delayed channel and the displaced tail is not extended beyond the existing time domain.
Output level, fades and reproducibility
Output modes
| Mode | Behavior |
|---|---|
| Normalize each stage to 0.95 (v0.3 legacy) | Peak-normalizes the wet render when non-silent; normalizes again after a wet-path exciter, the dry path before mixing, after dry/wet mixing, and after a post-mix exciter where those stages occur. This deliberately suppresses intermediate level differences. |
| Normalize only at the end | Leaves intermediate stages intact, then scales the pre-fade final render to peak 0.95 if non-silent. |
| Preserve rendered level | Does no peak or RMS normalization. The rendered level passes directly to fades and Output Gain. |
| Match loudness (RMS target, peak-guarded) | Scales the pre-fade render to Target_RMS_dBFS. If that produces a peak above 0.98, the Sound is instead peak-scaled to 0.98. This is the default mode. |
Output_Gain happens after the fades. Therefore the final measured RMS may differ slightly from Target_RMS_dBFS, and Output Gain can raise the final peak above the normalization/peak-guard value.Edge fades
Positive Fade_ms applies symmetric half-cosine fades at the beginning and end to avoid discontinuities from a steady-state iterative buffer. The effective fade is limited to at most one third of the Sound duration. Zero or negative values skip the fades.
Output object
- Name:
<source>_feedback_<PresetName>, where the internal names areCustom,Gentle,Aggressive,DeepIteration, orUnstableBurst. - Duration/time domain: preserved from the source.
- Sampling rate: preserved.
- Channels: Mono mode outputs one channel; every other spatial mode outputs stereo. Input multichannel count is not preserved.
- Final clipping check: the Info report warns if the measured sample peak exceeds 1.0 after fades and Output Gain.
Random seed
Randomness affects the noise excitation and iteration-domain spectral drift. A positive Random_seed initializes Praat predictably; the same input and settings then reproduce the random sequence. A value of 0 or below uses unpredictable initialization.
Visualization
The v0.6.1 figure is measurement-based; the former block diagram has been removed. It uses mono analysis copies for waveform/spectral measurements so stereo channel stacking does not distort the overlays.
- Controller waveform + sidechain envelope: the controller waveform is drawn on its own amplitude scale; the blue 0…1 sidechain envelope is overlaid with a separate control axis.
- Result waveform + RMS envelope: the result waveform is drawn on its own amplitude scale and the measured windowed RMS envelope is drawn above and below zero on that same amplitude scale. The label is literal RMS; no ×√2 conversion is used.
- Resonance trajectory: tracking mode plots the actual base trajectory after
F0 + offsetand Nyquist clamp, with the nominal bandwidth shaded. Fixed mode plots the constantmean F0 + offset. Per-iteration drift is not folded into this time-domain curve; it is shown in Panel 4. - Iteration convergence: pre-relevel loop peak and RMS are each normalized to their own run maxima; a small green trace shows the measured band-centre drift across iterations. This panel is diagnostic and its vertical axis is normalized, not Hz or linear amplitude.
- Input/output spectra: power density is averaged in 130 logarithmically spaced frequency bands and drawn on a shared dB/Hz range over a logarithmic frequency axis.
A summary strip reports the input, circuit, sidechain and output state. Do not compare the visual height of the controller and result waveforms as a gain measurement: those two waveform panels use separate vertical amplitude ranges.
Limitations and interpretation
- Not physical circuit feedback: feedback occurs between complete buffer passes, not around a sample-delay loop or analog circuit.
- No self-oscillation threshold: Noise mode is explicitly seeded and the loop is re-levelled every pass. A silent controller can therefore still produce a full generated ring.
- Intensity is file-relative: the envelope tracks dynamics relative to each file's own loudest analysed moment, not absolute SPL or calibrated level between files.
- Pitch tracking inherits Praat pitch analysis: unvoiced/ambiguous regions and pitch-analysis errors can affect the tracked resonance. The script smooths, holds gaps and clamps the trajectory but does not infer a musical score.
- Tracking is not universal throughout the processor: the iterative heterodyne band follows the time-varying resonance; Stereo Wide and the harmonic-air exciter use the nominal mean-F0-plus-offset centre.
- Instability is iteration-domain: the random drift factor changes between passes. It is not an audio-rate random modulation.
- Output RMS matching is not perceptual loudness normalization: it targets ordinary RMS and uses a 0.98 peak guard; it is not LUFS/BS.1770 normalization.
- Pseudo-Binaural is not HRTF: it is an asymmetric delay/filter effect.
- Multichannel output is not preserved: final output is mono or stereo.