BFG-Inspired Pitch & Duration Modulation

A procedural control-field modulator for Praat Manipulation. A deterministic two-dimensional field is sampled along time and channel trajectories, then mapped to pitch targets and, optionally, to a shared DurationTier.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Version: 0.5 (2026) License: MIT License Repo: Praat AudioTools
Contents:

What this does

The script creates a control field N(x,y) from one of 12 procedural basis functions. Elapsed source time traverses the field on the X axis, while each audio channel uses its own Y coordinate. The sampled field controls pitch deviation in a Praat Manipulation object. A second, separate field trajectory can control a shared DurationTier.

BFG-inspired: Cycling '74 jit.bfg evaluates procedural basis functions and basis-function graphs over coordinate fields. This Praat script uses custom implementations and analogues of related procedural ideas; it does not reproduce jit.bfg numerically or provide a compatible implementation.
Input scope: Pitch processing depends on Praat's trackable-F0 analysis and overlap-add resynthesis. It is intended primarily for voiced speech, singing, and other approximately monophonic pitched material. Polyphonic, noisy, or strongly percussive signals may contain few usable pitch points or may produce resynthesis artifacts.

Channel behavior: each input channel is extracted, analyzed, pitch-modulated, and resynthesized separately. The original number and order of channels are restored at the end. Pitch trajectories may differ by channel through Y_offset_per_channel; duration modulation is shared by all channels.

Quick start

  1. Select exactly one Sound object in Praat.
  2. Run BFG_Pitch_Time_Modulation.praat.
  3. Choose one of the 20 named presets, or use Custom.
  4. For Custom, choose the basis and field controls, then set pitch depth and optional duration depth.
  5. Set Pitch_floor and Pitch_ceiling for the source.
  6. Run the script. The result remains selected; it is played automatically only when Play_result is enabled.

Parameters

Field and modulation controls

ControlDefaultBehavior
Basis_typePerlin fBmSelects one of the 12 field generators described below.
Field_rate_units_per_s4.5X-axis traversal rate. For periodic bases it is also the cycle rate; for noise/fractal bases it is a domain-traversal rate rather than one modulation frequency.
Octaves3Used by Perlin fBm, ridged multifractal, and turbulence. Values above 8 are limited to 8.
Persistence0.5Amplitude multiplier between fractal octaves. Accepted range is > 0 to 1.5.
Lacunarity2.0Frequency multiplier between fractal octaves. Must be at least 1.
Random_seed12345Offsets the deterministic hash used by the stochastic/noise bases. Periodic bases such as sine, triangle, square, and checker do not use it.
Pitch_depth_semitones0.5Peak semitone scale applied to the calibrated pitch field. Magnitude is limited to 48 semitones.
Quantize_grid_semitones00 disables quantization. Positive values round the field-derived semitone deviation to the nearest grid multiple.
Time_depth_percent00 disables duration modulation. Otherwise the shared duration factor is 1 + Nt(t) * depth/100. Magnitude is limited to 90%.
Time_rate_ratio0.25Multiplies the field traversal rate used by the duration trajectory.
Y_offset_per_channel1.5Channel ch uses y = (ch-1) * Y_offset_per_channel. Larger offsets sample more widely separated field trajectories.
Calibrate_realized_depthYesCenters each realized pitch-channel trajectory independently, then applies one shared gain so the largest centered excursion reaches +/-1. The duration trajectory is centered and scaled separately.

Analysis and output controls

ControlDefaultBehavior
Pitch_floor75 HzLower bound passed to To Manipulation.
Pitch_ceiling600 HzUpper analysis bound. It must be below 0.45 * sampling_rate.
Peak_ceiling0.95Attenuate-only final peak ceiling. If the output peak is already at or below this value, no gain change is applied. Values above 1 are limited to 1.
Draw_visualizationYesDraws the diagnostic page described below.
Draw_bfg_mapYesIncludes the raw 2-D field map when visualization is enabled.
Map_columns180Horizontal map resolution; limited to 600.
Map_rows48Vertical map resolution; limited to 180.
Play_resultYesPlays the final result after processing.

