Rich Formant Grains — User Guide
Multi-bank source–filter granular synthesis. A fixed number of randomly placed grains generate harmonic/noise excitation, each grain is assigned to one of fifteen F1–F3 resonance buses, the filtered buses are RMS-matched and summed, and the result is optionally spatialized and level-managed.
What this does
Rich Formant Grains is a source–filter granular generator. It does not synthesize F1, F2, and F3 as oscillators. Instead, each grain first creates a broadband harmonic/noise excitation, and that excitation is then passed through a three-formant resonant filter bank.
The complete process is:
fixed-count grain plan
→ harmonic/noise excitation × half-sine grain window
→ one of 15 F1–F3 resonance buses
→ per-bus RMS compensation
→ sum of all buses
→ edge fades
→ spatial mode
→ selected level mode
Quick start
- Run
Rich_Formant_Grains.praat. No input Sound is required. - Choose Custom or one of the eight presets.
- Set Duration, Grain density, Base frequency, Breath noise mix, and Spatial mode.
- Enable Edit details to change sample rate, harmonic count, formant bandwidths, grain-duration range, level mode, output peak/ceiling, and random seed.
- Run the script. The complete stochastic grain plan is generated first, then rendered through the fifteen resonance buses.
Grain plan
Grain density does not drive a Poisson process. The script first fixes the number of grains:
totalGrains = round(Duration × GrainDensity) realizedDensity = totalGrains / Duration
Because the count is rounded to an integer, the realized density can differ slightly from the requested density.
Duration and onset
Each grain duration is drawn uniformly between Minimum grain duration and Maximum grain duration, after both limits are capped by the total output duration.
Duration is drawn before onset. Onset is then chosen uniformly from:
0 … Duration - grainDuration
Consequently every grain fits completely inside the output. There is no end-of-file truncation of randomly placed grains.
Grain onsets are independent and can overlap freely. With high density or long grains, substantial temporal overlap is expected.
Vowel and resonance-bus assignment
Five vowel templates are available: a, i, u, e, o. Each vowel has three resonance variants, giving fifteen buses in total.
For most presets the vowel is chosen uniformly from the five templates. Whisper Choir and Gregorian Chant use a weighted population of a/u/o = 40%/30%/30%. Ghost Voices chooses only i or u with equal probability.
After the vowel is chosen, one of its three resonance variants is selected uniformly for that grain.
Excitation source
Each grain receives an F0 drawn independently from:
grainF0 = BaseFrequency × U(0.90, 1.10)
Thus Base frequency is the center of a ±10% F0 spread. Base frequency may also be set to 0, in which case the excitation is noise-only.
Harmonic component
For nonzero F0, the harmonic source sums integer harmonics up to the user-selected Source harmonics limit, additionally truncated so that harmonic frequencies remain below Nyquist − 100 Hz:
harmonic amplitude ∝ 1 / h^0.85
Every grain resets the harmonic phases at its own onset because each sinusoid uses local grain time.
Breath-noise mixture
The excitation before windowing is:
(1 - n) × harmonicSource + n × GaussianNoise
where n is Breath noise mix in the range 0–1. At 1.0 the source is pure Gaussian noise.
Grain window and amplitude
Each grain is multiplied by a half-sine window:
w(τ) = sin(π τ / D), 0 ≤ τ ≤ D
The window starts and ends at zero. The grain amplitude also includes a small random factor of 0.85–1.15 and an inverse-square-root density compensation:
grainAmp = ampShape × 0.40 / sqrt(max(12, density)) × U(0.85,1.15)
The preset-specific ampShape is 1.0 except Whisper Choir = 0.8, Robotic Speech = 1.2, and Ghost Voices = 0.7.
F1–F3 resonance banks
The five base resonance templates are:
| Template | F1 | F2 | F3 |
|---|---|---|---|
| a | 730 Hz | 1090 Hz | 2440 Hz |
| i | 270 Hz | 2290 Hz | 3010 Hz |
| u | 300 Hz | 870 Hz | 2240 Hz |
| e | 530 Hz | 1840 Hz | 2480 Hz |
| o | 570 Hz | 840 Hz | 2410 Hz |
Three variants per vowel
For ordinary presets, each vowel receives three nearby fixed variants. Variant 2 uses the base values; variants 1 and 3 apply small downward/upward multipliers, with progressively smaller spread from F1 to F3.
Alien Language is different: its three variants are randomly generated at the start of each run from much wider independent multiplicative ranges. Once created, those fifteen bus resonances remain fixed for that realization.
Bandwidths
Nominal bandwidths are:
F1 BW = 90 × bandwidthScale F2 BW = 130 × bandwidthScale F3 BW = 180 × bandwidthScale
The resonance frequencies are kept ordered and constrained below Nyquist.
Filtering and RMS compensation
Each of the fifteen excitation buses is filtered by a Praat FormantGrid with three constant resonances. Filtering uses Filter (no scale).
After filtering, each bus is multiplied by one scalar gain so that its output RMS matches its pre-filter source RMS:
busGain = sourceRMS / filteredRMS
This compensation prevents the raw gain of the all-pole formant filter from becoming an unintended dynamic control. It does not flatten the formant spectrum; the spectral shaping remains.
Spatial modes
| Mode | Behavior |
|---|---|
| Mono | The fifteen filtered buses are summed to one mono output. |
| Stereo Spectral Split | Left uses a Hann pass band from 0 to min(2500 Hz, Nyquist−100); right uses 150 Hz to min(4000 Hz, Nyquist−100). The two filtered copies become stereo. |
| Rotating Field | Two copies use complementary square-root gains derived from 0.5 ± 0.5 cos(2π·0.12t), giving a constant-power left/right rotation at 0.12 Hz. |
| Dual-Band Whisper | Left: 100–min(3000, Nyquist−100) Hz with gain 0.8 + 0.1 sin(2π·0.2t). Right: 80–min(3500, Nyquist−100) Hz with gain 0.7 + 0.2 cos(2π·0.25t). |
The three stereo modes are created from the already summed mono source–filter result; individual grains are not independently panned.
Level modes
After spatial processing the script measures the pre-level peak and RMS, then applies one of three modes:
| Mode | Operation |
|---|---|
| 1 — Natural | No final peak scaling. Generated level is preserved. |
| 2 — Ceiling | If peak exceeds Output peak / ceiling, the complete output is scaled down once to that value. Signals already below the ceiling are unchanged. |
| 3 — Normalize | Every non-silent output is peak-normalized to Output peak / ceiling, including upward scaling when needed. |
Controls
Main page
| Control | Default | Meaning |
|---|---|---|
| Preset | Custom | Custom plus eight complete source/filter texture configurations. |
| Duration | 5.0 s | Final output duration. |
| Grain density | 35 /s | Target density used to compute the fixed grain count. |
| Base frequency | 120 Hz | Center of the ±10% per-grain excitation-F0 distribution; 0 selects noise-only excitation. |
| Breath noise mix | 0.05 | Linear harmonic/noise mixture, 0–1. |
| Spatial mode | Mono | Mono, Stereo Spectral Split, Rotating Field, or Dual-Band Whisper. |
| Edit details | off | Opens synthesis, level, and reproducibility controls. |
Details page
| Control | Default | Meaning |
|---|---|---|
| Sample rate | 44100 Hz | Direct synthesis and final output rate. |
| Source harmonics | 16 | Maximum harmonic count before the Nyquist−100 Hz truncation; valid range 1–40. |
| Formant bandwidth scale | 1.0 | Common multiplier for the three nominal resonance bandwidths. |
| Minimum grain duration | .04 s | Lower bound of the uniform duration distribution. |
| Maximum grain duration | .12 s | Upper bound of the uniform duration distribution. |
| Output mode | 2 | 1 Natural, 2 Ceiling, 3 Normalize. |
| Output peak / ceiling | .90 | Threshold for Ceiling mode or target for Normalize mode. |
| Random seed | 0 | 0 = unpredictable; positive = reproducible realization. |
Presets
Presets override Grain density, Base frequency, Source harmonics, Breath noise mix, Formant bandwidth scale, grain-duration range, and in some cases the internal amplitude-shape factor. They do not override Duration, Spatial mode, Sample rate, Output mode, Output peak/ceiling, or Random seed.
| Preset | Density | Base / harmonics | Noise | BW scale | Grain range |
|---|---|---|---|---|---|
| Vowel Cloud | 25/s | 110 Hz / 16 | .05 | 1.00 | .045–.13 s |
| Whisper Choir | 15/s | 180 Hz / 12 | 1.00 | 1.35 | .08–.23 s |
| Robotic Speech | 40/s | 80 Hz / 20 | .01 | .60 | .03–.08 s |
| Alien Language | 30/s | 140 Hz / 18 | .08 | .78 | .04–.12 s |
| Gregorian Chant | 20/s | 90 Hz / 20 | .025 | .92 | .10–.30 s |
| Baby Babble | 45/s | 250 Hz / 12 | .04 | .78 | .02–.06 s |
| Synthetic Singing | 28/s | 130 Hz / 24 | .015 | .82 | .07–.18 s |
| Ghost Voices | 12/s | 160 Hz / 14 | .18 | 1.20 | .12–.37 s |
The preset names describe intended timbral directions only; they are not analyses or models of actual speech, chant, infant vocalization, or language.
Sampling and safety
Sample rate must be at least 8000 Hz, and the minimum grain duration must span at least eight samples.
If Base frequency is above zero, the upper edge of its +10% F0 spread must remain below Nyquist − 100 Hz. Individual harmonic counts are additionally truncated to the same safety margin.
All F1–F3 resonance variants are kept ordered and constrained below Nyquist. At low sample rates this can alter the programmed template values to keep the filters valid.
Runtime guard
Version 1.1.1 limits the fixed grain plan to:
maximum grains = 12,000
If round(Duration × GrainDensity) exceeds this limit, the script stops before allocating the grain plan or beginning synthesis.
Randomness and reproducibility
Random choices include grain duration, onset, vowel selection, resonance variant, per-grain F0, amplitude variation, Gaussian excitation noise, and the wide resonance variants used by Alien Language.
Random seed = 0 initializes Praat unpredictably. A positive seed makes the realization repeatable for the same settings.
The script consumes one random integer for an internal temporary-object identifier after seeding; this consumption is deterministic under a fixed seed, so repeatability is preserved.
After a fixed-seed run, Praat's global RNG is restored to an unpredictable state.
Visualization and QC
| Panel | What it shows |
|---|---|
| A — Grain plan | Actual onset and duration of every grain, arranged by vowel. The three small vertical offsets within each vowel row indicate the resonance variant. |
| B — One realized grain | Left: the half-sine grain window. Right: the analytical harmonic/noise excitation model for one representative grain. |
| C — Source–filter stage | Left: a measured impulse-probe response of one actual FormantGrid bus, normalized to its own maximum and plotted over log frequency. Right: the actual rule used by the selected spatial mode. |
| D — Measured output | Final mono or stereo waveform after spatial processing and level handling. The amplitude scale is fixed at −1…1. |
The QC summary reports grain count, requested/realized density, duration mean/range, mean source F0, noise mix, mean F1/F2/F3, spatial mode, level mode, Nyquist frequency, final peak/RMS, and pre-level peak.
Output
| Property | Behavior |
|---|---|
| Input | No input Sound required. |
| Duration | Exactly the requested Duration. |
| Sample rate | Exactly the Details-page Sample rate. |
| Channels | Mono in Mono mode; stereo in all three spatial modes. |
| Overall fades | Linear fade-in up to 30 ms and fade-out up to 50 ms, each capped at one quarter of the total Duration. |
| Object name | RichFormant_<preset name>. |