Tenstorrent Quietbox 2 · your personal AI machine

Your art.
Your silicon.

The Quietbox 2 is a personal AI computer — four Tenstorrent chips on your desk, silent and always on. Whatever your art is, the machine learns it, generates it, and plays it back in real time. This is what it sounds like when it composes jazz.

Hear it compose See the machine GitHub →
↓ scroll

Silicon Road

After Tangerine Dream's Hyperborea (1983). Sawtooth lead over warm pad chords and a sequenced synth bass — no drums, just drift and texture. Each pattern is seeded from the previous, so motifs carry forward across the three movements.

Key: E minor  ·  BPM: 84  ·  Chords: Em7 → Cmaj7 → Am7 → Bm7  ·  Lead 2 Sawtooth + Pad 2 Warm + Synth Bass 1

Pattern 1

Void

Cold start — sparse emergence. Bass and pad establish the harmonic field before the lead appears.

piano roll
4× P300C 48.5s gen (incl. compile) lead:6n bass:47n pad:7n cold start
⬇ MIDI
Pattern 2

Drift

Seeded from the void — sawtooth lead opens up (52 notes), pads fill in, bass locks the pulse.

piano roll
4.2 ev/s 37.9s gen 1.66× loop lead:52n bass:40n pad:44n
⬇ MIDI
Pattern 3

Shore

Arrival — lead and pad interweave (42n + 32n), bass anchors. The motifs from drift resolve here.

piano roll
3.9 ev/s 41.1s gen 1.80× loop lead:42n bass:34n pad:32n
⬇ MIDI

Aria in D Minor

