Find your inner bassoon

The voice is a buzzy oscillator, an attack splat, and a fluttering decay. Knobs scale the existing onset classes rather than replacing their character.

Tune the voice

./zig-out/bin/kujamba render --phrase "kujamba karibu" --out shout.wav \
  --voice "intensity=2.5"
./zig-out/bin/kujamba render --phrase "kujamba karibu" --out low.wav \
  --voice "cents=-1200,noise=0.4,wobble=0.5"
Knob What it changes Default
attack Multiplier on each onset's attack time 1
noise Multiplier on attack noise mix 1
wobble Multiplier on flutter depth, not its rate 1
intensity Effort: level, noise, and stress emphasis 1
cents Vowel pitch offset; 100 cents is one semitone 0

Applied attack time is clamped to 0.5–200 ms; applied noise and wobble depth are clamped to 0–1. Effort is clamped to 0.25–4 and pitch to ±1200 cents. These are effective synthesis bounds, not all bounds on the raw multipliers. Silence and invalid floating-point audio are not useful presets.

intensity=0.4 whispers; intensity=2.5 shouts. Effort changes the penultimate syllable's stress emphasis too. cents=-1200 lowers vowels one octave but does not transpose the randomly pitched, wordless shuzi rumble.

Defaults are an identity. A preset spelling out every default reproduces the untuned voice in the same build.

Pick a different engine entirely

The knobs above belong to stock, the shipped engine. The M9 fart-off (#95) landed nine more engines, each with its own knob vocabulary — intestinal pressure, sphincter tension, tract resonance, turbulence, and engine-specific extras like swe2's wet/drop or opus's droop:

./zig-out/bin/kujamba render --engine swe2 \
  --voice "wet=1.3,drop=1.6" --phrase "kujamba karibu" --out swe2.wav

engine=<slug> inside --voice selects the engine too; an explicit --engine flag wins over that, and both win over a config file's engine = "<slug>". A knob the engine doesn't know is rejected with that engine's knob list. stock stays the default until the fart-off judging picks a winner.

Map a phrase onto bars

Mode On a play bar
repeat Start at sample zero again
loop Continue the cursor, wrapping at phrase end
once Continue one pass, then output silence

Rest bars freeze the cursor. --pattern N plays continuously in a pattern of N play bars; --pattern N+M adds M rest bars. 3+1 is the room default; offline render/play default to 1.

./zig-out/bin/kujamba render --phrase "habari yako" --out pattern.wav \
  --play loop --pattern 3+1 --bars 4 --bar-ms 500

In an offline file, silence takes up the rest bar's duration. In a room, a rest uses a NINJAM silence marker. Neither silently removes time.

The synth already reaches zero at both phrase ends. Do not add a loop crossfade merely because another instrument has one: the measured blend made this loop less seamless, and regression tests preserve that finding.

For the actual synthesis tables, see Synth internals.