L-System Granular Pitch — User Guide
Rule-based grain scheduling for rhythmic gating and cumulative pitch transposition while preserving the detected source F0 contour.
What this does
L-System Granular Pitch converts an L-system string into a sequence of fixed-duration control windows. Each window receives a symbol, a cumulative semitone shift, and a play/skip gain. The pitch schedule is applied to the detected source F0 contour with Praat Manipulation resynthesis, then the gain schedule is applied directly to the resulting continuous Sound.
L-system → grain-indexed pitch/gain schedule → optional pitch resynthesis → continuous gating envelope → peak safety.The term grain refers here to the time grid used for L-system control. The script does not extract, reorder, repeat, or overlap separate audio fragments. Pitch remains a continuous Praat resynthesis process, and gating is applied to the continuous output Sound.
The L-system itself is deterministic: the same source, rules, iterations, and processing settings produce the same control string and schedule. There is no random generator or seed.
Quick start
- Select exactly one Sound object in Praat.
- Run
L-System_Granular_Pitch.praat. - Choose one of the eight built-in presets or Custom.
- For Custom, define the axiom, the five production rules, the iteration count, and the maximum generated-string length.
- Set the control-window length with GrainDuration_ms.
- Use GrainOverlap to smooth gain changes at grain boundaries, or disable it for hard gain steps.
- Set the play/skip gains and cumulative pitch parameters.
- Choose whether to draw the visualization and play the result.
Symbol semantics
| Symbol | Gain behavior | Pitch behavior |
|---|---|---|
| G | Played at RepeatGain | No pitch-step change |
| S | Uses BaseSkipGain | No pitch-step change |
| U | Played at RepeatGain | Adds PitchStep_semitones to this grain |
| D | Played at RepeatGain | Subtracts PitchStep_semitones from this grain |
| N | Played at RepeatGain | No pitch-step change |
RepeatGain.L-system generation
The current string begins with Axiom. At each iteration every character is replaced in parallel by its matching production rule. Characters without one of the five defined rule names pass through unchanged.
G → Rule_G
S → Rule_S
U → Rule_U
D → Rule_D
N → Rule_N
Iterations and MaxStringLength are converted to integers. String growth is capped while each new generation is being built; the script does not first create an oversized temporary generation and truncate it afterward. If the axiom is already longer than the limit, it is truncated before rewriting begins.
If the generated L-system is shorter than the required number of control grains, the final string is reused cyclically across the Sound.
Grain schedule and gating
The control-window duration is GrainDuration_ms / 1000. The number of grains is calculated with ceiling(sound_duration / grain_duration), so the last grain may be shorter and reaches the exact end of the Sound.
Cumulative pitch schedule
The running shift starts at BasePitchShift_semitones, which is first clamped to ±MaxPitchShift_semitones. For every grain, a U or D symbol updates the running shift before that grain's shift is stored. The running value is then clamped again to the same limits.
D grain: shift ← max(−MaxPitchShift, shift − PitchStep)
G / S / N: shift unchanged
Continuous gating
After pitch processing, each grain interval is multiplied by either RepeatGain or BaseSkipGain. A skip is therefore not necessarily silence: it is silence only when BaseSkipGain = 0.
GrainOverlap does not overlap audio grains. When enabled, each grain begins with a raised-cosine transition from the previous grain's gain to the current grain's gain. The transition lasts up to 12 ms, limited to at most half of the nominal grain duration and to the actual length of the final partial grain. The first grain ramps from gain 0. When GrainOverlap is disabled, gain changes are hard steps at grain boundaries.
Pitch processing
Pitch analysis uses a mono reference: multichannel input is converted to mono for analysis only. The analysis settings are fixed at a 10 ms time step, a 40 Hz floor, and a ceiling of min(1200 Hz, 0.45 × sample rate).
If usable pitch is detected, the script creates a target PitchTier on a fixed 10 ms / 100 Hz control grid. At each voiced control point it reads the detected source F0 and applies the semitone shift of the grain that contains that time:
The target is limited to 20 Hz through 0.45 × sample rate. Only times with a defined source F0 become PitchTier points. The pitch stage therefore preserves the detected source contour and transposes it according to the L-system schedule; it does not replace the source with one fixed pitch per grain.
For multichannel input, the same source-derived target PitchTier is applied independently to every original channel, and the processed channels are combined again afterward. The original channel count is preserved.
Presets
The menu contains eight built-in presets plus Custom. Presets overwrite only the fields explicitly set below; all other form values remain as entered by the user. In particular, MaxStringLength, MaxPitchShift_semitones, Draw_visualization, and Play_result are never changed by a preset.
| Preset | L-system | Audio overrides |
|---|---|---|
| Rhythmic Stutter | A=GS; G→GSS; S→SG; U→U; D→D; N→N; iter=4 | 40 ms; overlap on; skip 0; repeat 1; base shift 0 st; step 1 st |
| Pitch Walk Up | A=GU; G→GUN; S→N; U→UUN; D→N; N→G; iter=3 | 60 ms; base shift −6 st; step 1 st |
| Pitch Walk Down | A=GD; G→GDN; S→N; U→N; D→DDN; N→G; iter=3 | 60 ms; base shift +6 st; step 1 st |
| Chaotic Glitch | A=GSUD; G→GSUN; S→N; U→UD; D→DU; N→G; iter=3 | 50 ms; base shift 0 st; step 2 st |
| Melodic Arpeggio | A=GUUUDDD; G→G; S→G; U→UN; D→DN; N→N; iter=2 | 80 ms; base shift −4 st; step 2 st |
| Sparse Texture | A=S; G→GSSS; S→SSSG; U→U; D→D; N→S; iter=4 | 30 ms; skip 0.05; repeat 0.8; step 3 st |
| Dense Granular | A=G; G→GGUNG; S→G; U→UNG; D→DNG; N→NG; iter=3 | 25 ms; skip 0.2; repeat 0.9; step 1 st |
| Fibonacci Pattern | A=GU; G→GU; S→G; U→SD; D→GU; N→N; iter=5 | 45 ms; base shift −6 st; step 1 st |
| Custom | Uses all form values unchanged. | |
Parameters
L-system
| Parameter | Default | Meaning |
|---|---|---|
| Preset | Custom | Eight built-in configurations or direct use of the form values. |
| Axiom | G | Initial string. |
| Rule_G | GSUN | Replacement for G. |
| Rule_S | N | Replacement for S. |
| Rule_U | UD | Replacement for U. |
| Rule_D | DU | Replacement for D. |
| Rule_N | G | Replacement for N. |
| Iterations | 3 | Number of parallel rewriting passes; floored to an integer and must be at least 1. |
| MaxStringLength | 10000 | Maximum generated-string length; floored to an integer and must be at least 1. |
Grain-indexed gating
| Parameter | Default | Meaning |
|---|---|---|
| GrainDuration_ms | 50 ms | Duration of each L-system control window. |
| GrainOverlap | Yes | Raised-cosine gain smoothing at the start of each grain; it is not literal grain overlap. |
| BaseSkipGain | 0.0 | Linear gain applied to S grains; must be non-negative. |
| RepeatGain | 1.0 | Linear gain applied to G/U/D/N and other non-S symbols; must be non-negative. |
Pitch
| Parameter | Default | Meaning |
|---|---|---|
| BasePitchShift_semitones | 0 st | Initial cumulative transposition; clamped to ±MaxPitchShift before the first grain. |
| PitchStep_semitones | 2 st | Amount added by U or subtracted by D. The value itself may be positive, zero, or negative. |
| MaxPitchShift_semitones | 12 st | Positive symmetric limit on the cumulative schedule. |
Output
| Parameter | Default | Meaning |
|---|---|---|
| Draw_visualization | Yes | Draw the current run in the Picture window. |
| Play_result | Yes | Play the final Sound after processing. |
Output behavior
- Name:
<source>_LSystem_<preset name>, using the script's short preset label such asStutter,Walk Up,Chaotic, orCustom. - Channels: original channel count preserved.
- Duration: source duration preserved; there is no DurationTier or time-stretch stage.
- Sample rate: source sampling frequency preserved.
- Randomness: none.
- Peak handling: if the final absolute peak exceeds 0.95, the result is scaled down to 0.95. Quieter results are not boosted. This is an attenuate-only safety ceiling, not target normalization.
Visualization
When Draw_visualization is enabled, the Picture window shows:
- Original waveform and result waveform.
- L-system pattern for up to the first 200 grains. G, S, U, D, and neutral symbols use different colors; S bars are also reduced by the play/skip flag.
- Scheduled pitch-shift curve for the same grains, in semitones relative to the unshifted source. This is the L-system control schedule, not a measurement of the resynthesized output F0.
- Grammar line with the axiom, selected rules, iteration count, and final L-system length.
- Statistics with grain count, grain duration, pitch step, and maximum scheduled range.
- Summary strip describing the run and pointing to the Info window for parameters.