Math Operations Between Sounds — User Guide
Sample-by-sample mathematical combination of two Sound objects, with 17 operation presets, 31 manual operations, explicit channel handling, deterministic random scatter when seeded, and four output-level modes.
What this does
Math Operations Between Sounds combines two Sound objects by applying one mathematical rule to corresponding samples. The script offers four operation tiers: Basic, Modulation, Nonlinear, and Advanced. In Custom mode, only the highest active tier runs: Advanced > Nonlinear > Modulation > Basic.
The script works on a copy of Sound 1, uses Sound 2 as the second operand, then applies the selected output-level policy. Presets select an operation and, where relevant, set Modulation_depth or Nonlinear_intensity. They do not reset global output scaling, channel policy, random seed, divide epsilon, fold passes, or magnitude-product polarity.
Inputs, order, duration, and channels
Sample rate and duration
- The two Sounds must have the same sampling frequency; otherwise the script exits.
- The processing duration is
min(duration(S1), duration(S2)). - Each Sound is cut from its own actual start time, then the extracted parts are shifted to a common zero-based time domain. Sounds whose domains start at different absolute times are therefore aligned by their own beginnings, not by absolute timestamp.
Channel policy
| Policy | Behavior |
|---|---|
| Sound 1 defines layout (default; v0.2/v0.3 behavior) | The result has Sound 1's channel layout. Mono Sound 2 is broadcast across Sound 1's channels. If Sound 2 has extra channels, they are ignored. If Sound 1 has more channels than Sound 2, Sound 1's extra channels are processed against silence. |
| Require matching channel counts | The script exits if the two inputs do not have the same number of channels. |
| Mix both to mono | Each input is converted to mono before the operation; the result is mono. |
Quick start
- Select exactly two Sound objects in Praat. Check their top-to-bottom order.
- Choose a Preset, or choose Custom (manual settings).
- For Custom, select operations in one or more tiers. If more than one tier is active, only the highest-priority tier runs.
- Adjust the parameter that actually belongs to that operation: modulation depth, nonlinear intensity, fold passes, divide epsilon, product polarity, or random seed.
- Choose a Channel_policy.
- Choose an Output_mode and Output_scaling.
- Run the script. The result is named
Sound1_PresetName_Sound2.
Random_seed.
Presets
The menu contains Custom + 17 operation presets. The values below are the settings assigned by each preset. Other form controls keep their current values.
| Preset | Selected operation | Preset parameter | Output tag |
|---|---|---|---|
| Clean Add | Basic: Add | — | Add |
| Clean Multiply (Ring Mod) | Basic: Multiply | — | RingMod |
| Tremolo Effect | Modulation: Tremolo | Mod depth = 0.5 | Tremolo |
| Crunch Mod (Arctan) | Modulation: Soft clip (arctan) | Mod depth = 2.0 | Crunch |
| FM-like Waveshaping | Modulation: FM-like sin(S1) × S2 | Mod depth = 2.0 | FM |
| Double Sine Waveshaping | Modulation: sin(S1) × sin(S2) | Mod depth = 1.5 | DoubleSine |
| Wavefold Distortion | Nonlinear: Wavefold | Intensity = 0.8; current Fold_passes retained | Wavefold |
| Quantized Lo-Fi | Nonlinear: Quantize to 1/N amplitude steps | Intensity = 0.5 → N = 8 | QuantizedLoFi |
| Cosine Cross-Waveshaper | Nonlinear: Cosine cross-waveshape | Intensity = 1.2 | CosXWaveshape |
| Pseudo-Sync | Nonlinear: Hard sync sim | Intensity = 0.9 | PseudoSync |
| Logistic-Style Shaping | Advanced: Logistic-style non-recursive | Intensity = 0.5 → r = 3.5 | LogisticStyle |
| Soft Normalized Mix | Nonlinear: Soft normalize mix | Intensity = 0.8 | SoftNormMix |
| Cross-Phase Waveshaper | Advanced: Cross-phase waveshaper | Intensity = 0.5 → index = 50 | CrossPhase |
| Random Amplitude Scatter | Advanced: Random amplitude scatter | Intensity = 0.5; current seed retained | RandAmpScatter |
| Geometric Product (sqrt magnitudes) | Advanced: Geometric product | Current Geometric_polarity retained; intensity unused | GeoProduct |
| Vector Morph | Advanced: Vector morph | Intensity = 0.5 | VectorMorph |
| Rectify Distortion | Advanced: Rectify & mix | Intensity = 0.5 → S2 magnitude weight = 1.0 | Rectify |
Operations
In the formulas below, S1 is the current sample of Sound 1 and S2 is the corresponding sample of Sound 2. d denotes Modulation_depth; i denotes Nonlinear_intensity.
Basic operations
| Operation | Actual formula / behavior | Notes |
|---|---|---|
| Add | S1 + S2 | Can exceed full scale. |
| Subtract | S1 − S2 | Order-sensitive. |
| Multiply (Ring Mod) | S1 × S2 | For sinusoidal inputs, produces sum/difference components. |
| Divide | 0 when |S2| ≤ Divide_epsilon; otherwise S1/S2 | Order-sensitive; guard avoids near-zero denominator blow-ups. |
| Average | (S1 + S2)/2 | Arithmetic average; not an equal-power crossfade. |
| Minimum | min(S1,S2) | Sample-wise minimum, not envelope extraction. |
| Maximum | max(S1,S2) | Sample-wise maximum, not envelope extraction. |
| Absolute difference | |S1 − S2| | Unsigned / rectified difference. |
| XOR-like (sign mixing) | Average magnitude; negative when the signs differ, positive otherwise | A sign-based custom mapping, not digital XOR. |
Modulation tier
| Operation | Formula | Meaning |
|---|---|---|
| AM unipolar (sin) | S1 × [0.5 + 0.5 sin(S2 × 10πd)] | S2 sample values drive a sine-shaped unipolar gain factor. |
| AM unipolar (cos) | S1 × [0.5 + 0.5 cos(S2 × 10πd)] | Cosine variant of the same sample-value modulation. |
| FM-like (sin) | sin(S1 × 5πd) × S2 | Static sine waveshaping/cross-modulation; no phase integration. |
| FM-like (cos) | cos(S1 × 5πd) × S2 | Cosine variant; not conventional FM. |
| Double sine waveshaping | sin(S1 × 5πd) × sin(S2 × 5πd) | Both sample streams are sine-waveshaped, then multiplied. |
| Soft clip (arctan) | (2/π) arctan(S1 × S2 × 10d) | Bounded nonlinear transform of the sample product. |
| Power mod | Signed |S1|^max(1+S2d,0.05), with a near-zero safety guard | Exponent is floored at 0.05; negative exponents are not allowed. |
| Tremolo | S1 × (1 + S2d) | Acts as tremolo when S2 is an LFO. For depth > 1 the gain can become negative. |
Nonlinear tier
| Operation | Actual behavior | Role of intensity |
|---|---|---|
| Cosine cross-waveshape | S1 × cos(2π × S2 × 100i) | Scales the cosine shaping index. This is not a frequency shifter. |
| AM depth control | S1 × (1 + S2i) | Direct gain-modulation depth. |
| Wavefold | Repeated reflection of S1+S2 around threshold T=1/(0.5+i) | Higher intensity lowers the threshold; Fold_passes sets repeated reflections. |
| Hard sync sim | If |S2| > |S1|i, output takes sign(S2) × |S1|; otherwise S1×S2 | Controls the switching criterion. It is not oscillator reset/sync. |
| Quantize to 1/N amplitude steps | round((S1+S2)N)/N | N = max(1, round(16i)). This defines step size 1/N; it is not an N-bit quantizer. |
| Amplitude-dependent blend | S1(1−i|S2|) + S2i | Controls both S1 attenuation and S2 contribution. |
| Soft normalize mix | (S1+S2) / [1+i(|S1|+|S2|)] | Controls static amplitude-dependent compression of the sum. |
Advanced tier
| Operation | Actual formula / behavior | Notes |
|---|---|---|
| Geometric product (sqrt magnitudes) | sqrt(|S1|) × sqrt(|S2|) | With default polarity, Sound 1's sign is restored. Unsigned mode remains nonnegative. |
| Magnitude product | |S1| × |S2| | Also optionally restores Sound 1's sign. It is a direct magnitude product, not an exponential-domain transform. |
| Vector morph | S1(1−i) + S2i | A linear crossfade only for 0≤i≤1. Values above 1 extrapolate and give Sound 1 a negative weight. |
| Logistic-style shaping | (S1+S2) × [r − r|S1||S2|], with r=7i | Non-recursive static shaping; not a logistic-map iteration or chaotic state system. |
| Rectify and mix | |S1| − (2i)|S2| | Output may be positive or negative because one rectified magnitude is subtracted from the other. |
| Cross-phase waveshaper | S1 cos(S2×100i×π) + S2 sin(S1×100i×π) | Sample-wise trigonometric recombination; no FFT, frames, phase estimation, or overlap-add. |
| Random amplitude scatter | (S1+S2) × [0.8 + 0.8i·U(−1,1)] | Per-sample random gain. At i=0.5 the gain spans 0.4–1.2. |
Operation-specific parameters
| Parameter | Default | Used by | Behavior |
|---|---|---|---|
| Modulation_depth | 1.0 | All Modulation-tier operations | Controls shaping/modulation strength. |
| Nonlinear_intensity | 0.5 | Most Nonlinear and Advanced operations | Its mapping is operation-specific. It is not used by the two magnitude-product operations. |
| Fold_passes | 4 | Wavefold only | Number of reflection passes. One pass may still leave very large values outside the threshold. |
| Divide_epsilon | 0.001 | Divide only | If |S2| ≤ epsilon, output is defined as 0 for that sample. |
| Geometric_polarity | Restore sign of Sound 1 | Both magnitude products | Signed mode restores sign(S1); unsigned mode returns a nonnegative magnitude signal and can therefore contain substantial DC. |
| Random_seed | 0 | Random amplitude scatter only | Positive seed = reproducible run. 0 = safely initialized unpredictable seed. |
Output level
Output_scaling is a positive scalar. The four modes differ in where scaling is applied relative to peak normalization.
| Output mode | Processing order | Consequence |
|---|---|---|
| Normalize to 0.95 (v0.2/v0.3; scaling inert) | Apply Output_scaling → measure → normalize peak to 0.95 | For a non-silent result and positive scaling, normalization divides the scaling back out. Changing Output_scaling does not change the final samples. |
| Normalize to 0.95, then apply scaling | Normalize to 0.95 → multiply by Output_scaling | Scaling survives. Values above about 1.0526 can push a normalized peak above 1.0. |
| Attenuate to 0.95 only if peak > 0.95 (after scaling) | Apply Output_scaling → if peak exceeds 0.95, globally Scale peak to 0.95 | This is global attenuation, not a dynamics limiter. Signals already below 0.95 are left unchanged. |
| Preserve (scaling only) | Multiply by Output_scaling only | No peak normalization. Output may exceed ±1.0. |
All normalization modes guard silent output: if the measured peak is zero, normalization is skipped. The report warns if the final measured peak exceeds 1.0 and also checks for undefined samples.
Visualization and reporting
When Draw_visualization is enabled, the script draws an 8×8 summary page. It is descriptive of the actual run rather than a generic catalog of all controls.
- Title: Sound 1, Sound 2, preset, active tier, active operation, and used duration.
- Operation diagram: Sound 1 + Sound 2 → selected mathematical operation → result.
- Parameter report: only operation-relevant controls, plus output scaling, output mode, channel policy, and alignment information.
- Input waveforms: the equal-duration extracted portions used by the operation.
- Result waveform: mono as one waveform; for multichannel results, channels 1 and 2 are shown and the label states when additional channels exist.
- Summary bar: active operation parameters, output-level policy, output duration, and measured peak.
The Info window separately reports source durations/channel counts, channel-policy consequences, each source's original start time, the operation actually applied, final output level, random seed when relevant, and warnings for peaks above 1.0 or undefined samples.
Limitations and interpretation
- Sample-domain only: all operations are direct sample-value transforms. There is no FFT, phase tracking, oscillator state, resynthesis, or true phase-vocoder processing.
- No automatic anti-aliasing: nonlinear waveshaping, quantization, hard switching, and folding can generate components above Nyquist that alias back into the audible band.
- No automatic DC removal: unsigned magnitude operations and rectified formulas can produce DC or a positive mean.
- Input order matters: several operations and the default channel layout are asymmetric with respect to Sound 1 and Sound 2.
- Channel-policy semantics are explicit but not universal mixing rules: under Sound-1-defined layout, missing Sound 2 channels are treated as silence and excess Sound 2 channels are discarded.
- Random scatter is stochastic: use a positive Random_seed when exact reproducibility is required.
- Output normalization changes level, not the transform: matched peak does not make two operations perceptually equivalent and can hide the absolute gain produced by a formula.
Examples
Ring modulation
S1: source audio
S2: sine tone or another pitched Sound
Preset: Clean Multiply (Ring Mod)
The result is the direct sample product. For two sinusoids this produces sum- and difference-frequency components.
Rhythmic amplitude control
S1: source audio
S2: low-frequency or rhythmic control waveform
Preset: Tremolo Effect
The operation is S1 × (1 + S2×depth); the behavior depends on the actual amplitude and shape of S2.
Reproducible random scatter
Preset: Random Amplitude Scatter
Random_seed: choose a positive integer
The same inputs, parameters, and seed reproduce the same random-gain sequence.
Signed vs unsigned magnitude product
Use either magnitude-product operation and compare Restore sign of Sound 1 with Unsigned magnitude product. The unsigned version is nonnegative and can carry a strong DC component.