Music
Extreme-fidelity synthesis of musical elements.
Music generates and manipulates sound in LPCM audio, sample by sample. It implements MASS (Music and Audio in Sample Sequences), a collection of psychophysical descriptions of musical elements expressed as equations and corresponding Python routines.
import music
# a chromatic scale, written to a WAV file
scale = [music.note(440 * 2 ** (i / 12), duration=0.25) for i in range(13)]
music.write_wav_mono(music.horizontal_stack(*scale), "scale.wav")
📖 Tutorial — from a single note to a short stereo piece. 📖 API reference — every routine documented with the equation it implements and the article it comes from.
Core features
- 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.
play_audioto listen to a result without saving a file.
Music can be used alone or with other packages, and it is well suited to the audiovisualization of data. It works with Percolation and Participation for harnessing open linked social data, and with the audiovisual analytics vocabulary and ontology (AAVO).
To understand the routines further, read Musical elements in the discrete-time representation of sound. If you use this package, please cite that article.
Every release is archived on Zenodo, so a specific version can be cited too: 10.5281/zenodo.22151793 always resolves to the newest one. GitHub's Cite this repository button reads CITATION.cff and gives you both, formatted.
How to install
pip install music
Requires Python 3.10 or newer. Everything needed to synthesise, filter and write audio comes with it; the dependencies are declared in pyproject.toml.
One thing is optional. PrimaryTables.draw_tables(), which plots the waveform
tables so you can look at them, needs matplotlib:
pip install 'music[plot]'
Nothing else in the package uses it, and leaving it out makes import music
about 40% faster.
To hack on it, install from a checkout so your edits take effect immediately:
git clone https://github.com/ttm/music.git
pip install -e music
A closer look
Every routine returns a numpy array of PCM samples, so results compose with each other and with anything else you can express in numpy.
Notes and envelopes
note = music.note_with_vibrato(freq=220, duration=2,
vibrato_freq=6, max_pitch_dev=0.5)
shaped = music.adsr(sonic_vector=note, attack_duration=80,
sustain_level=-6, release_duration=200)
Durations are in seconds, envelope stages in milliseconds, levels in decibels and pitch deviations in semitones — each parameter in the unit it is usually thought about in.
Change ringing
Permutation groups and the peals of campanology, acted on any domain you like — here on frequencies, so the peal is the melody:
peal = music.PlainChanges(4) # every permutation, once
rows = peal.act([220, 275, 330, 440])
notes = [music.note(freq, duration=0.2) for row in rows for freq in row]
music.write_wav_mono(music.horizontal_stack(*notes), "campanology.wav")
Spatialisation
A source moving from one side to the other, its interaural time and intensity differences computed at every sample from its position:
passing = music.localize_linear(music.note(330, duration=3),
theta1=150, theta2=30, dist=0.6)
music.write_wav_stereo(passing, "passing.wav")
Sequencing
seq = music.Sequencer()
for i, freq in enumerate([440, 550, 660]):
seq.add_note(freq, start=i * 0.25, duration=1.0,
adsr_params={"attack_duration": 20, "release_duration": 400})
seq.write("chord.wav")
Noise
Six colours, each defined by its gain per octave — brown at −6 dB, pink at −3, white at 0, blue at +3, violet at +6, black at −12 — or any number you pass instead:
colours = [music.noise(kind, duration=0.5)
for kind in ("brown", "pink", "white", "blue", "violet")]
music.write_wav_mono(music.horizontal_stack(*colours), "colours.wav")
Examples
Inside the examples folder you can find some scripts that use the main features of Music.
- chromatic_scale: writes twelve notes into a WAV file from a sequence of frequencies.
- penta_effects: writes a pentatonic scale repeated once clean, once with pitch, one with vibrato, one with Doppler, and one with FM, into a WAV stereo file.
- noisy: writes into a WAV file a sequence of different noises.
- thirty_notes and thirty_numpy_notes generate a sequence of sounds by using a synth class (in this case the class
Being). - campanology and geometric_music both use
Beingas their synth, but this time with permutations. - isynth also uses a synth class, but of a different kind,
IteratorSynth, that iterates through arbitrary lists of variables. - singing_demo: demonstrates
music.singing.setup_engine()andmusic.singing.make_test_song()to render a short sung phrase. - binaural_beats: generates binaural beats using two pure tones with tremolo for relaxation or focus.
- The
music.singingmodule provides basic text-to-speech utilities. Runmusic.singing.setup_engine()once to clone the eCantorix engine before using these features. It is cloned into your user cache directory; setMUSIC_ECANTORIX_DIRto put it elsewhere. Because eCantorix is a Perl program driving espeak through a Makefile, it also needsgit,make,perlandespeakinstalled on the system —setup_engine()will tell you which are missing.
Package structure
The modules are:
- core:
- synths for synthesization of notes (including vibratos, glissandos, etc.), noises and envelopes.
- filters for the application of filters such as ADSR envelopes, fades, IIR and FIR, reverb, loudness, and localization.
- io for reading, writing and playing audio, both mono and stereo.
- functions for normalization.
- structures for higher level musical structures: permutations and the algebraic groups they form, change-ringing peals, and symmetry. Scales, chords, counterpoint and tunings are not there yet.
- legacy for musical pieces that are rendered with the Music package and might be used as material to make more music.
- tables for the generation of lookup tables for some basic waveform.
- utils for various functions regarding conversions, mix, etc.
- sequencer for scheduling notes into a timeline and exporting audio.
Plans
Concrete things the code itself is waiting for, rather than a wish list:
- A head-related transfer function. Both
localizeandlocalize2say so in their own notes: the height of a source, and whether it is in front of or behind the listener, are cues an HRTF carries and neither of them models. - The remaining peals.
Peals.twenty_all_overandPeals.an_eight_and_fortyraiseNotImplementedError, andBeing.walk'sperm-walkmethod was never restored from its predecessor. - Reconciling
core/functions.pywith the MASS reference implementation, routine by routine. - An article describing the package, as a companion to the MASS one.
Contributing
The test, type-check, lint and documentation tooling comes with the dev and
docs extras:
pip install -e '.[dev,docs]'
pytest # 493 tests, 100% coverage
mypy music # type check
ruff check music tests examples tools conftest.py # lint, at PEP 8's 79 columns
sphinx-build -b html -W docs docs/_build/html
All four run in CI on Python 3.10 through 3.13 for every push and pull
request, and both pytest and sphinx-build are configured to fail on
anything less than full coverage or a docstring numpydoc cannot parse.
Docstrings are numpydoc style throughout, and the code follows PEP 8. For the maths behind a routine, examples of its use, and the article it comes from, read its docstring — or the rendered API reference.
Further information
Music is primarily intended for artistic use, psychophysics experiments and data sonification.
You can find an example in Versinus, an animated visualization method for evolving networks that uses Music to render the musical track that represents networks structures.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file music-1.2.0.tar.gz.
File metadata
- Download URL: music-1.2.0.tar.gz
- Upload date:
- Size: 110.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/5.1.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66840ffda2a165fd703940bb6ab6b592377da867de8a36eb5a063a44380f0333
|
|
| MD5 |
356a068cb112872aab3872199d2499a3
|
|
| BLAKE2b-256 |
38c85d1b1b294ae95595aaab4146c05bc6870587bdf09e638df343e8220e0ae4
|
File details
Details for the file music-1.2.0-py3-none-any.whl.
File metadata
- Download URL: music-1.2.0-py3-none-any.whl
- Upload date:
- Size: 81.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/5.1.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2612f22e92bc159aa770cfe5b3d9b7f6d0708a34861c7afa297abb1f7563269
|
|
| MD5 |
3b357fd67ac5e0b768e8c8339f942f53
|
|
| BLAKE2b-256 |
32e44e68ad97a1239653aaa9389191533dc1f067a4f923400b085bd6eb68fbb1
|