Baroque continuo texture at 76 BPM. Acoustic piano carries a singing treble line over sustained string chords — no percussion, just the keyboard-and-strings palette of Bach and Handel. String ensemble chords are velocity-boosted (90–115) for clear presence alongside the piano line. Three patterns develop from a spare exposition through fuller voicings, each seeded from the last. Chord progression: Dm → F → Gm → A7 (the A7's C# leading tone is restored by the harmonic filter on strong cadence beats).

Pattern 1

Exposition — cold start

Piano melody emerges (14n) over string chord cushion (43n). Sparse but present — Baroque opening.

piano roll
4× P300C 48.8s gen piano: 14n strings: 43n bass: 20n
⬇ MIDI
Pattern 2

Development

Seeded from P1 — the piano opens up (38n), strings swell into full chord support (70n).

piano roll
4.2 ev/s 37.7s gen 1.49× loop piano: 38n strings: 70n bass: 40n
⬇ MIDI
Pattern 3

Recapitulation

The return — familiar material in new light, the A7→Dm cadence settling into place.

piano roll
3.9 ev/s 41.1s gen 1.63× loop piano: 77n strings: 85n bass: 49n
⬇ MIDI

Midnight in East Texas

Slow Delta shuffle at 80 BPM. Acoustic steel guitar and barrelhouse piano over a shuffled kit — A7 → D7 → A7 → E7. The coherence layer uses the pentatonic minor scale (root, ♭3, 4, 5, ♭7) at strictness 0.65 — period-correct 1930s phrasing with no chromatic passing tones or dissonant tritone. Triplet swing (2:1 ratio) baked into every upbeat.

Pattern 1

Intro — cold start

Sparse opening: guitar feeling out the changes, piano touches, a light shuffle. Delta blues in embryo.

piano roll
4× P300C 47.7s gen guitar: 33n piano: 26n bass: 2n drums: 43n
⬇ MIDI
Pattern 2

Groove

Seeded from P1 — guitar and piano both open up, the kit locks in. Pentatonic lines settle into the shuffle.

piano roll
4.4 ev/s 28.9s gen 1.20× loop guitar: 55n piano: 59n bass: 8n drums: 69n
⬇ MIDI
Pattern 3

Resolution

Guitar, piano, and kit all locked in. Pentatonic lines ring clean — no blue note dissonance, pure Delta feel.

piano roll
4.2 ev/s 38.0s gen 1.58× loop guitar: 75n piano: 114n bass: 14n drums: 120n
⬇ MIDI

Slow Light

62 BPM. All four voices — string ensemble melody, warm pad harmony, synth bass, and sparse kit — emerge from almost nothing and grow across three patterns. Ebmaj7 → Cm7 → Abmaj7 → Bb. Each 8-bar loop is 31 seconds. Strict scale adherence and wider micro-timing (±16 ticks) create the floating, consonant texture of the style.

Pattern 1

Opening

Cold-start: a single string note, a bass touch, barely anything. Silence as texture.

piano roll
4× P300C 32.2s gen strings: 16n bass: 1n pad: 26n drums: 9n
⬇ MIDI
Pattern 2

Drift

Seeded from P1 — all four voices gain presence. The pad opens. The strings breathe.

piano roll
7.8 ev/s 12.3s gen 0.40× loop strings: 18n bass: 1n pad: 23n drums: 8n
⬇ MIDI
Pattern 3

Dissolution

Richest texture: strings carry the melody (18n), pad fully voiced (22n), bass and kit threading through.

piano roll
7.8 ev/s 10.3s gen 0.33× loop strings: 18n bass: 1n pad: 22n drums: 8n
⬇ MIDI

Quick Changes

200 BPM. Piano trio texture emerged: piano comping over walking bass and ride cymbal. Bbmaj7 → G7 → Cm7 → F7. Chromatic approach notes and bebop passing tones are now preserved (scale strictness 0.25, passing-tone tolerance 1 semitone). Medium swing (0.63 ratio) applied to off-beat eighths. At this tempo each loop is 9.6 seconds — piano and drums just keep building.

Pattern 1

Head

Sparse opening: bass walking, piano touches chord changes, light kit. The changes assert themselves.

piano roll
4× P300C 48.3s gen bass: 5n piano: 55n drums: 42n
⬇ MIDI
Pattern 2

First chorus

Seeded from head — piano opens up (89n), kit locks in hard. The bebop machine is warming up.

piano roll
4.4 ev/s 29.3s gen 3.05× loop bass: 6n piano: 89n drums: 52n
⬇ MIDI
Pattern 3

Second chorus

Full throttle — piano is dense (85n), drums relentless (52n), bass walking the turnaround. Chromatic lines intact.

piano roll
4.2 ev/s 38.5s gen 4.01× loop bass: 6n piano: 85n drums: 52n
⬇ MIDI

Monosynth

Single-voice generation — one instrument, one channel, no accompaniment. Lead 1 Square (GM 80) over a C major pentatonic framework at 120 BPM. All other roles are silenced so the model concentrates entirely on the melodic line. Each pattern seeds the next, so motifs evolve across the three takes.

Key: C major (pentatonic)  ·  BPM: 120  ·  Chords: Cmaj7 → Am7 → Fmaj7 → G7  ·  Lead 1 Square — melody only

Pattern 1

Theme

Cold start — 45 notes, single voice, no accompaniment. Pure melodic thinking.

piano roll
4× P300C 41.4s gen (incl. compile) 45 notes cold start
⬇ MIDI
Pattern 2

Variation

Seeded from the theme — 38 notes, melodic variation on the opening phrase.

piano roll
4.5 ev/s 21.4s gen 2.68× loop 38 notes
⬇ MIDI
Pattern 3

Development

Seeded from variation — 44 notes, the line develops further before returning to the root.

piano roll
4.3 ev/s 22.1s gen 2.76× loop 44 notes
⬇ MIDI

All the parts, working together

Every musical token flows through this pipeline — from a handful of parameters, through four silicon chips, out to your speakers. Each component is a gear in the machine. Nothing leaves the box.

▸ PHASE 1 — PROMPT CONSTRUCTION Musical Parameters D minor · BPM 118 · 8 bars Dm7 · Am7 · Bbmaj7 · A7 key / tempo / style / chords Blueprint MusicalBlueprint Pydantic model Token Prompt BOS + set_tempo + patch_changes role channels + event context → MIDI token stream Source MIDI previous pattern last 8 bars context optional chaining ▸ PHASE 2 — HARDWARE GENERATION TENSTORRENT HARDWARE — 4× P300C forge.compile 12-layer LlamaModel ~45s first call P300C #0 tensix mesh P300C #1 tensix mesh P300C #2 tensix mesh P300C #3 tensix mesh hw_context_interval = 4 HW net called every 4 events ~500ms PCIe dispatch per call CPU net_token (3-layer, ~50M params) runs between hardware refreshes · top-p / top-k sampling per token cpu cpu cpu HW cpu cpu cpu HW cpu ··· ··· ▸ PHASE 3 — GENRE STRUCTURE & IMPROV Genre Structure · deterministic walking bass drum groove phrase gaps Improv Layer · stochastic · seeded approach notes tension arc P1 → P2 → P3 ▸ MUSIC THEORY COHERENCE Coherence Layer scale_quantize chord_aware_filter humanize_velocities swing · nudge_timing ▸ PHASE 4 — TESTING & RECIRCULATION Quality Judge rule_score = max(0, 1 − 0.12 × n_issues) · pass threshold: 0.55 ✓ PASS → continue to output ✗ FAIL → re-roll pattern re-roll up to 3× GM MIDI FluidSynth loop player 🔊 speakers Hardware Synthesizer MIDI keyboard / module any MIDI-capable device DAW / Software Synth Ableton · Logic · Reaper VST / AU · ALSA port

forge.compile — one line to the metal

tt-forge compiles the 12-layer LlamaModel onto the 4-chip P300C mesh with a single forge.compile() call. No kernel writing, no hardware-specific code — standard PyTorch in, silicon execution out. ~45s first compile, then 121/121 JIT cache hits on every subsequent run.

hw_context_interval — the key optimization

Hardware is called every 4 events (not every step). Between calls, the CPU 3-layer net_token generates with the cached hidden state. This amortises the ~500ms PCIe dispatch cost and yields 7.7 ev/s vs 2 ev/s naive.

Source MIDI context — musical chaining

The last 8 bars of the previous pattern are tokenized and prepended to the next prompt. The model reads the previous music before writing new material, creating coherent progressions across all four patterns.

Coherence layer — music theory post-processing

Four passes clean up raw model output: scale quantization (D Aeolian), chord-aware filter (keeps chord tones on beats), velocity humanization (natural dynamics), and micro-timing nudge (±10ms groove feel).

Genre structure layer — deterministic skeleton

Applied after model generation, not inside it. Walking bass (root → 3rd → 5th → chromatic approach), genre drum groove (shuffle, swing ride, or straight), and call-response phrase gaps — all deterministic given the chord progression. The model generates melody; the structure layer makes it sound like the genre.

Improv layer — stochastic variation

Seeded random layer that adds chromatic approach notes before chord-tone downbeats, displaces note timing by ±half-beat, and transposes melodic material by a semitone shift for cross-pattern development. A tension arc (0.0 → 0.3 → 0.6) increases density from pattern 1 to pattern 3 — the music opens up as it progresses.

Quality judge — rule-based gating

Eight heuristics score each generated pattern: notes-per-bar density, pitch span, unique pitches, mean/max melodic intervals, direction reversal ratio, silence ratio, rhythmic cluster ratio, and register overlap. Score = max(0, 1 − 0.12 × issues). Patterns below 0.55 are discarded and re-rolled up to 3× — the best attempt is kept.

tt-forge — PyTorch to silicon in one call

Every note in every demo on this page was generated by a transformer running on Tenstorrent P300C chips. The bridge between standard PyTorch and that silicon is tt-forge — Tenstorrent's open-source compiler frontend. No CUDA. No custom kernels. No hardware expertise required.

Before tt-forge

Running a model on custom accelerator hardware means writing device kernels, managing memory layouts, and handling chip-specific dispatch. Standard ML frameworks don't speak hardware natively — you need a compiler layer between them.

# Without tt-forge: hardware-specific kernel code, # manual memory management, chip coordination… # hardware-specific setup code omitted

After tt-forge

One function call compiles your existing PyTorch module for the full 4-chip P300C mesh. The compiler handles graph optimization, kernel generation, and multi-chip dispatch. You keep writing Python.

import forge # your existing nn.Module — unchanged compiled = forge.compile( model.net, sample_inputs=[prompt_tensor], ) # run it exactly like PyTorch output = compiled(tokens)
1
function call
to compile any PyTorch model for TT hardware
speedup
vs naive single-chip dispatch (hw_context_interval=4)
121/121
JIT cache hits
second run — compile once, run forever

tt-forge is what makes this practical. Running a 350M-parameter transformer on four P300C chips at real-time speed requires a compiler that understands the hardware — tt-forge handles that so the Python stays standard PyTorch. The music is the demo. The compiler is the story.

tt-forge on GitHub Tenstorrent.com

The model doesn't know what sounds good

Raw transformer output is probabilistic — the model generates tokens it finds likely given the context, not tokens that form a musical phrase. The result without filtering is what it sounds like: rhythmic pile-ups, melodic zigzag, silence-free walls of notes. The quality judge exists to catch this before it reaches your speakers.

Rule-based metrics

8 musical correctness checks

  • Notes per bar — too sparse or machine-gun
  • Pitch span — monotonous or scattered
  • Mean / max interval — random leaps vs stepwise motion
  • Direction reversals — melodic zigzag detector
  • Silence ratio — breathing room check
  • Rhythmic clustering — half-beat pile-up
  • Register overlap — bass invading melody's range
  • Unique pitches — repetition floor
Re-rolling

Best of N candidates

Every generation call scores the result against the rules. Patterns below threshold are discarded and regenerated — up to 3 attempts per pattern, keeping the highest-scoring result.

Audit of 22 committed patterns: 86% pass rate before re-rolling was enabled. The single-voice monosynth format scored highest — two patterns at 1.00 (no issues detected).

Perplexity scoring

Model self-evaluation

Beyond rules: the model evaluates its own output. Two batched forward passes compute mean negative log-probability of event-type tokens — how "surprised" the model is by the sequence it generated.

Lower NLL means the model found the sequence plausible. High NLL often correlates with audible jumble. Available as a secondary signal via scripts/analyze_quality.py.

Most common quality failures across 22 patterns
Rhythmic clustering
Notes landing within 24 ticks (half a beat) of each other. Results in a "stacked" sound where rhythm blurs into a block chord feel.
Melodic zigzag
>75% of melodic intervals reverse direction. Sounds like a random walk — up–down–up–down with no phrase shape.
No breathing room
Silence ratio below 8%. When notes fill every tick with no rests, the track loses dynamics and all musical phrasing.

Compose from any AI assistant

tt-midi-maker exposes every generation and playback capability as a standard MCP server. Connect from Claude Desktop (or any MCP-compatible client) and compose interactively — the assistant can generate loops, continue patterns, analyze what it made, and play it back through your speakers, all without leaving the conversation.

// ~/Library/Application Support/Claude/claude_desktop_config.json { "mcpServers": { "tt-midi-maker": { "command": "python", "args": ["-m", "tt_midi_maker"], "cwd": "/path/to/tt-midi-maker", "env": { "MIDI_LLM_URL": "http://localhost:8000/v1" // local LLM endpoint } } } }
Generation
generate_midi

Generate a multi-track MIDI file from a natural language prompt. Returns a file path and hardware stats.

Generation
continue_midi

Extend an existing file by seeding the model with its last 4–8 bars. Writes a new file; original untouched.

Generation
set_musical_context

Lock in key, BPM, style, and chord progression for the session. All subsequent generates respect these values.

Analysis
describe_midi

Analyze a MIDI file: key, tempo, bar count, track inventory, chord guesses, style guess, prose description.

Analysis
chat_with_midi

Ask any musical question about a file. "Why does bar 4 feel tense?" "How do I make this more 90s R&B?"

Devices
list_midi_devices

Enumerate all ALSA sequencer ports (USB synths, BT devices, DAW loopbacks), soundfonts, and active playback jobs.

Playback
play_midi

One-shot playback via FluidSynth or any ALSA port. Per-channel routing: send melody to one synth, bass to another.

Playback
stop_playback

Cancel a background playback job by its job_id. Stops within ~100 ms.

Streaming
synth_start

Launch a persistent FluidSynth server for real-time loop playback. Call once per session before loop_play.

Streaming
loop_play

Start looping a MIDI file immediately — tight real-time loop, no gap between iterations, monotonic clock timing.

Streaming
loop_queue

Queue the next pattern to take over at the next loop boundary. The current loop keeps playing until its end.

Streaming
loop_stop

Stop the loop after the current phrase ends (clean), or immediately with all-notes-off on every channel.

Quick Loop

Best starting point. Provide a style, optional key, and bar count — the assistant calls set_musical_context then generate_midi and returns a ready-to-play loop.

Build a Song Section

Guided 5-step workflow: set context → generate seed → describe → extend to full length → describe final. Ideal for verse/chorus/bridge with real internal development.

Analyze and Improve

Point it at an existing file and a goal ("make it more tense", "resolve the harmony"). The assistant diagnoses what's wrong and recommends whether to regenerate, continue, or re-context.

Collaborative Session

Open-ended start. The assistant asks about style, mood, instrumentation, and reference tracks, then begins generating and iterating — a co-composer in your chat window.

Real-time loop

Generate once, then keep improving while the music plays
set_musical_context synth_start generate_midi loop_play while playing… generate_midi loop_queue loop_stop

Iterative composition

Generate → analyze → improve in a conversation loop
set_musical_context generate_midi describe_midi chat_with_midi continue_midi play_midi

Multi-pattern chaining

Each pattern hears the previous — how Silicon Road and every suite was made
set_musical_context generate_midi( "cold start" ) → p1 generate_midi( source=p1 ) → p2 generate_midi( source=p2 ) → p3 play p1 → p2 → p3 …
midi://session/context

Active key, BPM, style, and chord progression. Read before generating to confirm the session context is set.

midi://hardware/status

Connected Tenstorrent devices, active model, and generation backend. Check when generation is slow or failing.

midi://styles/catalog

Full styles catalog — BPM ranges, keys, roles, and example prompts for all 20 styles. Consult before prompting.

midi://output/{filename}

Fetch a previously generated MIDI file by name. Returns raw MIDI bytes for download or further analysis.

20 styles. One sentence to any of them.

Every style has calibrated defaults: BPM range, typical keys, instrument roles, swing ratio, and example prompts. Feed these directly to generate_midi or mix and match — the model handles the rest.

Electronic & Hip-Hop
Lo-Fi Hip Hop
70–90 BPM · swing 0.55
pensiveoozyorganic
"dusty vinyl drums, sparse piano, melancholic bass"
Hip Hop
80–100 BPM · swing 0.55
tenseexuberantsynthetic
"trap hi-hats, 808 sub, synth melody, punchy snare"
Drum & Bass
160–180 BPM · no swing
tenseexuberantsynthetic
"amen break chops, rolling sub bass, minimal arp"
Synthwave
90–118 BPM · no swing
atmosphericsyntheticpensive
"arpeggiated poly synth, analog bass, gated reverb drums, lush pad"
IDM
100–160 BPM · no swing
glitchysynthetictense
"glitchy polyrhythmic drums, filtered acid bass, melodic arp, evolving pads"
Detroit Techno
128–138 BPM · no swing
tensesyntheticatmospheric
"hard kick, minimal acid bass, sparse chord stab, cold pad"
Jazz & Swing
Jazz
120–200 BPM · swing 0.65
pensiveexuberantorganic
"walking bass, piano comping, trumpet melody, brushed kit"
Bossa Nova
120–160 BPM · no swing
pensiveorganicethereal
"brushed snare, walking bass, piano melody, nylon guitar chords"
Blues
60–130 BPM · shuffle 0.65
pensiveorganictense
"12-bar blues, guitar lick call-response, walking bass, shuffled kit"
Ska
160–200 BPM · swing 0.5
exuberantorganic
"offbeat keyboard chop, walking bass, horn stabs, snare on 2 and 4"
Rock
Surf Rock
140–180 BPM · no swing
exuberanttenseorganic
"reverb-drenched tremolo guitar lead, locked bass and drums, twangy arp"
Post-Rock
60–140 BPM · no swing
atmosphericpensiveethereal
"quiet clean guitar swell, slow build, crashing drum climax, lush string pad"
World & Latin
Afrobeat
100–130 BPM · no swing
exuberantorganic
"interlocking polyrhythm drums, bass guitar groove, horn stabs, keyboard vamp"
Cumbia
100–120 BPM · swing 0.2
exuberantorganic
"caja drum pattern, bass guitar ostinato, marimba riff, accordion harmony"
Cinematic & Classical
Classical
60–180 BPM · no swing
pensiveetherealexuberant
"piano melody, string ensemble accompaniment, pizzicato bass"
Nino Rota
80–140 BPM · swing 0.4
pensiveorganicethereal
"accordion-style melody, circus waltz rhythm, pizzicato bass, orchestral color"
Dark Cinematic
60–110 BPM · no swing
tenseatmosphericethereal
"low cello ostinato, tension pad swell, distant brass, sparse piano"
Ambient & Experimental
Ambient
60–90 BPM · no swing
spaceyetherealatmospheric
"slow pad swells, sparse high melody, atmospheric fx, no percussion"
Dark Ambient
40–70 BPM · no swing
spaceyoozytense
"glacial drone, low sub rumble, sparse high tone, evolving noise texture"
Glitch
90–150 BPM · no swing
glitchysyntheticchaos
"fragmented micro-rhythms, stuttered bass, granular pad, unstable pitch fx"

The next pattern is ready before this one ends

The Quietbox 2 runs the 350M-parameter composition model at 7.8 events per second — fast enough that a full 8-bar phrase is written in 12.3s, while the previous one loops at 16.3s. No cloud. No latency. Your art runs on your machine.

7.8
events / second
sustained throughput
0.76×
loop ratio
generation vs. playback time
speedup
hw_interval=4 vs. interval=1
24
hw calls / pattern
96 events ÷ interval 4
hw_context_interval max_events generation time ev/s loop ratio real-time?
1 (every step)6435.3s22.5× ✗ too slow
4 (default)9612.3s7.80.88× ✓ fits in 1 loop
812810.8s11.90.77× ✓ comfortable

Key files

forge_backend.py — hardware generation

generate_hardware( compiled_net, # forge-compiled LlamaModel model, # full MIDIModel (CPU) prompt, # seed token array hw_context_interval=4, max_events=96, )

midi_backend.py — orchestration

generate_from_blueprint( blueprint, # key/bpm/chords/roles roles_config, # GM channel map source_midi="prev.mid", hw_context_interval=4, )

stream_player.py — live loop playback

start_synth(gain=2.5) loop_play("p1_intro.mid") loop_queue("p2_variation.mid") # transitions at loop boundary, no gap

server.py — MCP interface

# 12 tools exposed over MCP: generate_pattern # create MIDI synth_start # launch FluidSynth loop_play # start looping loop_queue # queue next pattern loop_stop # graceful or immediate

Your personal AI machine,
for whatever your art is

Four P300C chips. Silent. Always on. No subscription, no cloud, no rate limits. The Quietbox 2 runs models the way instruments run scales — immediately, locally, yours. This project is proof: a full multi-track composer across jazz, blues, ambient, and bebop, running faster than real time, on hardware that fits on a shelf. All of it compiled by tt-forge from plain PyTorch.

Tenstorrent.com tt-midi-maker → tt-forge →