Metadata-Version: 2.4
Name: montyroll
Version: 0.1.0
Summary: A lightweight MIDI visualiser, piano-roll editor and player, stdlib-only Python with tkinter
Author: acscpt
License: MIT
Project-URL: Repository, https://github.com/acscpt/montyroll
Project-URL: Issues, https://github.com/acscpt/montyroll/issues
Keywords: midi,piano-roll,music,tkinter,editor,visualiser,player
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: X11 Applications
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Sound/Audio :: MIDI
Classifier: Topic :: Multimedia :: Sound/Audio :: Editors
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: pytest-cov>=4; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Dynamic: license-file

# MontyRoll

[![PyPI](https://img.shields.io/pypi/v/montyroll.svg)](https://pypi.org/project/montyroll/)
[![PyPI Downloads](https://static.pepy.tech/personalized-badge/montyroll?period=total&units=INTERNATIONAL_SYSTEM&left_color=GRAY&right_color=RED&left_text=downloads)](https://pepy.tech/projects/montyroll)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Tests](https://github.com/acscpt/montyroll/actions/workflows/tests.yml/badge.svg)](https://github.com/acscpt/montyroll/actions/workflows/tests.yml)
[![codecov](https://codecov.io/gh/acscpt/montyroll/branch/develop/graph/badge.svg)](https://codecov.io/gh/acscpt/montyroll)

***And now for something completely MIDI***

MontyRoll is a lightweight and simple MIDI visualiser written in Python. It can read Standard MIDI Files and display the channels, their assigned instruments and a summary of what each one plays, and shows the notes on a scrollable, zoomable piano roll. It has no Python dependencies other than the standard library.

MontyRoll can also play the file through a [synth](#synths) such as `timidity`, if one is installed.

<a href="docs/images/note-display.png"><img src="docs/images/note-display.png" width="400" alt="The piano roll showing the bundled Chopsticks demo, with the channel strip on the left"></a> <a href="docs/images/events.png"><img src="docs/images/events.png" width="400" alt="The Events tab listing every event in the demo file, decoded"></a>

## Requirements

- Python 3.10+ with tkinter (`sudo apt install python3-tk` on Debian/Ubuntu)

- Optional, for sound: a software synth on `PATH`, `timidity` recommended. See [Synths](#synths) for the alternatives and install commands.

Without a synth, everything except audio playback still works.

## Run

```bash
python -m montyroll                            # start empty
python -m montyroll path/to/file.mid
python -m montyroll resources/chopsticks.mid   # the bundled demo
```

The demo is an original arrangement of Chopsticks (Euphemia Allen, 1877, public domain) generated by `resources/make_demo.py`: piano alone for sixteen bars, then the repeat with vibes, bass and drums, a tempo lift at the repeat and a ritardando at the end.

## Features

**Visualisation**

- Channel strip for every channel in use:
  - colour key
  - GM instrument
  - note count
  - pitch range
  - instrument family
  - whether the part uses pitch bend

- Piano roll with:
  - per-channel colours
  - velocity-shaded notes
  - piano-key gutter
  - bar/beat grid

- Three-row header ruler:
  - seconds (tempo-aware)
  - bar numbers
  - tempo changes and markers from the file

- A file can contain any number of tempo changes. Each one is shown in the header ruler, and the seconds row stretches and compresses against the bar grid to match.

- Event list with every message decoded, with tick, seconds and bar:beat for each

- Status bar tracking the pointer in musical time, naming the note (or drum sound) under the cursor

**Editor**

- Add, move, resize and delete notes with the mouse (see [Controls](#controls)).

- Grid snap from whole notes down to 1/32, or off for free placement

- Set velocity on any selection.

- Change a channel's GM instrument and set the channel volume.

- Saving re-serialises the original tracks, so any event the editor does not understand is written back unchanged.

**Listen**

- Play and stop from the toolbar or `Space`, with a cursor that follows the file's tempo map and auto-scrolls the roll.

- Mute and solo per channel. Mute silences a channel; solo plays only the soloed channels.

- Each channel's instrument can be previewed from the channel strip, in that channel's own pitch range.

- Master volume and playback speed (25-300%), affecting playback only

- Mute, solo, volume and speed all take effect during playback, which carries on from the cursor position.

- Live readout of elapsed time, bar:beat and current tempo

## Controls

| Action | Control |
| --- | --- |
| Play / stop | `Space` or the toolbar button |
| Select all / clear | `Ctrl+A` / `Esc` |
| Delete selection | `Del` |
| Open / save | `Ctrl+O` / `Ctrl+S` |
| New file | `Ctrl+N` |
| Add a note | Double-click the piano roll |
| Move / resize a note | Drag the note / drag its right edge |
| Zoom horizontally | `Ctrl` + mouse wheel (anchored at the pointer) |
| Scroll horizontally | `Shift` + mouse wheel |
| Scroll vertically | Mouse wheel |
| Note context menu | Right-click |

## Synths

MontyRoll makes no sound of its own. For playback it writes a temporary MIDI file and hands it to the first of these found on `PATH`:

- [TiMidity++](https://timidity.sourceforge.net/) (`timidity`), recommended. On Debian/Ubuntu: `sudo apt install timidity`.

- [FluidSynth](https://www.fluidsynth.org/) (`fluidsynth`), which needs a General MIDI soundfont in `/usr/share/sounds/sf2`, `/usr/share/soundfonts` or `/usr/local/share/soundfonts`. On Debian/Ubuntu: `sudo apt install fluidsynth fluid-soundfont-gm`.

- [WildMIDI](https://github.com/Mindwerks/wildmidi) (`wildmidi`)

- `aplaymidi` from [alsa-utils](https://github.com/alsa-project/alsa-utils), used only when an ALSA synth port other than "Midi Through" exists. Midi Through is always present and plays nothing, so on its own it is not enough.

## Licence

MIT - see [LICENSE](LICENSE).