Presets

Each named preset overrides exactly these ten controls: Basis_type, Field_rate_units_per_s, Octaves, Persistence, Lacunarity, Pitch_depth_semitones, Quantize_grid_semitones, Time_depth_percent, Time_rate_ratio, and Y_offset_per_channel. The random seed, calibration switch, pitch-analysis bounds, peak ceiling, visualization settings, and playback setting remain user-controlled.

PresetBasisField: rate / oct / pers / lacPitch: depth / gridTime: depth% / ratioY offset
Subtle VibratoPerlin fBm5.5 / 2 / 0.50 / 2.00.30 / off0 / 0.250.7
Organic VibratoPerlin fBm4.5 / 3 / 0.50 / 2.00.80 / off0 / 0.251.5
Multiscale Pitch-Time DriftPerlin fBm3.0 / 4 / 0.65 / 2.00.50 / off5 / 0.151.5
Slow Value-Noise DriftValue noise0.25 / 2 / 0.50 / 2.00.70 / off3 / 0.502.0
Stereo Chorus DetunePerlin fBm0.9 / 2 / 0.50 / 2.00.25 / off0 / 0.254.0
Drunken ChoirPerlin fBm1.6 / 3 / 0.55 / 2.02.50 / off0 / 0.256.0
Fast Multiscale Pitch ShiverPerlin fBm10 / 4 / 0.65 / 2.00.35 / off0 / 0.252.5
Cellular Pitch JumpsVoronoi cellular22 / 3 / 0.50 / 2.07.00 / off0 / 0.253.0
Chromatic Cellular StepsVoronoi cellular6 / 3 / 0.50 / 2.012.0 / 1 st0 / 0.251.5
Wide Pitch-Time WarpValue noise1.2 / 2 / 0.50 / 2.03.0 / off35 / 0.601.5
Quantum GlitchVoronoi cellular30 / 3 / 0.50 / 2.04.0 / 2 st55 / 1.003.5
Slow Sine Pitch SweepSine LFO0.35 / 3 / 0.50 / 2.06.0 / off0 / 0.252.0
Ridge SnapRidged multifractal5.0 / 4 / 0.55 / 2.02.00 / off0 / 0.252.0
Turbulent WarpTurbulence4.0 / 4 / 0.60 / 2.01.20 / off12 / 0.302.0
Sparse Pitch ExcursionsSparse convolution3.0 / 3 / 0.50 / 2.05.00 / 1 st0 / 0.252.5
Cell-Edge DetuneCellular edges12 / 3 / 0.50 / 2.01.50 / off0 / 0.253.0
Checker TrillChecker9 / 3 / 0.50 / 2.03.00 / 1 st0 / 0.251.0
Quasiperiodic Stereo DetuneSine bank2.2 / 3 / 0.50 / 2.00.60 / off0 / 0.253.0
Triangle Pitch-Time WarpTriangle LFO0.6 / 3 / 0.50 / 2.08.00 / off20 / 1.001.5
Hard TrillSquare LFO7 / 3 / 0.50 / 2.01.00 / 1 st0 / 0.251.5

Basis functions

Perlin fBm fractal

Additive fractal Brownian motion built from the script's 2-D gradient-noise function.

Ridged multifractal fractal

Rectifies and squares octave noise to create narrow high ridges over lower regions.

Turbulence fractal

Uses the absolute value of octave noise before summation, producing rectified multiscale motion.

Value noise noise

Quintic interpolation between deterministic hashed lattice values.

Sparse convolution noise

Sums signed cosine-windowed kernels around hashed feature points.

Voronoi cellular cellular

Assigns the value of the nearest deterministic feature point, creating piecewise-constant regions.

Cellular edges cellular

