Effects

Effects for one instrument or the master bus, and the master limiter.

Effect

Effect()

A sound effect: put it in synth.fx or kiln.master.fx.

The subclasses are the effects: Delay, Reverb, Chorus, Flanger, Phaser, Drive and Bitcrush. Their attributes are parameters: set them at any time, and the sound glides to the new value over about 20 ms. Numbers outside a parameter’s range are clamped. Every effect has mix, from 0 (dry: the sound passes unchanged, bit for bit) to 1 (only the effect).

An effect is in one list at a time. It keeps its state (an echo still ringing, a reverb tail) while it stays in a list; a new effect starts silent.

Raises

Name Type Description
ImportError The “sound” extra is not installed.
RuntimeError Too many effects at once (64), or no effect memory left.

Delay

Delay(time=0.375, feedback=0.4, tone=0.6, ping_pong=False, mix=0.3)

Echoes: the sound repeats after time, each repeat feedback times quieter.

Ported from STK’s DelayL and Echo (Perry Cook and Gary Scavone). For echoes in time with a tempo, give time in beats: 60 / bpm * 0.75 is a dotted eighth. Gliding time bends the repeats, like a tape echo.

echo = kiln.Delay(time=60 / 122 * 0.75, feedback=0.45, ping_pong=True)
synth.fx = [echo]

Parameters

Name Type Description Default
time float Seconds between repeats, 0.001 to 2.5. The line holds 131,072 samples, so above 52 kHz the longest is shorter: 1.36 s at 96 kHz. 0.375
feedback float How much of each repeat comes back, 0 to 0.98. 0.4
tone float Brightness of the repeats, 0 (each repeat darker) to 1 (unchanged). 0.6
ping_pong bool True bounces the repeats between left and right. False
mix float Dry 0 to wet 1. 0.3

Reverb

Reverb(size=0.7, decay=2.0, damping=0.3, mix=0.25)

A plate reverb: the sound blooms into a room-like tail.

Jon Dattorro’s plate (1997), the classic studio-plate algorithm, not FreeVerb.

synth.fx = [kiln.Reverb(size=0.8, decay=3.0, mix=0.3)]

Parameters

Name Type Description Default
size float How big the plate is, 0 to 1: small and dense to large and spacious. 0.7
decay float Seconds the tail takes to fall by 60 dB (RT60), 0.1 to 20; within about 10 % from 1 s up. Shorter settings come out a little longer, since the plate’s own loop sets a floor (0.5 s measures about 0.64 s at size 0.7). 2.0
damping float 0 (bright tail) to 1 (highs die out quickly, a darker room). 0.3
mix float Dry 0 to wet 1. 0.25

Chorus

Chorus(rate=0.513, depth=1.0, mix=0.5)

The Roland Juno-60’s chorus: a slow shimmer that spreads the sound wide.

A bucket-brigade-style delay swept by a triangle, read in opposite phase on left and right.

Parameters

Name Type Description Default
rate float LFO speed, Hz, 0.05 to 10 (0.513 is the Juno’s mode I, 0.863 mode II). 0.513
depth float Sweep depth, 0 to 1 (1 is the Juno’s, 1.7 to 5.4 ms). 1.0
mix float Dry 0 to wet 1 (0.5, half and half, is the Juno’s). 0.5

Flanger

Flanger(rate=0.2, depth=0.7, feedback=0.5, mix=0.5)

A flanger: a jet-plane whoosh from a very short, sweeping delay.

Parameters

Name Type Description Default
rate float LFO speed, Hz, 0.01 to 10. 0.2
depth float Sweep depth, 0 to 1 (the delay sweeps from 0.3 ms up to 4.3 ms). 0.7
feedback float Resonance, -0.95 to 0.95 (negative sounds hollow). 0.5
mix float Dry 0 to wet 1 (0.5 gives the deepest notches). 0.5

Phaser

Phaser(rate=0.4, depth=0.7, feedback=0.3, mix=0.5)

A phaser: notches that sweep up and down the spectrum.

Four swept all-pass stages, as in the MXR Phase 90.

Parameters

Name Type Description Default
rate float LFO speed, Hz, 0.01 to 10. 0.4
depth float Sweep width, 0 to 1 (1 sweeps 3 octaves either side of 700 Hz). 0.7
feedback float Resonance, -0.9 to 0.9. 0.3
mix float Dry 0 to wet 1 (0.5 gives the deepest notches). 0.5

Drive

Drive(drive=0.5, mix=1.0)

Saturation: from warm to fuzzy, adding odd harmonics.

A tanh waveshaper, oversampled four times and anti-aliased, so loud driven highs do not fold back as grit.

Parameters

Name Type Description Default
drive float 0 (gentle) to 1 (36 dB into the curve: fuzz). 0.5
mix float Dry 0 to wet 1. 1.0

Bitcrush

Bitcrush(bits=8.0, rate=11025.0, mix=1.0)

Lo-fi: fewer bits and a lower sample rate, like old samplers and game consoles.

Parameters

Name Type Description Default
bits float Bit depth, 1 to 16 (4 bits is 16 levels); fractions blend smoothly. 8.0
rate float Sample rate it holds the sound at, Hz, 100 to 48000 (no filter: it aliases). 11025.0
mix float Dry 0 to wet 1. 1.0

