midi2song


Namemidi2song JSON
Version 0.1.1 PyPI version JSON
download
home_pageNone
SummaryCLI player that streams MIDI files to system MIDI OUT ports with optional text visualisations
upload_time2025-10-26 00:51:27
maintainerNone
docs_urlNone
authorAndrea Antonio Perrelli
requires_python>=3.9
licenseMIT
keywords midi music cli player
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 🎹 py_midi2song — Player MIDI da riga di comando (Python)

`py_midi2song` è un player **standalone** per file `.mid` / `.midi`, scritto in
**Python 3.9+**, che utilizza le librerie `mido` e `python-rtmidi` per
riprodurre eventi MIDI reali attraverso una porta MIDI OUT del sistema (es. su
Windows, "Microsoft GS Wavetable Synth"). Il progetto è ora impacchettato come
modulo Python installabile e fornisce un comando `py-midi2song` pronto all'uso.

---

## 🚀 Funzionalità principali

✅ Riproduce file MIDI reali su una porta MIDI OUT di sistema  
✅ Supporta tempo variabile (`set_tempo`) e tempo globale (`--tempo-scale`)  
✅ Supporta start offset e fine (`--start-at-seconds`, `--end-at-seconds`)  
✅ Filtro per tracce e canali (`--tracks`, `--channels`)  
✅ Controllo del gain sulla velocity (`--gain`)  
✅ Gestione corretta delle NoteOn/NoteOff, anche in caso di interruzione (`Ctrl+C`)  
✅ Visualizzazioni testuali opzionali (`--viz` con modalità *grid* o *lanes*)  
✅ Logging dettagliato (INFO / DEBUG)  
✅ Compatibile con **Windows**, **Linux** e **macOS**

---

## 📦 Installazione

Assicurati di avere **Python 3.9+** installato, poi esegui:

```bash
pip install py-midi2song
```

Il pacchetto installerà automaticamente `mido` e `python-rtmidi`. Su Windows è
consigliato attivare o installare un sintetizzatore MIDI come:

- **Microsoft GS Wavetable Synth** (già incluso in Windows)
- Oppure un sintetizzatore virtuale come **VirtualMIDISynth** o
  **loopMIDI + VST**

Per chi preferisce lavorare direttamente dal codice sorgente è disponibile anche
lo script di compatibilità:

```bash
python midi2song.py --help
```

---

## 🧩 Utilizzo

### Elenca le porte MIDI disponibili

```bash
python midi2song.py --list-ports
```

Esempio output:

```
[0] Microsoft GS Wavetable Synth
[1] loopMIDI Port 1
```

---

### Riproduci un file MIDI

```bash
python midi2song.py --midi song.mid
```

---

### Seleziona una porta specifica (per nome o indice)

```bash
python midi2song.py --midi song.mid --port "Microsoft GS"
# oppure
python midi2song.py --midi song.mid --port 0
```

---

### Riproduzione parziale o più lenta/veloce

```bash
python midi2song.py --midi song.mid --start-at-seconds 12.5 --tempo-scale 0.9
```

---

### Filtrare tracce e canali

```bash
# Solo tracce 0 e 2
python midi2song.py --midi song.mid --tracks include:0,2

# Tutti i canali tranne il 9 (percussioni)
python midi2song.py --midi song.mid --channels exclude:9
```

---

### Regolare la dinamica

```bash
# Gain 0.5 => più morbido
python midi2song.py --midi song.mid --gain 0.5
```

---

## ⚙️ Argomenti CLI completi