Maps the difference between the nearest and second-nearest feature-point distances.

Checker periodic

Hard two-state checker field based on integer X/Y cells.

Sine LFO periodic

A single sine field; Y position changes phase.

Sine bank quasiperiodic

Weighted sum of three sine components at 1x, 1.618034x, and 2.718282x.

Triangle LFO periodic

Piecewise-linear triangle field with Y-dependent phase.

Square LFO periodic

Two-state field obtained from the sign of a sine function.

Processing pipeline

1. Coordinate mapping and field detail

Pitch field coordinates
x = elapsed_time * Field_rate_units_per_s
y = (channel - 1) * Y_offset_per_channel

For Perlin fBm, ridged multifractal, and turbulence, the script estimates the finest field-detail rate as field_rate * lacunarity^(octaves-1). For the sine bank it uses field_rate * 2.718282. Other bases use the field rate directly.

2. Realized pitch-field calibration

When Calibrate_realized_depth is enabled, the script scans each actual channel trajectory over the full source duration. It subtracts a separate mean from each channel, finds the largest absolute centered excursion across all channels, and uses one common gain equal to its reciprocal. Therefore the largest realized pitch-field excursion reaches +/-1 while relative depth differences between channels are retained.

When calibration is disabled, pitch fields use zero offset and unit gain; values are still clipped to the interval [-1, 1] before mapping to pitch.

3. Pitch mapping

Pitch target

semitone_deviation = Np(t, ch) * Pitch_depth_semitones

If the grid is positive: deviation = round(deviation/grid) * grid

pitch_factor = 2^(deviation/12)

requested_F0 = analyzed_F0 * pitch_factor

Final target F0 values are clipped to 20 Hz through 0.45 x sampling rate. The Info window reports how many targets were clipped.

4. Adaptive Manipulation analysis step

analysis_step = clamp(1 / (8 * field_detail_rate), 0.002, 0.010) seconds.

The script also estimates control samples per field-detail unit and reports a warning when the value falls below 4.

5. Shared duration field

If Time_depth_percent is nonzero, a separate Y plane is used for duration control. The duration trajectory is sampled at field_rate * Time_rate_ratio. With calibration enabled, its piecewise-linear trajectory is centered using a trapezoidal mean and independently scaled to a peak magnitude of 1.

relative_duration = 1 + Nt(t) * Time_depth_percent / 100

These values are written to one DurationTier and the same tier is inserted into every channel's Manipulation object. Values above 1 locally lengthen time; values below 1 locally shorten it. The number of duration control intervals adapts to the estimated time-field detail and is capped at 6000 intervals (6001 points).

6. Per-channel resynthesis

Each channel receives its field-derived PitchTier and the shared DurationTier, then uses Get resynthesis (overlap-add). If no pitch points are detected for a channel, the script does not replace that Manipulation object's existing pitch tier.

Output behavior

PropertyBehavior
Name<source>_bfg_<preset>, with spaces removed from the preset name.
ChannelsThe original channel count and order are preserved. Mono remains mono; multichannel inputs are rebuilt from the separately resynthesized mono channels.
Sample ratePreserved through the Manipulation resynthesis and channel recombination.
Time originThe result is shifted so its start time matches the source start time.
DurationWithout duration modulation, the result follows the source duration apart from resynthesis behavior. With a DurationTier, local relative-duration factors can change the final duration. The Info window reports input duration, the integrated tier-model duration, and actual output duration.
Peak stagePeak_ceiling is an attenuate-only ceiling. Signals below the ceiling are not amplified.
ReproducibilityThe field generator is deterministic. For hash-based noise functions, the same settings and Random_seed reproduce the same field trajectories; the periodic bases do not depend on the seed.

Visualization

When Draw_visualization is enabled, the script draws a single diagnostic page:

Scale distinction: the 2-D map displays the raw field clipped to [-1, 1]. The Np(t) curves display the realized channel trajectories after their offset/gain calibration.