Need help with glitch?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

naivesound
242 Stars 14 Forks GNU General Public License v3.0 298 Commits 4 Opened issues

Description

Minimal algorithmic music composer and synthesizer

Services available

!
?

Need anything else?

Contributors list

Glitch

Build Status

Glitch is a minimal environment for creating algorithmic music and live coding.

It uses arithmetic expressions to synthesize instruments and create music patterns.

Try it online: http://naivesound.com/glitch

Download for Mac, Windows or Linux: https://github.com/naivesound/glitch/releases

Read more about Glitch on Medium: https://medium.com/@naive_sound

Build

On linux:

make alsa=1
or
make alsa=1 pulse=1
. If you want to use JACK:
make jack=1
.

On windows:

make windows=1
.

On MacOS:

make macos=1
.

Asm.js:

make js
(requires Docker).

Reference

Glitch syntax is arithmetic expressions, most likely you still remember it from the math class.

Arithmetics:

+
-
*
/
%
(modulo)
**
(power)

Bitwise:

&
|
^
(xor or bitwise not)
<<
>>

Compare:

==
!=
<
<=
>
>=
(return 1 or 0)

Grouping:

(
)
,
(separates expressions or function arguments)

Conditional:

&&
||
(short-circuit operators)

Assignment:

=
(left side must be a variable)

Instruments

| Function | Description | Example | |----------|-------------|---------| | sin(freq) | sine wave at given frequency |

sin(440)
| | tri(freq) | triangular wave at given frequency |
tri(440)
| | saw(freq) | saw-tooth wave at given frequency |
saw(440)
| | sqr(freq, [pwm=0.5]) | square wave at given frequency and (optionally) pwm |
sqr(440)
| | fm(freq, [m1, v1, m2, v2, m3, v3]) | FM-synthesizer with 3 operators, vN is operator strength, mN is operator multiplier, operators 1 and 2 are parallel, operator 3 is sequential to operator 1 |
fm(440, 0.5, 0.5)
| | tr808(drum, [vol=1], [shift=0]) | plays TR808 drum sample at given volume and pitch shift. The following drum IDs may be used: BD (bass drum), SD (snare drum), MT (middle tom), MA (maracas), RS (rimshot), CP (clap), CB (cowbell), OH (open hat), HH (hi-hat) |
tr808(BD, 1)
| | piano(freq) | very basic piano sample at the given frequency |
piano(440)
| pluck(freq, decay) | Karplus-Strong string synthesizer, fill is a function used to prepare the initial values in the delay buffer |
pluck(440, 0.7)
|

FM synthesizer, TR808 sampler and Piano are reset if any of the parameters is NAN. All instruments return NAN if the input is NAN.

All instruments return a sound wave with the given frequency in the range [-1..1], so you can combine them by adding the signals (e.g.

(sin(440)+sin(220))/2
) or modulate using multiplication, e.g.
saw(440)*sin(1)
.

You may put custom samples into the

samples
subdirectory, each group of samples should be in a separate folder. Then you could use samples providing the directory name as a function. For example if you have
samples/bass/bass0.wav
and
samples/bass/bass1.wav
you may call them as
bass(0)
and
bass(1)
respectively. Samples are expected to be in the WAV mono 16-bit format with 44100 Hz sample rate.

Sequencers:

| Function | Description | Example | |----------|-------------|---------| |a(i, ...) | array element by its index, most primitive sequencer |

sin(a(t>>10, 440, 466, 493))
| |seq(tempo, ...) | switches elements at given tempo |
sin(loop(120, 400, 466, 493))
| |loop(tempo, ...) | switches elements at given tempo, unlike seq() it evaluates each argument for each time frame which makes it possible to nest loops |
sin(loop(60, seq(240,400,466,493), seq(480, 400,493)))
|

Tempo can be a single number (beats per minute) or a pair

(offset, bpm)
, where offset is number of beats to skip before starting the sequence.

Seq and loop values can be pairs, too. Then the first value is a relative beat duration and the second is the actual returned value:

seq(120, (3/4, 1), (1/4,
1))
returns the value of "1", but the first value lasts 3 times longer than the second value.

