Phase Magnet — Phase-Aware Sound Hybridisation

Weaves two sounds together by alternating between them at phase-compatible splice points. A "magnetism" parameter keeps the cursors proportionally aligned, producing click-free hybrids from glitch stutter to ambient morph.

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

What this does

This script implements phase-aware sound hybridisation — it weaves two sounds together by alternating between them at splice points chosen for phase compatibility. A "magnetism" parameter keeps the playback cursors proportionally aligned (like magnetic tape pulling the sounds together), while crossfades and zero-crossing detection ensure click-free transitions. The result ranges from glitchy stutter (fast alternation, short segments) to smooth ambient morphs (long segments, high magnetism).

How it works: The script selects a segment length from the current source sound (A or B), then searches for a splice point in the other sound that matches the amplitude, slope, or zero-crossing phase of the segment's end. The "magnetism" parameter determines how much the splice position is pulled toward a proportionally aligned position (keeping the two sounds in sync) versus the previous drift position. Crossfades bridge the gap between segments. The process repeats, alternating sources according to strict A-B-A-B or probabilistic rules.

Key Features:

Performance note (v1.7): The real bottleneck was the splice search, not the blends. Previous versions used per-sample Get value at sample number inside loops over the entire patience window (up to millions of command calls). For zero-crossing modes, the search is now a single Get nearest zero crossing call — thousands of reads reduced to one command. Mode 3 (amplitude match) still scans, but the window is bounded (≤ 100 ms) so it cannot blow up on large patience settings.

Quick start

  1. In Praat, select exactly two Sound objects (order matters: A = first selected, B = second).
  2. Run script…Phase_Magnet.praat.
  3. Choose a preset from the dropdown (Glitch Stutter, Ambient Morph, Rhythmic Alternation, Chaotic Scatter, or Custom).
  4. Adjust parameters: Crossfade length, Patience, Magnetism, Segment range (min/max), Splice mode, Randomness, Start source, Alternation mode.
  5. Click OK — script weaves the sounds, creates output PhaseMagnet_NameA_NameB.
Quick tip: Start with Ambient Morph for smooth, evolving textures (long segments, high magnetism). For rhythmic, stuttering effects, use Glitch Stutter (short segments, low crossfade, high randomness). Rhythmic Alternation produces strict A-B-A-B patterns at a consistent tempo. Enable Draw_visualisation to see the splice timeline — blue bars = segments from A, orange = from B.
Important: Both sounds are resampled to the sample rate of the first selected sound (A) if rates differ. Segment length is randomised between min and max per splice. Magnetism = 100% locks the splice point to proportionally aligned positions (sounds stay in sync). Magnetism = 0% ignores proportional alignment entirely (free drift). Crossfades prevent clicks — increase if you hear pops. Patience controls the search window for splice points; larger patience = wider search = more compatible matches but slower (except zero-crossing modes).

5 Presets

PresetCrossfadePatienceMagnetismSegment (ms)MatchingRandomAlt ModeCharacter
Glitch Stutter2 ms20 ms95%10–45Zero crossing50%StrictFast, glitchy, stuttering texture
Ambient Morph150 ms500 ms60%400–1200Same-slope ZC10%ProbabilisticSmooth, evolving, ambient morphs
Rhythmic Alternation5 ms50 ms100%125–250Same-slope ZC0%StrictSteady A-B-A-B, rhythmic
Chaotic Scatter15 ms300 ms20%20–800Amplitude match100%ProbabilisticUnpredictable, wild, chaotic

Splice Modes (3)

Mode 1 — Zero crossing

Finds the nearest zero crossing to the predicted splice position. Guarantees amplitude continuity (sample value = 0 at the splice point). Fastest mode — O(1) using Praat's native Get nearest zero crossing.

Best for: Percussion, transients, or any sound where click-free splicing is critical.

Mode 2 — Same-slope zero crossing

Same as zero crossing, but also requires the slope (direction) of the crossing to match the source's slope. This preserves waveform phase (positive vs negative zero crossing).

Best for: Sustained tones, where matching slope reduces phase cancellation at the splice.

Mode 3 — Nearest amplitude match

Searches for a sample whose amplitude is closest to the source's endpoint amplitude, with bonus for matching slope. Performs a bounded linear scan (≤100 ms window).

Best for: Noisy or complex signals where zero crossings are too frequent or amplitude continuity is more important.

Score function (Mode 3)

score = |v₀ - from_amp| + slope_penalty + 0.5 × d

where d = normalised distance from target position, slope_penalty = 0 if slopes match, else 0.2.

The candidate with lowest score is chosen as the splice point.

Parameters

Timing & Geometry

