Skip to main content

PyPiano

PyPiano plays and records piano from Python. You play note names such as "C-4", or the Notes, NoteContainers, Bars and Tracks of mingus, through your speakers or into a wav file. FluidSynth does the sound, and a sound font with eight pianos is included, so it works out of the box.

Installation

PyPiano needs Python 3.11 or newer and the FluidSynth library:

sudo apt install libfluidsynth3   # Debian / Ubuntu
brew install fluid-synth          # macOS

Then install PyPiano from PyPI with pip or uv:

pip install pypiano
uv add pypiano

The development version installs from GitHub: pip install git+https://github.com/FelixGSE/pypiano.git.

Usage

from pypiano import Instrument, Piano
from mingus.containers import Bar, Note

# The with block releases FluidSynth when it ends; without it, call p.close() when done
with Piano() as p:
    # Play a simple C-4 via audio; play() returns when the note has sounded for a second
    p.play("C-4")

    # Play a mingus Note for two seconds, louder (velocity 0 to 127)
    note = Note("C-4")
    p.play(note, duration=2, velocity=110)

    # Record a Note to a wav file
    p.record(note, "my_first_recording.wav", seconds=2)

    # Play a Bar at a given tempo
    bar = Bar()
    for name in ("C-4", "E-4", "G-4", "C-5"):
        bar.place_notes(name, 4)
    p.play(bar, bpm=90)

    # Use a different instrument; its name, "Honky-tonk Piano", works too
    p.load_instrument(Instrument.HONKY_TONK_PIANO)
    p.play(note)

play() takes a note name, a key index from 0 (A-0) to 87 (C-8), a PianoKey from p.keyboard, or any mingus Note, NoteContainer, Bar or Track, and plays it through the audio output. It returns when the music has finished: a note or chord sounds for duration seconds (1 by default), a Bar or Track as long as its notes take at bpm. The notes then fade out, unless the piano is closed right away. velocity sets how hard every note is struck.

record() takes the same and writes a wav file instead, rendered faster than real time and without sound. Without seconds the recording ends when the fade has died away; with it, the recording is exactly that long.

Note names

Note names follow scientific pitch notation, like mingus: octave numbers go up at C, so middle C is C-4 and A-4 is 440 Hz. Every key has both of its names, for example C#-4 and Db-4, and the octave boundary applies to them too: B#-3 is the same key as C-4, and Cb-5 the same as B-4. play() also takes a name without an octave, such as "C", in octave 4.

Instruments

The included sound font has the eight General MIDI pianos, as Instrument members or by their names. The default is the Acoustic Grand Piano.

Instrument Name
Instrument.ACOUSTIC_GRAND_PIANO "Acoustic Grand Piano"
Instrument.BRIGHT_ACOUSTIC_PIANO "Bright Acoustic Piano"
Instrument.ELECTRIC_GRAND_PIANO "Electric Grand Piano"
Instrument.HONKY_TONK_PIANO "Honky-tonk Piano"
Instrument.ELECTRIC_PIANO_1 "Electric Piano 1"
Instrument.ELECTRIC_PIANO_2 "Electric Piano 2"
Instrument.HARPSICHORD "Harpsichord"
Instrument.CLAVI "Clavi"

Any other General MIDI sound font works too, and then program numbers select its instruments, for example the violin: Piano("FluidR3_GM.sf2", instrument=40).

Audio output

FluidSynth uses its default audio driver. To choose another one, pass its name, for example Piano(audio_driver="pipewire"). Which drivers there are depends on how FluidSynth was built; an unknown name raises AudioDriverError with the list. Without a sound device, playing logs a warning and nothing is heard, while recording to a file works as usual.

Errors

PyPiano's own errors derive from PyPianoError, for example InvalidNoteError for a note outside the 88 keys. Each one also derives from the built-in exception it stands for, such as ValueError or TypeError.

Good to know

PyPiano's public API is what the pypiano package exports, for example from pypiano import Piano, Instrument. Its submodules are internal and can change between releases.

Importing pypiano adjusts mingus' FluidSynth bindings (mingus.midi.pyfluidsynth) for the whole process: it finds Homebrew's FluidSynth on macOS, makes recording work with numpy 2.3 or newer, and accepts every audio driver of FluidSynth 2. Other code in the same process that uses these bindings gets the same changes.

The included sound font

The bundled sound font holds the eight pianos of FluidR3_GM by Frank Wen, cut reproducibly from Debian's fluid-soundfont package with sf2-cutter to a pinned checksum (details).

Contributing

Bug reports and pull requests are welcome. CONTRIBUTING.md explains the development setup, the checks and how releases work. Changes are listed in the changelog.

License

PyPiano is free software under the GNU General Public License, version 3 or later, like mingus, which it builds on. See LICENSE. Copyright (C) 2021-2026 FelixGSE. Releases up to and including 0.1.2 were published under the MIT license.

The included sound font is under the MIT license, see LICENSE-FluidR3_GM_sf2.txt.

Metadata

Release files for pypiano 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pypiano 0.2.1
File Size Uploaded
pypiano-0.2.1.tar.gz 16.7 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pypiano 0.2.1
File Interpreter ABI Platform
pypiano-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 33.4 MB

Release files / pypiano-0.2.1.tar.gz

Download URL pypiano-0.2.1.tar.gz
Size 16.7 MB
Tags Source
SHA-256 checksum
How to use checksums
0ed3f18f19c5eeb6bedf95f9272f50ab3b60cadbc54c99ec4b77c69e1b674ec9
BLAKE2b-256 checksum
How to use checksums
916ec2c98fdca2414c6e83cfeacbfde2f9589de75458f0fdafd0f4469dc3fb01
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / pypiano-0.2.1-py3-none-any.whl

Download URL pypiano-0.2.1-py3-none-any.whl
Size 16.7 MB
Tags Python 3
SHA-256 checksum
How to use checksums
0c4cb47d8a1688a6b4c0696f25a6f541a55f934b13c359ce8a688e3ca8b286ad
BLAKE2b-256 checksum
How to use checksums
583578fe8d73424da1e2551b5a906bf77a8282cb564fc7f550969e94335e7d99
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

1 release file

0.1.0

1 release file

0.0.0

2 release files

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