Skip to main content

Music

PyPI Python versions CI Docs License: MIT DOI

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_audio to 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 Being as 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() and music.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.singing module provides basic text-to-speech utilities. Run music.singing.setup_engine() once to clone the eCantorix engine before using these features. It is cloned into your user cache directory; set MUSIC_ECANTORIX_DIR to put it elsewhere. Because eCantorix is a Perl program driving espeak through a Makefile, it also needs git, make, perl and espeak installed 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 localize and localize2 say 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_over and Peals.an_eight_and_forty raise NotImplementedError, and Being.walk's perm-walk method was never restored from its predecessor.
  • Reconciling core/functions.py with 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

music-1.2.0.tar.gz (110.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

music-1.2.0-py3-none-any.whl (81.1 kB view details)

Uploaded Python 3

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

Hashes for music-1.2.0.tar.gz
Algorithm Hash digest
SHA256 66840ffda2a165fd703940bb6ab6b592377da867de8a36eb5a063a44380f0333
MD5 356a068cb112872aab3872199d2499a3
BLAKE2b-256 38c85d1b1b294ae95595aaab4146c05bc6870587bdf09e638df343e8220e0ae4

See more details on using hashes here.

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

Hashes for music-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d2612f22e92bc159aa770cfe5b3d9b7f6d0708a34861c7afa297abb1f7563269
MD5 3b357fd67ac5e0b768e8c8339f942f53
BLAKE2b-256 32e44e68ad97a1239653aaa9389191533dc1f067a4f923400b085bd6eb68fbb1

See more details on using hashes here.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page