| Argomento | Tipo | Default | Descrizione |
|------------|-------|----------|-------------|
| `--midi PATH` | obbligatorio | — | Percorso del file MIDI da riprodurre |
| `--list-ports` | flag | — | Mostra le porte MIDI OUT disponibili e termina |
| `--port NAME/INDICE` | opzionale | auto | Seleziona la porta per nome o indice |
| `--start-at-seconds FLOAT` | float | 0.0 | Avvia la riproduzione da questo tempo |
| `--end-at-seconds FLOAT` | float | — | Interrompe la riproduzione a questo tempo |
| `--tempo-scale FLOAT` | float | 1.0 | Scala globale del tempo (0.8 = più lento) |
| `--gain FLOAT` | float | 1.0 | Moltiplicatore di velocity (clamp 1–127) |
| `--tracks all\|include:CSV\|exclude:CSV` | string | all | Filtra per indici di traccia (0-based) |
| `--channels all\|include:CSV\|exclude:CSV` | string | all | Filtra per canali MIDI (0–15) |
| `--ignore-meta` | flag | — | Ignora meta-eventi non necessari |
| `--log-level {INFO,DEBUG,WARNING}` | string | INFO | Livello di dettaglio log |
| `--viz` | flag | — | Abilita la visualizzazione testuale |
| `--viz-mode {grid,lanes}` | string | grid | Seleziona la modalità di visualizzazione |
| `--viz-refresh-hz FLOAT` | float | 30.0 | Frequenza di aggiornamento della visualizzazione |
| `--viz-base-note INT` | int | 60 | Nota base per *grid* e *lanes* |
| `--viz-lanes {5,7}` | int | 7 | Numero di corsie per la modalità *lanes* |
| `--viz-window-seconds FLOAT` | float | 4.0 | Finestra futura visualizzata nella modalità *lanes* |
| `--viz-height INT` | int | 20 | Altezza (righe) per la modalità *lanes* |
| `--viz-beats` | flag | — | Mostra la beat grid/metronomo nelle visualizzazioni |

---

## 🧠 Log e debug

Esempio log:

```
INFO: File: 'song.mid' | ticks_per_beat=480 | tracce=2 | eventi_canale=356 | meta=12 | durata=31.09s
INFO: Porta selezionata (auto): Microsoft GS Wavetable Synth
INFO: Riproduzione: start=0.000s
```

In modalità debug:
```
python py_midi2song.py --midi song.mid --log-level DEBUG
```

---

## 🧩 Architettura del codice

Struttura principale del pacchetto installabile:

```
py_midi2song.py
├── list_output_ports()
├── select_output_port()
├── build_timeline()
├── apply_filters()
├── seek_index()
├── play_events()
└── main()
```

È inoltre disponibile un wrapper di compatibilità (`py_midi2song.py`) per eseguire
la CLI direttamente dalla directory del repository senza installazione.

Ogni evento MIDI è rappresentato da una dataclass:

```python
@dataclass
class Event:
    time_s: float
    message: mido.Message
    track_index: int
    channel: Optional[int]
```

---

## ⚠️ Casi limite gestiti

- File con più `set_tempo`
- Tracce solo meta-eventi
- Canale 10 (percussioni)
- Note sovrapposte (NoteOn/NoteOff coerenti)
- MIDI Type 0 e Type 1
- Seek a metà nota (non invia NoteOff senza NoteOn post-seek)
- `Ctrl+C` → chiusura porta + `All Notes Off`

---

## 🧰 Esempi rapidi

```bash
python midi2song.py --midi test.mid
python midi2song.py --midi test.mid --tempo-scale 0.5
python midi2song.py --midi test.mid --gain 0.5
python midi2song.py --midi test.mid --start-at-seconds 10
python midi2song.py --midi test.mid --channels exclude:9
```

---

## 🧩 Compatibilità

- ✅ **Windows** (prioritario)
- ✅ **Linux**
- ✅ **macOS**

Su Windows, viene selezionata automaticamente la porta
**“Microsoft GS Wavetable Synth”** se disponibile.

---

## 🪶 Licenza

MIT License © 2025 — Autore originale: *Andrea Antonio Perrelli*

---

## 🧡 Contributi

Pull requests e issue sono benvenuti.
Ogni miglioramento al timing, alla gestione del seek o alla compatibilità multi-porta è apprezzato.

---