Instrument.fx

Instrument.fx

This instrument’s effects, in order (a copy: assign a list to change them).

Instrument.pan

Instrument.pan

Instrument.bind

Instrument.bind(name, param)

Makes a control follow a kiln.Gui Parameter.

The control takes the Parameter’s value now, then follows it: every slider move, and every preset load, reaches the sound through the control’s usual write, so it glides over the same few milliseconds as a write from code. A choice Parameter drives a control that picks an option (a Synth’s osc1_wave or filter_type); a number Parameter (a slider or a knob) drives a numeric control, clamped to the control’s range. Binding a control again replaces its earlier binding.

Bind once, for example in setup(), not every frame. Binding again, or unbind, removes the earlier listener from the Parameter, so none pile up.

The binding lasts as long as the Parameter and this object do: when this object goes away the Parameter is let go. unbind ends it sooner. Hiding a panel does not: its Parameters keep working.

Parameters

Name Type Description Default
name str A control of this object, such as "cutoff". required
param A Parameter from Gui.slider, Gui.choice and the like. required

Raises

Name Type Description
ValueError name is not a control, or a choice Parameter offers an option the control doesn’t have (checked for every option, so a later move or preset load can’t fail).
TypeError The Parameter’s kind doesn’t fit the control (an xy pad on a numeric control, a slider on a waveform choice).

Instrument.unbind

Instrument.unbind(name)

Stops a control following its Parameter; it keeps its last value (no-op if unbound).

Effect.bind

Effect.bind(name, param)

Makes a control follow a kiln.Gui Parameter.

The control takes the Parameter’s value now, then follows it: every slider move, and every preset load, reaches the sound through the control’s usual write, so it glides over the same few milliseconds as a write from code. A choice Parameter drives a control that picks an option (a Synth’s osc1_wave or filter_type); a number Parameter (a slider or a knob) drives a numeric control, clamped to the control’s range. Binding a control again replaces its earlier binding.

Bind once, for example in setup(), not every frame. Binding again, or unbind, removes the earlier listener from the Parameter, so none pile up.

The binding lasts as long as the Parameter and this object do: when this object goes away the Parameter is let go. unbind ends it sooner. Hiding a panel does not: its Parameters keep working.

Parameters

Name Type Description Default
name str A control of this object, such as "cutoff". required
param A Parameter from Gui.slider, Gui.choice and the like. required

Raises

Name Type Description
ValueError name is not a control, or a choice Parameter offers an option the control doesn’t have (checked for every option, so a later move or preset load can’t fail).
TypeError The Parameter’s kind doesn’t fit the control (an xy pad on a numeric control, a slider on a waveform choice).

Effect.unbind

Effect.unbind(name)

Stops a control following its Parameter; it keeps its last value (no-op if unbound).

Limiter

Limiter()

The master limiter: always on, it keeps the output at or under ceiling.

A lookahead brickwall limiter on the master bus, after kiln.master.fx. It sees each peak lookahead seconds before it plays and turns the gain down smoothly just enough, so no sample goes over the ceiling and nothing clips; below the ceiling it changes nothing. The price is lookahead seconds of latency (2 ms by default). Reach it as kiln.master.limiter.

Attributes

Name Type Description
ceiling float The highest output level, dBFS, -40 to 0 (default -1).
release float How fast the gain comes back after a peak, seconds, 0.05 to 2 (default 0.1). It starts 20 ms after the peak, so a held note or chord is turned down evenly, without distortion.
lookahead float How far ahead it looks, seconds, 0 to 0.005 (default 0.002). It is also the latency it adds; changing it restarts the limiter (a click).
reduction float The most the limiter has turned the gain down since you last read it, dB (0 or negative); reading it starts over, so read it once a frame for a meter. Read-only.

Master

Master()

The master bus: everything you hear passes through it.

Reach it as kiln.master.

kiln.master.fx = [kiln.Reverb(mix=0.2)]   # every instrument, one room
kiln.master.limiter.ceiling = -3.0
kiln.master.gain = 12                     # push the mix into the limiter
kiln.master.volume = 0.5                  # half as loud at the speakers
size = 100 * kiln.master.level()          # how loud it is now, 0 to 1

level(), spectrum() and waveform() read the mix back to drive visuals; kiln.mic reads the microphone the same way.

Attributes

Name Type Description
fx list The effects every instrument goes through, in order (a list; empty by default). Assign a new list to change them: effects that leave fade out and new ones fade in, over 20 ms, so it never clicks. When a sketch’s window closes, the list is emptied.
gain float Gain in dB applied to the whole mix just before the limiter, -24 to +24 (default 0). Raise it to push a mix into the limiter, which holds the peaks at its ceiling. It glides over 20 ms, so changing it never clicks.
limiter The always-on output Limiter.
volume float The level sent to the speakers, 0 (mute) to 1 (full, the default), after the limiter. The analysis is taken before it, so muting does not blank level(), spectrum() or waveform().

When a sketch’s window closes, fx, gain, volume and the limiter’s settings go back to their defaults, so every run starts from the same sound. Set them in setup (or before kiln.run, for the first run).

master

master