If seq takes more values, they will be sliding from one another, e.g.

seq(120, (1, 0, 4, 2), (1, 2, 4, 0))
slides the values like
0->4->2->2->4->0
. The first value in a group is still a relative beat duration.

Seq and loop return NAN every then the value is changed.

Utils

| Function | Description | Example | |----------|-------------|---------| | r(max) | random number in the range [0..max), it sounds like white noise, good for synthesizing drums or making randomized music patterns |

r(100)
| | s(phase) | sine wave amplitude at the given phase, unline sin() you must provide phase in the range [0..1] |
s(t*14)
| | l(x) | binary logarithm, useful to convert frequencies to note values |
note=l(440)*12
| | hz(note) | note frequency of the given note index, index 0 is note A of 4th octave, you may also use helper variables like
A#4
,
C2
,
Db3
|
sin(hz(A4))
| | scale(pos, mode) | return note index at given position in given scale, scale 0 is major scale, scale 6 is minor |
sin(hz(scale(t>>11&7)))
| | env(signal, (dt, level)...) | Creates an ADSR envelope for the signal, envelope is reset if signal is NAN, if first part has non-zero level - the initial level starts from 1, otherwise from 0; if last argument is not zero - the release section is inserted automatically |
env(v, (0.1, 0.2))
| | mix(...) | mixes voices together, each parameter is a signal or a pair of (volume, signal). Signals are clipped if overflow occurs |
mix(sin(220), sin(440), tri(880))
| | lpf(voice, cutoff) | applies low-pass filter to the voice at given cutoff frequency |
lpf(v, 200)
| | hpf(voice, cutoff) | applies high-pass filter to the voice at given cutoff frequency |
hpf(v, 400)
| | bpf(voice, cutoff) | applies band-pass filter to the voice at given cutoff frequency |
bpf(v, 400)
| | bsf(voice, cutoff) | applies band-stop filter to the voice at given cutoff frequency |
bsf(v, 400)
| | delay(voice, time, level, feedback) | delays signal by given time, delay level can be controlled as well as the amount of delay feedback, which affect the number of delay repetitions |
delay(v, 0.1, 0.5, 0.2)
|

Macros

To reuse the same expression multiple times you may create a macro:

$(organ, (sin($1)+0.4*sin($1+7)+0.3*sin($1-5))/3)
(organ(hz(C4))+organ(hz(G4)))/2

Macros are definde using the

$(name, body)
function. Body can consist of multiple expressions if you extra parenthesis, e.g.
$(filter, (z=saw($1), lpf(z)))
.

There are special argument variables $1..$9 that get expanded to the actual values when the macro is called.

Special variables:

t
is time variable that increases at rate 8000/second.

x
and
y
in the web version are mouse cursor position, normalized to (0..1) range.

bpm
is a tempo, user input is synchronized with the playback at this rate, so you might want to use
bpm=120/4
to synchronize user input every 4 beats.

Polyphony

To apply the same expression to a number of variables you may use

each()
function. It takes a list of formal variables, a function, and a list of actual values:
each(f, sin(f), 440, 880, 220)
.

You may pass multiple variables as well:

each((vol, freq), vol*sin(freq), (1, 440), (0.4, 880), (0.2, 220))
.

This is useful for live MIDI input.

MIDI

Glitch provides special variables that change their values if a MIDI keyboard is used:

  • k0, k1, ..., k9 - MIDI key values (0=A4, 1=A#4 etc)
  • v0, v1, ..., v9 - MIDI velocity (it gradually fades out on key release)
  • g0, g1, ..., g9 - MIDI gate signal (it is set to NAN immediately on key release)

Here's how you can play a sine wave with a MIDI keyboard (handling up to 5 keys pressed at a time, use k5, k6 etc to get more polyphony):

each((k, v), v*sin(hz(k)),
  (k0, v0), (k1, v1), (k2, v2), (k3, v3), (k4, v4))

Special variables

x
and
y
are set to the pitch wheel and modulation wheel values if a MIDI keyboard is used.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.