**Enjoy your MIDI playback! 🎶**

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "midi2song",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "midi, music, cli, player",
    "author": "Andrea Antonio Perrelli",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/a6/61/ab02fac5e3f65514fac3ecc9a0e26ca0822c1a957720daf1f7ba2a90d2bc/midi2song-0.1.1.tar.gz",
    "platform": null,
    "description": "# \ud83c\udfb9 py_midi2song \u2014 Player MIDI da riga di comando (Python)\r\n\r\n`py_midi2song` \u00e8 un player **standalone** per file `.mid` / `.midi`, scritto in\r\n**Python 3.9+**, che utilizza le librerie `mido` e `python-rtmidi` per\r\nriprodurre eventi MIDI reali attraverso una porta MIDI OUT del sistema (es. su\r\nWindows, \"Microsoft GS Wavetable Synth\"). Il progetto \u00e8 ora impacchettato come\r\nmodulo Python installabile e fornisce un comando `py-midi2song` pronto all'uso.\r\n\r\n---\r\n\r\n## \ud83d\ude80 Funzionalit\u00e0 principali\r\n\r\n\u2705 Riproduce file MIDI reali su una porta MIDI OUT di sistema  \r\n\u2705 Supporta tempo variabile (`set_tempo`) e tempo globale (`--tempo-scale`)  \r\n\u2705 Supporta start offset e fine (`--start-at-seconds`, `--end-at-seconds`)  \r\n\u2705 Filtro per tracce e canali (`--tracks`, `--channels`)  \r\n\u2705 Controllo del gain sulla velocity (`--gain`)  \r\n\u2705 Gestione corretta delle NoteOn/NoteOff, anche in caso di interruzione (`Ctrl+C`)  \r\n\u2705 Visualizzazioni testuali opzionali (`--viz` con modalit\u00e0 *grid* o *lanes*)  \r\n\u2705 Logging dettagliato (INFO / DEBUG)  \r\n\u2705 Compatibile con **Windows**, **Linux** e **macOS**\r\n\r\n---\r\n\r\n## \ud83d\udce6 Installazione\r\n\r\nAssicurati di avere **Python 3.9+** installato, poi esegui:\r\n\r\n```bash\r\npip install py-midi2song\r\n```\r\n\r\nIl pacchetto installer\u00e0 automaticamente `mido` e `python-rtmidi`. Su Windows \u00e8\r\nconsigliato attivare o installare un sintetizzatore MIDI come:\r\n\r\n- **Microsoft GS Wavetable Synth** (gi\u00e0 incluso in Windows)\r\n- Oppure un sintetizzatore virtuale come **VirtualMIDISynth** o\r\n  **loopMIDI + VST**\r\n\r\nPer chi preferisce lavorare direttamente dal codice sorgente \u00e8 disponibile anche\r\nlo script di compatibilit\u00e0:\r\n\r\n```bash\r\npython midi2song.py --help\r\n```\r\n\r\n---\r\n\r\n## \ud83e\udde9 Utilizzo\r\n\r\n### Elenca le porte MIDI disponibili\r\n\r\n```bash\r\npython midi2song.py --list-ports\r\n```\r\n\r\nEsempio output:\r\n\r\n```\r\n[0] Microsoft GS Wavetable Synth\r\n[1] loopMIDI Port 1\r\n```\r\n\r\n---\r\n\r\n### Riproduci un file MIDI\r\n\r\n```bash\r\npython midi2song.py --midi song.mid\r\n```\r\n\r\n---\r\n\r\n### Seleziona una porta specifica (per nome o indice)\r\n\r\n```bash\r\npython midi2song.py --midi song.mid --port \"Microsoft GS\"\r\n# oppure\r\npython midi2song.py --midi song.mid --port 0\r\n```\r\n\r\n---\r\n\r\n### Riproduzione parziale o pi\u00f9 lenta/veloce\r\n\r\n```bash\r\npython midi2song.py --midi song.mid --start-at-seconds 12.5 --tempo-scale 0.9\r\n```\r\n\r\n---\r\n\r\n### Filtrare tracce e canali\r\n\r\n```bash\r\n# Solo tracce 0 e 2\r\npython midi2song.py --midi song.mid --tracks include:0,2\r\n\r\n# Tutti i canali tranne il 9 (percussioni)\r\npython midi2song.py --midi song.mid --channels exclude:9\r\n```\r\n\r\n---\r\n\r\n### Regolare la dinamica\r\n\r\n```bash\r\n# Gain 0.5 => pi\u00f9 morbido\r\npython midi2song.py --midi song.mid --gain 0.5\r\n```\r\n\r\n---\r\n\r\n## \u2699\ufe0f Argomenti CLI completi\r\n\r\n| Argomento | Tipo | Default | Descrizione |\r\n|------------|-------|----------|-------------|\r\n| `--midi PATH` | obbligatorio | \u2014 | Percorso del file MIDI da riprodurre |\r\n| `--list-ports` | flag | \u2014 | Mostra le porte MIDI OUT disponibili e termina |\r\n| `--port NAME/INDICE` | opzionale | auto | Seleziona la porta per nome o indice |\r\n| `--start-at-seconds FLOAT` | float | 0.0 | Avvia la riproduzione da questo tempo |\r\n| `--end-at-seconds FLOAT` | float | \u2014 | Interrompe la riproduzione a questo tempo |\r\n| `--tempo-scale FLOAT` | float | 1.0 | Scala globale del tempo (0.8 = pi\u00f9 lento) |\r\n| `--gain FLOAT` | float | 1.0 | Moltiplicatore di velocity (clamp 1\u2013127) |\r\n| `--tracks all\\|include:CSV\\|exclude:CSV` | string | all | Filtra per indici di traccia (0-based) |\r\n| `--channels all\\|include:CSV\\|exclude:CSV` | string | all | Filtra per canali MIDI (0\u201315) |\r\n| `--ignore-meta` | flag | \u2014 | Ignora meta-eventi non necessari |\r\n| `--log-level {INFO,DEBUG,WARNING}` | string | INFO | Livello di dettaglio log |\r\n| `--viz` | flag | \u2014 | Abilita la visualizzazione testuale |\r\n| `--viz-mode {grid,lanes}` | string | grid | Seleziona la modalit\u00e0 di visualizzazione |\r\n| `--viz-refresh-hz FLOAT` | float | 30.0 | Frequenza di aggiornamento della visualizzazione |\r\n| `--viz-base-note INT` | int | 60 | Nota base per *grid* e *lanes* |\r\n| `--viz-lanes {5,7}` | int | 7 | Numero di corsie per la modalit\u00e0 *lanes* |\r\n| `--viz-window-seconds FLOAT` | float | 4.0 | Finestra futura visualizzata nella modalit\u00e0 *lanes* |\r\n| `--viz-height INT` | int | 20 | Altezza (righe) per la modalit\u00e0 *lanes* |\r\n| `--viz-beats` | flag | \u2014 | Mostra la beat grid/metronomo nelle visualizzazioni |\r\n\r\n---\r\n\r\n## \ud83e\udde0 Log e debug\r\n\r\nEsempio log:\r\n\r\n```\r\nINFO: File: 'song.mid' | ticks_per_beat=480 | tracce=2 | eventi_canale=356 | meta=12 | durata=31.09s\r\nINFO: Porta selezionata (auto): Microsoft GS Wavetable Synth\r\nINFO: Riproduzione: start=0.000s\r\n```\r\n\r\nIn modalit\u00e0 debug:\r\n```\r\npython py_midi2song.py --midi song.mid --log-level DEBUG\r\n```\r\n\r\n---\r\n\r\n## \ud83e\udde9 Architettura del codice\r\n\r\nStruttura principale del pacchetto installabile:\r\n\r\n```\r\npy_midi2song.py\r\n\u251c\u2500\u2500 list_output_ports()\r\n\u251c\u2500\u2500 select_output_port()\r\n\u251c\u2500\u2500 build_timeline()\r\n\u251c\u2500\u2500 apply_filters()\r\n\u251c\u2500\u2500 seek_index()\r\n\u251c\u2500\u2500 play_events()\r\n\u2514\u2500\u2500 main()\r\n```\r\n\r\n\u00c8 inoltre disponibile un wrapper di compatibilit\u00e0 (`py_midi2song.py`) per eseguire\r\nla CLI direttamente dalla directory del repository senza installazione.\r\n\r\nOgni evento MIDI \u00e8 rappresentato da una dataclass:\r\n\r\n```python\r\n@dataclass\r\nclass Event:\r\n    time_s: float\r\n    message: mido.Message\r\n    track_index: int\r\n    channel: Optional[int]\r\n```\r\n\r\n---\r\n\r\n## \u26a0\ufe0f Casi limite gestiti\r\n\r\n- File con pi\u00f9 `set_tempo`\r\n- Tracce solo meta-eventi\r\n- Canale 10 (percussioni)\r\n- Note sovrapposte (NoteOn/NoteOff coerenti)\r\n- MIDI Type 0 e Type 1\r\n- Seek a met\u00e0 nota (non invia NoteOff senza NoteOn post-seek)\r\n- `Ctrl+C` \u2192 chiusura porta + `All Notes Off`\r\n\r\n---\r\n\r\n## \ud83e\uddf0 Esempi rapidi\r\n\r\n```bash\r\npython midi2song.py --midi test.mid\r\npython midi2song.py --midi test.mid --tempo-scale 0.5\r\npython midi2song.py --midi test.mid --gain 0.5\r\npython midi2song.py --midi test.mid --start-at-seconds 10\r\npython midi2song.py --midi test.mid --channels exclude:9\r\n```\r\n\r\n---\r\n\r\n## \ud83e\udde9 Compatibilit\u00e0\r\n\r\n- \u2705 **Windows** (prioritario)\r\n- \u2705 **Linux**\r\n- \u2705 **macOS**\r\n\r\nSu Windows, viene selezionata automaticamente la porta\r\n**\u201cMicrosoft GS Wavetable Synth\u201d** se disponibile.\r\n\r\n---\r\n\r\n## \ud83e\udeb6 Licenza\r\n\r\nMIT License \u00a9 2025 \u2014 Autore originale: *Andrea Antonio Perrelli*\r\n\r\n---\r\n\r\n## \ud83e\udde1 Contributi\r\n\r\nPull requests e issue sono benvenuti.\r\nOgni miglioramento al timing, alla gestione del seek o alla compatibilit\u00e0 multi-porta \u00e8 apprezzato.\r\n\r\n---\r\n\r\n**Enjoy your MIDI playback! \ud83c\udfb6**\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "CLI player that streams MIDI files to system MIDI OUT ports with optional text visualisations",
    "version": "0.1.1",
    "project_urls": null,
    "split_keywords": [
        "midi",
        " music",
        " cli",
        " player"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "d97a489c8143174a3125425dc9b02ddc5753be718eef5cc789258dcf0225518a",
                "md5": "b887e30c44c5d05f20c8ad705591062d",
                "sha256": "d691209de42466c3fe91c5059a9665053f7537c6d089666a8f07069138508276"
            },
            "downloads": -1,
            "filename": "midi2song-0.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b887e30c44c5d05f20c8ad705591062d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 15045,
            "upload_time": "2025-10-26T00:51:26",
            "upload_time_iso_8601": "2025-10-26T00:51:26.006670Z",
            "url": "https://files.pythonhosted.org/packages/d9/7a/489c8143174a3125425dc9b02ddc5753be718eef5cc789258dcf0225518a/midi2song-0.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a661ab02fac5e3f65514fac3ecc9a0e26ca0822c1a957720daf1f7ba2a90d2bc",
                "md5": "405de7336e56ba8ada739a5897e33fb7",
                "sha256": "bfb86a0cfa2a3d84345071fc1277701e38b859b0fccf4b363496bc64b927e085"
            },
            "downloads": -1,
            "filename": "midi2song-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "405de7336e56ba8ada739a5897e33fb7",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 17095,
            "upload_time": "2025-10-26T00:51:27",
            "upload_time_iso_8601": "2025-10-26T00:51:27.167772Z",
            "url": "https://files.pythonhosted.org/packages/a6/61/ab02fac5e3f65514fac3ecc9a0e26ca0822c1a957720daf1f7ba2a90d2bc/midi2song-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-26 00:51:27",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "midi2song"
}
        
Elapsed time: 1.47186s