{"slug": "show-hn-duetto-pretrained-music-transformer-that-plays-a-piano-with-you", "title": "Show HN: Duetto – pretrained music transformer that plays a piano with you", "summary": "Riccardo Cataldi released Duetto, an open-source system that pairs a live MIDI keyboard with the pretrained Anticipatory Music Transformer (trained on Lakh MIDI) to generate a second piano part in real time, running the model on an Nvidia Jetson Orin Nano with JetPack 6 while a laptop handles MIDI, FluidSynth sound and a piano roll display. Duetto offers presets including duet, call & response, it comps and it solos, plus controls for density, harmony, role, dialogue, groove, risk, focus, key follow, scale and tempo, and is licensed under PolyForm Noncommercial 1.0.0, which permits noncommercial use, modification and sharing but bars commercial use.", "body_md": "## duo-f-blues.mp4\n\nPlay a MIDI keyboard and a transformer plays a second piano with you, in real time. It listens like a partner: your key, the chord you play, your pulse, your phrases. It comps while you play and takes the melody when you rest.\n\nThe model is the pretrained [Anticipatory Music Transformer](https://github.com/jthickstun/anticipation) (Lakh MIDI), running on a Jetson; the laptop handles MIDI, sound and the piano roll.\n\n## duo-you-comp-it-solos.mp4\n\nAbove: you play low chords, the model improvises over them (the **it solos** preset). Files in [samples/duo](https://github.com/RiccardoCataldi/duetto/blob/main/samples/duo).\n\n```\nssh -t jetson sudo jetson_clocks   # after every Jetson reboot\n./run_duet.sh                      # on the laptop\n```\n\n`run_duet.sh` restarts everything: the model server on the Jetson, the SSH tunnel, FluidSynth, `main.py` on the keyboard and the piano roll. Closing the piano roll stops the duo and saves it in `generated/`.\n\nWithout a Jetson: `python -m music_transformer.server` in one terminal, `python main.py` in another (Ctrl+C stops and saves).\n\n## Setup\n\n- **Jetson** (Orin Nano, JetPack 6): the repo in`~/Ai-Duet` with a venv made with`--system-site-packages` (NVIDIA's torch), the model as safetensors in`~/models/music-medium-800k` , power mode MAXN_SUPER, and`ssh jetson` working with a key.\n- **Laptop** : FluidSynth with a General MIDI soundfont (`SOUNDFONT=path/to.sf2 ./run_duet.sh` for a sampled grand), and a venv with`pip install mido python-rtmidi pygame imageio-ffmpeg` .\n- **Code changes** : the Jetson does not pull from git; copy the files over (`scp music_transformer/*.py jetson:~/Ai-Duet/music_transformer/` ) and run`./run_duet.sh` again. The session tests need torch: run`python -m unittest tests.test_duo_session` there.\n- **Logs** :`~/amt_server.log` on the Jetson;`duet.log` ,`fluidsynth.log` ,`pianoroll.log` in`/tmp` on the laptop.\n\nThe top of the piano roll says what the model hears (key, chord, tempo) and what it is doing. Keys: F fullscreen, K show or hide the controls, Esc close.\n\nControls are sliders (drag them; hold Shift to drag finely) and steppers (click the arrows). The wheel or the arrow keys over a control turn it, and the wheel elsewhere scrolls the panel. A double click resets a control, and the bottom of the panel says what the control under the mouse does. A control is dimmed while what it shapes is not happening.\n\n- **AI mind**  - Presets: **duet** ,**call & response** ,**it comps** (it plays the harmony, you improvise),**it solos** (you play the harmony, it improvises),**free**\n  - Musical controls: density, harmony, role, dialogue, groove, risk, focus, key follow\n  - Range: `lowest` ,`highest` octave\n  - Scale: `root` and`scale` force it into a scale (C major, D harmonic minor, F minor pentatonic...) instead of your key\n  - Tempo: `bpm` fixes its tempo instead of following yours,`metronome` clicks it\n- Presets: \n- **Your sound** ,**AI sound** : instrument, volume, pan, envelope, reverb and delay, in FluidSynth\n- **Advanced** : every knob of the model, described in`KNOBS` in[music_transformer/duo.py](https://github.com/RiccardoCataldi/duetto/blob/main/music_transformer/duo.py) , where the defaults are too\n\nKnobs and sound are kept in `~/.config/ai-duet/`.\n\n[PolyForm Noncommercial 1.0.0](https://github.com/RiccardoCataldi/duetto/blob/main/LICENSE): use it, change it and share it freely for anything noncommercial (personal, study, research, education, hobby). Commercial use is not allowed. The model itself is the [Anticipatory Music Transformer](https://github.com/jthickstun/anticipation), under its own license.", "url": "https://wpnews.pro/news/show-hn-duetto-pretrained-music-transformer-that-plays-a-piano-with-you", "canonical_source": "https://github.com/RiccardoCataldi/duetto", "published_at": "2026-10-24 09:44:20+00:00", "updated_at": "2026-10-24 10:12:34.386321+00:00", "lang": "en", "topics": ["artificial-intelligence", "machine-learning", "generative-ai", "ai-tools"], "entities": ["Duetto", "Riccardo Cataldi", "Anticipatory Music Transformer", "Nvidia Jetson Orin Nano", "JetPack 6", "FluidSynth", "Lakh MIDI", "PolyForm Noncommercial 1.0.0"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-duetto-pretrained-music-transformer-that-plays-a-piano-with-you", "markdown": "https://wpnews.pro/news/show-hn-duetto-pretrained-music-transformer-that-plays-a-piano-with-you.md", "text": "https://wpnews.pro/news/show-hn-duetto-pretrained-music-transformer-that-plays-a-piano-with-you.txt", "jsonld": "https://wpnews.pro/news/show-hn-duetto-pretrained-music-transformer-that-plays-a-piano-with-you.jsonld"}}