Plucked strings and sound effects

A plucked string (STK’s Plucked) and retro game sound effects (sfxr).

Pluck

Pluck(polyphony=6)

A synth pluck: the short, bright, filter-snapped note of melodic techno and trance.

The analog voice with a pluck patch fixed in place: two saws a few cents apart and a square sub an octave down, through a resonant 24 dB ladder low-pass with a touch of drive. Each note opens the filter wide and snaps it shut within a couple of hundred milliseconds, while the amp envelope (no sustain) lets the note fade away on its own, so a note needs no note_off; note_off damps it in 80 ms.

lead = kiln.Pluck()
lead.decay = 0.4
lead.fx = [kiln.Delay(time=0.28, ping_pong=True), kiln.Reverb()]
for freq in (220.0, 261.6, 329.6, 440.0):   # an A minor arpeggio
    lead.note_on(freq)

It holds polyphony notes at once (6 by default): a seventh damps the oldest. With polyphony=1 every note plucks again instead of gliding. A pluck is an analog voice, so it costs one voice of the voice budget, and a six-note chord costs six of the 24. Its patch is not editable; for another sound, use Synth.

Parameters

Name Type Description Default
polyphony int Notes that ring at once, 1 to 16 (default 6). 6

Attributes

Name Type Description
decay Time for a note to fall 40 dB, seconds, 0.05 to 10 (default 0.5). The filter’s snap lengthens with it, from 80 to 450 ms.
brightness Tone, 0 (a dull, rounded blip) to 1 (a bright, biting zap); default 0.5. It sets how high the filter starts and how far it opens.
volume Output level, 0 to 1 (default 0.8).

Sfx

Sfx(polyphony=_shared.DEFAULT_POLYPHONY)

Retro game sound effects, made from about twenty numbers, as DrPetter’s sfxr makes them.

play(preset) rolls a new sound from one of sfxr’s generators, a coin, a jump, a hit, a laser, …, and plays it. A seed makes it repeatable: the same preset and seed are always the same sound, so a game can give each event its own. hit() plays the current sound again.

sfx = kiln.Sfx()
sfx.play("coin", seed=3)     # the same coin every time
sfx.play("laser")            # a new laser every time
sfx.slide = -40.0            # tweak it: fall faster, 40 octaves a second
sfx.hit()

The sound is a waveform whose pitch starts at tune, slides and wobbles, shaped by an envelope (attack, sustain with its punch, decay) and through a sweeping comb, low-pass and high-pass (kiln.sound.dsp.sfxr has the model). Each hit plays the envelope through and stops: an Sfx is a one-shot, like a drum, so a Sequencer pattern plays it at tune with no note_off. note_on(freq) plays the sound transposed to start at freq.

Every attribute below is a control: set it at any time, or use control_change(name, value). Unlike other instruments’ controls, these are queued in order with the notes: the values set before a hit are the ones it plays with, even several hits in one frame. A hit reads them once, at its start.

Parameters

Name Type Description Default
polyphony int Sounds that play at once, 1 to 16 (default 8): one more cuts the oldest short. _shared.DEFAULT_POLYPHONY

Attributes

Name Type Description
wave “square” (default), “saw”, “sine” or “noise”.
attack Seconds the level takes to rise, 0 to 5 (default 0).
sustain Seconds it holds, 0 to 5 (default 0.2).
punch How far above full the sustain starts, falling to full, 0 to 1 (default 0; 1 starts at three times).
decay Seconds it takes to fall to silence, 0 to 5 (default 0.36).
tune Starting pitch, Hz, 20 to 12000 (default 321).
min_freq A falling pitch stops the sound here, Hz, 0 to 12000 (default 0: it never stops; the pitch rests at 3.5 Hz).
slide Pitch slide, octaves per second, -700 to 700 (default 0).
delta_slide How fast the slide itself changes, octaves per second per second, -3000 to 3000 (default 0).
vibrato_depth Vibrato, semitones, 0 to 12 (default 0).
vibrato_rate Vibrato speed, Hz, 0 to 100 (default 0).
arp A pitch jump, as a multiple of the pitch, 0.05 to 20 (default 1: none; 2 jumps an octave up), after arp_time.
arp_time Seconds before the jump, 0 to 1 (default 0: none).
pulse_width The square’s duty cycle, 0 to 0.5 (default 0.5: square; 0.1 is thin and nasal).
pulse_width_sweep How fast the duty cycle moves, per second, -3 to 3 (default 0).
repeat Seconds after which the pitch, slide, duty and jump start over, 0 to 1 (default 0: never). The envelope runs on.
phaser_delay A copy of the sound this many milliseconds late is added, 0 to 2.9 (default 0: none, the sound doubled): a comb, sfxr’s “phaser”.
phaser_sweep How fast that delay moves, milliseconds per second, -125 to 125 (default 0).
cutoff Resonant low-pass cutoff, Hz, 10 to 20000 (default 20000: off).
cutoff_sweep Its sweep, octaves per second, -30 to 30 (default 0).
resonance The low-pass’s emphasis at the cutoff, 0 to 1 (default 0).
hp_cutoff High-pass cutoff, Hz, 0 to 6000 (default 0: only DC is removed).
hp_sweep Its sweep, octaves per second, -20 to 20 (default 0).
volume Output level, 0 to 1 (default 0.5).

Methods

Name Description
control_change Sets a named control, in order with the notes: the next hit plays with it.
hit Plays the current sound. The same as note_on(self.tune, velocity).
play Rolls a sound from one of sfxr’s generators, makes it the current sound, plays it.

control_change

Sfx.control_change(name, value)

Sets a named control, in order with the notes: the next hit plays with it.

Parameters
Name Type Description Default
name str A control of this instrument, such as "slide" or "volume". required
value The new value, clamped to the control’s range (or an option’s name). required
Raises
Name Type Description
ValueError name is not a control of this instrument, or value is NaN.

hit

Sfx.hit(velocity=1.0)

Plays the current sound. The same as note_on(self.tune, velocity).

Parameters
Name Type Description Default
velocity float Loudness, 0 to 1 (clamped). 1.0

play

Sfx.play(preset='random', seed=None)

Rolls a sound from one of sfxr’s generators, makes it the current sound, plays it.

Parameters
Name Type Description Default
preset str “coin”, “jump”, “hit”, “laser”, “powerup”, “blip”, “explosion”, or “random” (any sound at all, within 2 seconds). 'random'
seed int | None Any integer: the same preset and seed are always the same sound. None (the default) rolls a new one every time. None
Raises
Name Type Description
ValueError An unknown preset.