4-Channel Canon

Creates four delayed, independently varispeed-shifted copies of one source and routes them as quadraphonic, two stereo-pair, or stereo-mix output.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Version: 0.4.1 (2026) Praat
Contents:

What this does

4-Channel Canon always generates four voices from one selected Sound. The source is converted to mono, resampled to the requested working sample rate, copied four times, and each copy receives an independent playback-rate pitch shift and entry delay.

The four delayed voices can remain on four separate channels, be returned as two separate stereo pairs, or be reduced to one stereo mix. There is no independent time-stretch, audio reversal, variable voice count, tempo-sync system, dry/wet control, or phase-vocoder stage in this implementation.

What does “canon” mean here? The source material is repeated as four copies whose starts are offset in time. Presets can also assign different pitch transpositions, so the result can range from a strict unison canon to chordal, octave, cluster, or registrally spread entries.

Quick start

  1. Select exactly one Sound in Praat.
  2. Run 4-Channel_Canon.praat.
  3. Choose one of the nine named presets or Custom.
  4. For Custom, set the four Shift_percent values and four entry delays.
  5. Choose the working Resample_frequency, optional edge-fade time, and output format.
  6. Enable or disable the visualization and playback, then run the script.
The named presets override all four pitch-shift and delay values. Resample_frequency, Fade_time, output format, visualization, and playback remain user-controlled.

Signal path

Input Sound → Copy → Convert to mono → Resample to Resample_frequency (precision 50) → make four copies → per voice: Override sampling frequency by shift_rate → Resample back to Resample_frequency → optional Fade in + Fade out → place voice at its Delay_n in its own mono channel buffer → combine according to Output_format → Scale peak to 0.95

Pitch shifting

For voice n: ratio_n = 1 + Shift_percent_n / 100 shift_rate_n = Resample_frequency × ratio_n semitones_n = 12 × log2(ratio_n) Because this is playback-rate / sample-rate reinterpretation: output pitch = source pitch × ratio_n voice duration ≈ source duration / ratio_n

Pitch and duration therefore change together. Positive percentages raise pitch and shorten the voice; negative percentages lower pitch and lengthen it.

Source channel handling

Any multichannel input is averaged to mono with Praat's Convert to mono before the canon is generated. The current script does not use strongest-channel fallback for phase-cancelling material.

Presets

PresetVoice transpositionsDelays (s)
CustomForm values; defaults ≈ 0, +1.0, +2.0, −1.0 st0.00, 0.30, 0.60, 0.90
Classic Canon0, 0, 0, 0 st0.00, 0.50, 1.00, 1.50
Octave Stack+12, 0, −12, −24 st0.00, 0.20, 0.40, 0.60
Perfect Fifths0, +7, +14, +21 st0.00, 0.30, 0.60, 0.90
Major Chord0, +4, +7, +12 st0.00, 0.25, 0.50, 0.75
Minor Chord0, +3, +7, +12 st0.00, 0.25, 0.50, 0.75
Cluster0, +1, +2, +3 st0.00, 0.15, 0.30, 0.45
Wide Spread−12, −5, +7, +19 st0.00, 0.40, 0.80, 1.20
Accelerando Canon0, 0, 0, 0 st0.00, 0.80, 1.20, 1.40
Reverse Canon+12, +5, 0, −7 st0.90, 0.60, 0.30, 0.00
Reverse Canon reverses the entry order through descending delays; it does not reverse the audio samples. Accelerando Canon uses progressively shorter inter-entry intervals: 0.80 s, then 0.40 s, then 0.20 s.

Parameters

ParameterDefaultActual behaviour
PresetCustomCustom plus nine named pitch/delay presets.
Shift_percent_10Playback-rate pitch offset for voice 1.
Shift_percent_26.0Playback-rate pitch offset for voice 2.
Shift_percent_312.0Playback-rate pitch offset for voice 3.
Shift_percent_4−5.5Playback-rate pitch offset for voice 4.
Delay_1 … Delay_40.0, 0.3, 0.6, 0.9 sAbsolute entry time for each voice in the output buffer.
Resample_frequency44100 HzWorking/output sample rate. Initial source resampling and all pitch-shift resampling use precision 50.
Fade_time0.01 sIf greater than zero, Praat Fade in and Fade out are applied to each pitched voice before placement.
Output_format4 channels4-channel output, two stereo-pair objects, or one stereo reduction.
Draw_visualizationonDraws the v0.4.1 process/parameter figure.
Play_resultonPlays the Sound stored as result after processing.

Output formats

4 channels (quadraphonic)

Voice 1 → channel 1, Voice 2 → channel 2, Voice 3 → channel 3, Voice 4 → channel 4. The result is peak-scaled to 0.95 and named <source>_canon4ch_<preset>.

2 stereo pairs

Two separate stereo Sounds are created: voices 1+2 as <source>_canon_pair1_<preset> and voices 3+4 as <source>_canon_pair2_<preset>. Each pair is independently peak-scaled to 0.95.

In this mode, the script's result variable points to pair 1. Consequently Play_result and the output-waveform visualization use pair 1; pair 2 remains as a separate Sound object in the Objects list.

Stereo mix

Voices 1 and 2 are summed into the left channel; voices 3 and 4 are summed into the right channel. The combined stereo Sound is peak-scaled to 0.95 and named <source>_canon_stereo_<preset>.

The nominal output duration is the latest delay + pitched voice duration, plus 0.05 s.

Visualization

The v0.4.1 figure uses an 8-inch suite-standard layout and visualizes the canon structure rather than adding an explanatory text layer.

Limits & edge cases

Custom pitch values: the script does not clamp Shift_percent_n. The playback-rate ratio is 1 + shift/100, so values at or below −100% do not define a valid positive sampling-rate ratio and should not be used.

Custom delay fields are also not explicitly constrained to non-negative values. The presets use non-negative delays and the placement logic is designed around entries inside a zero-based output buffer.

Because the source is converted to mono before voice generation, stereo imaging from the input is not preserved. Four-channel separation is created by assigning the four mono canon voices to different output channels.

Peak scaling is always applied to the final result (or independently to each stereo pair). There is no user-facing normalization bypass or dry/wet mix in this version.