Listen

Each sound on this page is computed by the code above it, when the documentation is built, and played as that code returns it: written losslessly, as FLAC, and brought to one loudness, so that no clip is louder than the next only because of what it is. Each block leaves its sound in sound, which music.play_audio() plays and music.write_audio() writes, in one channel or two.

In a notebook, IPython.display.Audio(sound, rate=music.get_sample_rate()) plays it in the page. Every block here is in a notebook that runs in Google Colab, with nothing to install.

Two of these are for headphones, and say so; one is high, and says that.

A scale, joined without clicks

Thirteen notes of the chromatic scale. Each note ends wherever its phase happens to be, so notes joined raw would click; the envelope takes each to silence at both ends first.

import music

notes = [music.note(440 * 2 ** (i / 12), duration=0.25)
         for i in range(13)]
sound = music.horizontal_stack(*[music.adsr(sonic_vector=note)
                                 for note in notes])

A vibrato, and a glide under it

The pitch moves at every sample, inside the wavetable lookup, rather than being bent afterwards: half a semitone each way, six times a second, on a held note and then on a glide up an octave.

import music

held = music.note_with_vibrato(220, duration=2, vibrato_freq=6,
                               max_pitch_dev=0.5)
glide = music.note_with_glissando_vibrato(220, 440, duration=2,
                                          vibrato_freq=6,
                                          max_pitch_dev=0.5)
sound = music.horizontal_stack(music.adsr(sonic_vector=held),
                               music.adsr(sonic_vector=glide))

A sawtooth that folds, and one that does not

High: turn the volume down first. A sawtooth at 10 kHz read from a table, as MASS reads it, and then the same note band-limited. The first has partials above the Nyquist frequency, folded back into the band between its own harmonics, where they sound as tones the note does not have; the second has none. Band-limited synthesis measures both.

import music

folded = music.note(10000, duration=1.5,
                    waveform_table=music.waveform_table("sawtooth"))
clean = music.bandlimited_note(10000, duration=1.5, waveform="sawtooth")
sound = music.horizontal_stack(music.adsr(sonic_vector=folded),
                               music.silence(duration=0.5),
                               music.adsr(sonic_vector=clean))

Noise, by colour

Brown, pink, white, blue and violet: each colour is a slope, in decibels per octave, from -6 for brown to +6 for violet. A seed draws the same noise again.

import music

colours = ("brown", "pink", "white", "blue", "violet")
sound = music.horizontal_stack(*[
    music.adsr(sonic_vector=music.noise(colour, duration=0.6, seed=1))
    for colour in colours])

A low pass, opening

White noise through a low pass whose cutoff doubles six times, from 125 Hz to 8 kHz. A cutoff is a fraction of the sample rate, which music.fraction_of() converts hertz to, so the same coefficients describe the same filter at any rate.

import music

noise = music.noise("white", duration=0.5, seed=2)
steps = [music.iir(noise, *music.low_pass(music.fraction_of(cutoff)))
         for cutoff in (125, 250, 500, 1000, 2000, 4000, 8000)]
sound = music.horizontal_stack(*[music.adsr(sonic_vector=step)
                                 for step in steps])

A mode, and a cadence

The theory is counted in semitones from a tonic of zero, so a scale or a chord becomes frequencies in one step. The dorian mode up from A, and then I, vi, IV and V7 in A major.

import music

dorian = music.pitch_to_freq(220.0, music.scale("dorian") + (12,))
line = [music.adsr(sonic_vector=music.note(freq, duration=0.3))
        for freq in dorian]
chords = [music.chord("major"), music.chord("minor", root=9),
          music.chord("major", root=5),
          music.chord("dominant seventh", root=7)]
cadence = [music.adsr(sonic_vector=music.mix_many(
               [music.note(freq, duration=1)
                for freq in music.pitch_to_freq(220.0, chord)]))
           for chord in chords]
sound = music.horizontal_stack(*line, music.silence(duration=0.4),
                               *cadence)

A vibrato bound to the pitch

music.Bonds decides once how a line’s notes behave, rather than note by note: here the vibrato quickens as the line rises, and its depth narrows.

import music

voice = music.Bonds(vibrato_freq=music.proportional(1 / 40),
                    max_pitch_dev=music.inversely_proportional(400))
sound = voice.render([220, 277, 330, 440, 330, 277, 220], duration=0.5)

Plain changes on four bells

Four bells, tuned to the first four notes of E major and rung from the highest, in every order once: the permutations act on the bells’ frequencies, so the peal is the melody. It needs pip install 'music[structures]'.

import music

bells = [440.0, 415.3, 369.99, 329.63]
rows = music.PlainChanges(4).act(bells)
sound = music.horizontal_stack(*[
    music.adsr(sonic_vector=music.note(freq, duration=0.16))
    for row in rows for freq in row])

A source passing by

Headphones. Pink noise moving from one side to the other, its interaural time and intensity differences computed at every sample from where it is.

import music

source = music.adsr(sonic_vector=music.noise("pink", duration=3, seed=3))
sound = music.localize_linear(source, theta1=150, theta2=30, dist=0.6)

A binaural beat

Headphones. 197 Hz in one ear and 203 Hz in the other. Neither ear hears a beat; the 6 Hz one arises where their signals meet, in the listener. Each of the package’s stimuli is named for the SSTIM technique it implements, and Stimuli in SSTIM writes them as descriptions.

import music

beat = music.binaural_beats(carrier_freq=200, beat_freq=6, duration=8)
sound = music.adsr(sonic_vector=beat, attack_ms=500, release_ms=500)

A session, crossfaded

Stimuli are delivered as a protocol, one phase after another. A music.StimulationSession plays its phases in order, crossfaded rather than cut, and lasts exactly as long as the durations written down: isochronic tones, and then pink noise modulated at the same rate.

import music

session = music.StimulationSession(end_ramp=0.5)
session.add(music.isochronic_tones, duration=5, carrier_freq=300,
            pulse_rate=4, ramp_duration=0.01)
session.add(music.modulated_noise, duration=5, ramp=1,
            noise_type="pink", modulation_freq=4, seed=1)
sound = session.render()

A line, sung

One syllable a note: espeak-ng says each syllable, and Praat’s pitch-synchronous overlap-add holds it at its note’s pitch and length, with a vibrato on the long note. It needs espeak-ng and pip install 'music[singing]'.

import music

sound = music.sing(text="Twin-kle, twin-kle, lit-tle star",
                   notes=(0, 0, 7, 7, 9, 9, 7),
                   durs=(1, 1, 1, 1, 1, 1, 2))