ParameterRangeDefaultDescription
Crossfade_length_ms0–20010Cosine fade duration at each splice. Prevents clicks.
Patience_ms0–1000100Search window around predicted splice point (±). Larger = more compatible matches.
Magnetism (%)0–100800 = ignore proportional alignment (free drift). 100 = lock to proportionally aligned position.
Minimum_segment_ms> crossfade50Shortest possible segment length.
Maximum_segment_ms> min500Longest possible segment length. Actual length randomised between min and max.

Behaviour

ParameterOptionsDescription
Matching_modeZero crossing / Same-slope ZC / Nearest amplitude matchHow splice points are chosen in the target sound.
Randomness (%)0–100Adds random offset to predicted splice position. 100 = up to ±patience samples of jitter.
Start_sourceA / BWhich sound provides the first segment.
Alternation_modeStrict A-B-A-B / ProbabilisticStrict = alternates every segment. Probabilistic = dice roll per segment (probability = segment length relative to range).
Magnetism explained: For each splice, the predicted position in the other sound is calculated as:
predicted = magnetism × (proportional_position) + (1 - magnetism) × (previous_position)
where proportional_position = (current_time / dur_A) × dur_B (or the inverse). Magnetism = 100% means splice points stay proportionally aligned (sounds play in sync). Magnetism = 0% means splice points drift freely from the previous position.

Applications

Glitch / Stutter effects (Glitch Stutter preset)

Use case: Transform a vocal or drum loop into a stuttering, glitchy texture.

Settings: Very short segments (10–45 ms), high magnetism (95%), zero-crossing mode, high randomness (50%). The rapid alternation between sounds creates a granular, stuttering effect.

Ambient morphs / crossfades (Ambient Morph preset)

Use case: Gradually morph from one sound into another over time.

Settings: Long segments (400–1200 ms), long crossfade (150 ms), moderate magnetism (60%), same-slope ZC mode. The result is smooth, evolving hybrids where the two sounds blend seamlessly.

Rhythmic alternation (Rhythmic Alternation preset)

Use case: Create a call-and-response pattern between two sounds.

Settings: Strict A-B-A-B alternation, magnetism = 100% (perfect sync), medium segment length (125–250 ms). Each sound plays for a fixed rhythmic duration before switching.

Chaotic / unpredictable textures (Chaotic Scatter preset)

Use case: Experimental sound design where unpredictability is desired.

Settings: Low magnetism (20%), high randomness (100%), amplitude match mode, probabilistic alternation. The splice points are nearly random, producing wild, disorienting hybrids.

Workflow: Voice + Drone → Ambient Vocal Morph

Sounds: A = spoken voice, B = sustained synth drone.
Settings: Ambient Morph preset (long segments, same-slope ZC, magnetism=60%).
Result: The voice and drone weave together — voice phrases fade into the drone, then drift back. The magnetism keeps approximate timing alignment, so voice syllables still land roughly where expected.

Workflow: Drum loop + Drum loop → Rhythmic Stutter

Sounds: Two different drum loops at same tempo.
Settings: Rhythmic Alternation preset (strict A-B-A-B, magnetism=100%, segment = 1/8 note).
Result: A new drum pattern that alternates between the two loops every 1/8 note — like a live remix.

Workflow: Speech + Noise → Chaotic Glitch

Sounds: A = speech, B = white noise.
Settings: Chaotic Scatter preset (low magnetism, high randomness, amplitude match mode).
Result: The speech is constantly interrupted by noise bursts at unpredictable positions — a chaotic, glitchy texture.

Troubleshooting:
Clicks at splices: Increase crossfade_length_ms (10–50 ms usually sufficient). Ensure crossfade ≤ segment length.
Output duration too long/short: The total duration is approximately the sum of both input durations (up to n_A + n_B samples). For shorter outputs, reduce segment lengths or stop manually.
Magnetism not working as expected: Magnetism = 100% locks to proportional alignment based on time, not sample count. If sounds have different durations, proportional alignment maps progress (0→1) from one sound to the other.
Visualisation shows wrong splice colours: Blue = A (first selected sound), orange = B (second). Check selection order in Praat before running.
Mode 3 (amplitude match) is slow: The window is bounded to 100 ms to prevent explosion. If you need larger search, use zero-crossing modes (fast, O(1)).

Visualisation (Suite 8×8)

When Draw_visualisation is enabled, the script generates a Praat picture with:
  • Title bar — preset name, sound names, magnetism %, splice mode, splice count
  • Source A waveform (left) — blue curve, first selected sound
  • Source B waveform (right) — orange curve, second selected sound
  • Hybridised output waveform — full-width, dark grey
  • Splice-source timeline — full-width, colour-coded bars: blue = from A, orange = from B. Each bar's width = segment duration.
  • Summary bar — segment counts (A/B), crossfade length, segment range, output duration
The splice timeline is particularly useful for debugging — you can see exactly which sound contributed which segment and how alternation progressed.