Sound Duplicator — User Guide

Duplicates a selected sound N times, assembles the copies into a single longer sound with crossfades at every join, and applies a shaping envelope across the full output. Four envelope types: Linear, Cosine, Triangle, Gentle arch. Optimised for speed: incremental assembly (one copy in RAM at a time) and a single vectorised Formula call for the envelope.

Author: Shai Cohen Affiliation: Department of Music, Bar‑Ilan University, Israel Version: 1.1 (2026) – rewritten for speed License: MIT License Repo: GitHub
Contents:

What this does

Sound Duplicator creates a new sound by concatenating multiple copies of the selected source, with a smooth crossfade at each join to eliminate clicks. After assembly, a global envelope (Linear, Cosine, Triangle, or Gentle arch) is applied to the entire output, shaping its overall amplitude profile.

Key features v1.1:
  • Incremental assembly – only one copy in RAM at a time, avoiding memory blow‑up for large N.
  • Single vectorised Formula: call for the envelope – no sample‑by‑sample loops.
  • Four envelope shapes with independent fade‑in, fade‑out, and peak level.
  • Crossfade duration adjustable (ms).
  • Presets for common effects: Stutter, Echo Decay, Swell, Tight Loop, Pulse Burst, Long Fade.

Quick start

  1. In Praat, select exactly one Sound object (mono or stereo).
  2. Run script…Sound_Duplicator.praat.
  3. Choose a Preset:
    • Stutter, Echo Decay, Swell, Tight Loop, Pulse Burst, Long Fade
  4. For custom mode (preset = Custom), adjust parameters as desired:
    • Number_of_repetitions – how many copies.
    • Crossfade_duration_ms – overlap length at joins.
    • Envelope_type – Linear / Cosine / Triangle / Gentle arch.
    • Fade_in_percent – percentage of total duration for fade‑in.
    • Fade_out_percent – percentage for fade‑out.
    • Peak_level_percent – maximum amplitude relative to original.
  5. Click OK. The script builds the duplicated sound incrementally, applies the envelope, and imports the result as originalname_dupN_xfX_envelope.
Tip: Start with Swell (4 copies, 120 ms crossfade, Cosine envelope, 25 % in/out) for a smooth build‑up and decay. For a rhythmic stutter, try Stutter (8 copies, 10 ms crossfade, no envelope).
Important: This effect is implemented entirely in Praat – no Python required. The crossfade is applied using Praat’s Concatenate with overlap, which handles the details. The envelope is applied via a single Formula: call, which is vectorised and very fast.

The 6 presets (+ Custom)

PresetCopiesXfade (ms)EnvelopeFade in/outDescription
Stutter810Linear0/0%Rapid, dry repetitions.
Echo Decay580Linear0/60%Echoes with long fade‑out.
Swell4120Cosine25/25%Smooth rise and fall.
Tight Loop6200Linear0/0%Long crossfade, seamless loop.
Pulse Burst820Triangle10/10%Rapid, peaked bursts.
Long Fade3150Gentle arch30/30%Gentle hill‑shaped envelope.

Envelope types

TypeShapeFormula (simplified)Use case
LinearStraight line rise and fallrise = x/fi, fall = (total-x)/foSimple fades, predictable.
CosineS‑shaped (sinusoidal) fades0.5-0.5·cos(πx/fi) etc.Smoothest, natural‑sounding.
TriangleRise to peak at fade‑in end, then continuous linear fallrise: x/fi, fall: 1-(x-fi)/fallDurPeaked, then steady decay.
Gentle archSymmetrical hill (sin²)0.5-0.5·cos(2πx/total)Soft swell and decay, zero at both ends.

The envelope is applied after concatenation and affects the entire output duration. Fade_in_percent and Fade_out_percent are percentages of the total output length. For the Triangle envelope, the fade‑in is the rise, and the fade‑out is the entire remaining length – the separate fade_out_percent is ignored (but still displayed).

Parameters & defaults

Duplication

ParameterRangeDefaultDescription
Number_of_repetitions≥14How many copies of the source to concatenate.

Crossfade

ParameterRangeDefaultDescription
Crossfade_duration_ms≥050 msOverlap length at each join (capped at 90 % of source duration).

Overall Envelope

ParameterRangeDefaultDescription
Envelope_typeLinear / Cosine / Triangle / Gentle archLinearShape of the global amplitude envelope.
Fade_in_percent0–10010Percentage of total duration for fade‑in (0 = no fade).
Fade_out_percent0–10015Percentage for fade‑out. f_in+f_out ≤100.
Peak_level_percent0–100100Maximum amplitude relative to original (scales whole envelope).

Output

ParameterDefaultDescription
Draw_visualizationyesShow source waveform, output waveform with crossfade boundaries, envelope curve, and summary.
Normalize_outputyesScale peak to 0.99 to avoid clipping.
Play_resultyesAuto‑play after processing.

Performance notes

The script is optimised for memory and speed:

For very large N (e.g., 100 repetitions of a long sound), processing time will be dominated by the incremental concatenations (each requires rewriting the growing sound). The envelope itself remains fast.

Visualization (Praat picture)

When Draw_visualization = 1, the script draws:

Tip: The envelope curve plot is especially useful to verify that the fade‑in, sustain, and fade‑out match your intentions. For the Triangle envelope, note that the fall spans the entire remaining length after the fade‑in.

FAQ / troubleshooting

Output is silent / has clicks

If the crossfade duration is too short, clicks may occur at joins. Increase Crossfade_duration_ms. Also check that the envelope is not zeroing out the signal – ensure Peak_level_percent > 0.

Output is distorted / clipped

The script normalises the output to 0.99 peak if Normalize_output is on. If clipping persists, reduce Peak_level_percent (e.g., to 80 %).

Triangle envelope fade_out_percent is ignored

This is by design – the Triangle envelope has a continuous fall from the peak at the end of the fade‑in all the way to zero at the end. The separate fade_out_percent parameter is not used, but still appears in the summary for consistency. To create a triangle with a separate fade‑in and fade‑out, use Linear or Cosine.

Memory usage

For a stereo sound at 44.1 kHz, one second is about 176 kB (44,100 × 4 bytes × 2 channels). A 10‑second sound repeated 100 times would produce a 1000‑second output – about 176 MB. The incremental assembly keeps only two copies in RAM at once, so peak memory is roughly 2 × output size / N? Actually, at the final concatenation, the result is already built; the last step adds one more copy, so memory stays at about (output size) + (one copy). This is still large for very long outputs, but far better than building all copies separately first.

Envelope formula for Gentle arch

The Gentle arch is 0.5 - 0.5·cos(2π·x/total), which equals sin²(π·x/total). It starts at 0, peaks at the midpoint, and returns to 0 – ideal for a swell that decays back to silence.