music

Extreme-fidelity synthesis of musical elements.

music generates and manipulates music and sound in LPCM audio. It implements the MASS framework — Music and Audio in Sample Sequences — a collection of psychophysical descriptions of musical elements expressed as equations and corresponding Python routines.

import music

notes = [music.note(440 * 2 ** (i / 12), duration=0.4) for i in range(12)]
scale = [music.adsr(sonic_vector=note) for note in notes]
music.write_wav_mono(music.horizontal_stack(*scale), "chromatic.wav")

The envelope brings each note to silence at its ends so that joining different pitches does not introduce a click.

New here? The Tutorial walks from a single note to a short stereo piece, and explains what the sample-by-sample model actually buys you. Choosing the smallest API maps common tasks onto the few routines to start with, Band-limited synthesis renders without the folding a wavetable read brings, and Stimuli in SSTIM writes stimuli as SSTIM descriptions and renders them back.

What it does

  • Synthesis of notes and their variation, sample by sample: vibrato, glissando, FM and AM, Doppler, ADSR envelopes, tremolo, and noise of six colours.

  • Band-limited synthesis, when asked for: notes whose partials stop short of the Nyquist frequency, oscillators for a pitch that moves, and any generator rendered at several times the rate and filtered.

  • Filters: IIR and FIR, reverberation, loudness transitions, and the four filter designs the MASS article specifies.

  • Spatial audio: interaural time and intensity differences computed at every sample, a source moving in a line or around the head, and measured head-related transfer functions.

  • Music theory: the diatonic modes, the minor scales, triads and tetrads, intervals and their names, the harmonic series.

  • Musical structures: permutation groups, change-ringing peals and plain changes.

  • Bonds that tie a note’s vibrato and tremolo to its pitch, once, for a whole piece.

  • Sensory stimulation: seven auditory stimuli named for the SSTIM techniques they implement, and sessions that sequence them, each of which can be written as an SSTIM description and rendered back.

  • Singing: a lyric sung to a melody by speech synthesis and PSOLA, with a vibrato on long notes and accents on the beats, and the eCantorix engine as a second backend that sings the same score.

  • Input and output: reading, writing and playing audio, mono and stereo, and a sequencer that schedules notes into a timeline.

What makes it precise

Sample-based synthesis. State is updated at every sample. A note with a vibrato has a different instantaneous frequency at each of its samples, and the vibrato pattern is folded into the wavetable lookup rather than applied afterwards — so the rendered sound is as close as it can be to the mathematical model that describes it.

Musical structures, with an emphasis on symmetry and discourse: permutation groups, change-ringing peals and plain changes.

Every routine’s docstring carries the equation it implements and cites the article it comes from. If you use this package, please cite:

Fabbri, Renato, et al. Musical elements in the discrete-time representation of sound. arXiv preprint arXiv:1412.6853 (2017).

Install

pip install music

Or from a checkout, which is convenient for hacking and debugging:

git clone https://github.com/ttm/music.git
pip install -e music

Requires Python 3.10 or newer.

PrimaryTables.draw_tables plots the waveform tables and is the one thing that needs matplotlib, which is an extra:

pip install 'music[plot]'

Nothing else in the package uses it, and leaving it out makes import music about 40% faster.

music.sing() sings with espeak-ng, a system program, and Praat, through praat-parselmouth, which the singing extra installs:

sudo apt install espeak-ng        # or: brew install espeak-ng
pip install 'music[singing]'

Its second backend, eCantorix, is a Perl program the package clones; the API reference says what it needs.

music.render_oversampled() needs SciPy, and the SSTIM modules need RDFLib and SSTIM’s own validator:

pip install 'music[antialias]'
pip install 'music[sstim]'

Where things live

Module

What it holds

core.synths

Notes with vibrato, glissando, FM and Doppler; envelopes; noises; band-limited notes and oscillators

core.filters

ADSR, fades, FIR/IIR, reverb, loudness, stereo localization

core.io

Reading, writing and playing audio, mono and stereo

structures

Permutations, algebraic groups, change-ringing peals

sequencer

Scheduling notes into a timeline and rendering them

utils

Conversions, mixing, stacking, rhythm

theory

Scales, modes, chords, intervals and the harmonic series

bonds

Vibrato and tremolo tied to a note’s pitch

hrtf

The KEMAR measurements, fetched and read by direction

stimulation

Binaural, monaural and isochronic beats, modulations, sessions, and their SSTIM descriptions

singing

sing, with the PSOLA singer and the eCantorix engine

tables

Waveform lookup tables

legacy

The Being and IteratorSynth synthesizer classes

The whole public API is re-exported flat from the top level, so music.note(...) works regardless of which submodule defines it.