Spectral Mirror — User Guide

A two-character spectral reflection processor: the original phase-crushed legacy texture and a measured-correct frequency-domain mirror, both rendered as a stereo wet field around a mono source.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Version: 0.4.2 (2026) License: MIT License Repo: https://github.com/ShaiCohen-ops/Praat-plugin_AudioTools
Contents:

What this does

Spectral Mirror reflects frequency-domain content around a controllable axis and adds the reflected image to the retained source spectrum. The processor first derives a mono source, builds different left and right mirror geometries, then returns a stereo result.

The script intentionally offers two different engines. legacy texture preserves the original phase-crushed, chunk-breathing behaviour because that sound became part of the instrument's identity. clean mirror implements the intended frequency reflection in measured frequency coordinates and uses 50% Hann overlap-add normalization.

Important: this is not a one-way "high frequencies fold downward" effect. In the clean engine, any source component whose reflected destination lands inside the receiving band can contribute. A source below the reflection axis can therefore move upward, while one above the axis moves downward.

What is spectral mirroring?

For the clean engine, a source frequency f is reflected around an axis using:

destination = reflection_sum - source_frequency\naxis = reflection_sum / 2

Reflection therefore works like a geometric mirror on the frequency axis. If the axis is 6.8 kHz, 6.0 kHz reflects to 7.6 kHz and 10.0 kHz reflects to 3.6 kHz. The script keeps the identity component and adds the reflected image only where its destination lies below the channel's cutoff.

Not pitch inversion: this is a spectrum-bin transformation, not melodic inversion, pitch-class inversion or formant shifting. Complex FFT bins are reversed in frequency order; because negative-frequency symmetry involves complex conjugation, the mirrored component also carries a time-reversed character within the affected band. That is especially audible on transients.

Quick start

  1. Select exactly one Sound.
  2. Run Basic_Mirror.praat.
  3. Choose a preset and a Character.
  4. Set Dry_wet_mix and Stereo_spread.
  5. Use Edit_details only when you need a custom divisor, stereo reflection offset or output peak.
  6. Run the script and compare the visualization with what you hear.
For the most literal reflection, choose clean mirror. For the original crushed, pulsing sound, keep the default legacy texture.

Presets

The preset changes the base cutoff divisor. Stereo spread is applied afterwards, so the final left and right receiving cutoffs can differ from the nominal base value.

PresetBase cutoff before stereo spread
MildNyquist / 4
ModerateNyquist / 2
StrongNyquist / 8
ExtremeNyquist / 16
CustomNyquist / Custom cutoff divisor; divisor must be greater than 1

Two characters

CharacterWhat it doesLevel / overlap behaviour
legacy texturePreserves the original implementation: numeric frequency controls are used as FFT-bin indices, the real spectrum row is duplicated into both rows, and the nearly non-overlapping Hann chunks create the characteristic phase-crushed breathing texture.Hop = chunk duration − 20 ms. Wet L/R are peak-scaled independently to 0.95 before mixing.
clean mirrorReads from a frozen complex spectrum, reflects by measured bin width, realigns partial-frame mirror images and retains the untouched identity component.50% Hann hop with overlap-sum normalization. Wet L/R use one joint scale to 0.95, preserving their relative balance.

Controls

ControlDefaultMeaning
PresetModerateSets the base receiving-band cutoff.
Characterlegacy textureSelects the original or corrected spectral engine.
Dry_wet_mix0.7Linear wet proportion, 0…1.
Stereo_spread0.25Moves left/right receiving cutoffs apart. Valid range 0…0.9.
Edit_detailsOffOpens the secondary controls.
Custom cutoff divisor2Used only by Custom; must be >1.
Stereo reflection-sum offset0.15Separates the L/R reflection axes; valid range 0…0.9.
Output peak0.9Final target peak for the complete stereo mix.
Draw_visualizationOnDraws the process-oriented four-panel figure.
Play_resultOnPlays the final Sound.

Processing pipeline

  1. Convert the selected source to mono.
  2. Keep a full-rate dry copy.
  3. Process the wet path at min(source sample rate, 32 kHz).
  4. Split the signal into 32,768-sample Hann chunks.
  5. Transform each chunk to the spectrum, apply the selected mirror character independently for L/R geometry, and transform back to sound.
  6. Overlap-add the chunks using the character-specific normalization.
  7. Resample the wet channels back to the original sample rate when required.
  8. Scale the wet field, mix the same mono dry source into L/R, combine to stereo, then target-normalize the final output.

Channels, bandwidth and level

Output name: <source>_mirror_<preset>.

Visualization

The visualization is diagnostic rather than decorative: it shows the actual mapping law and measured output used by the selected character.

Compositional context

Spectral mirroring treats the frequency distribution itself as compositional material. Rather than transposing a melody or shifting every partial by one ratio, the processor reorganizes spectral locations around a fixed axis. This can turn harmonic material into inharmonic structures, move low components upward while sending high components downward, and create time-reversed spectral pre-images on attacks.

The two-character design is also part of the instrument's compositional identity: the legacy engine preserves a historically accidental but musically distinctive phase/chunk texture, while the clean engine exposes the intended reflection law. They should therefore be heard as two related instruments, not as "wrong" and "right" versions of the same sound.