---
slug: /gambeta-music/
url: https://zajdband.com/gambeta-music/
markdownUrl: https://zajdband.com/gambeta-music/index.md
title: 'Gambeta''s music: from anything that looks like a score to a Game Boy'
description: >-
  Gambeta, my Game Boy style football game, has more than thirty songs and not a single audio file.
  The tools Claude built so I could turn MIDIs, karaokes, Guitar Pro tabs and even a choir score
  into four Game Boy channels, choosing by ear. You can play with all of them here.
published: '2026-10-22T15:00:00.000Z'
updated: '2026-10-22T15:00:00.000Z'
language: en
category: Games
tags:
  - gambeta
  - web-audio
  - midi
  - games
takeaways:
  - >-
    Gambeta has more than thirty songs and no audio files: every note is a Web Audio oscillator, in
    four voices like a Game Boy's (a square, a 25% pulse, a triangle and filtered noise).
  - >-
    Converting a MIDI to four channels is a hundred lines of code. Deciding which track plays what
    can only be done by listening.
  - >-
    When a song had no usable vocal line, it came from somewhere else: a Guitar Pro tab, a PDF choir
    score lined up with the karaoke's lyrics, or a sequence played by hand on a website,
    straightened with a fitted line.
  - Claude wrote the code and built the tools. Dan chose by ear.
wordCount: 1758
readingMinutes: 9
license: https://creativecommons.org/licenses/by/4.0/
draft: false
recipe:
  name: chiptune-from-any-score
  description: >-
    Turn a song into four Game Boy style voices (melody, harmony, bass, drums) from whatever
    notation exists for it: a MIDI, a karaoke file, a Guitar Pro tab, a PDF score or a web
    sequencer. Use when someone wants chiptune versions of real songs for a game or a toy, or asks
    how to get a melody out of a MIDI that does not have one.
  url: https://zajdband.com/.well-known/agent-skills/chiptune-from-any-score/SKILL.md
---

I launched [Gambeta](https://gambeta.futbol), a neighbourhood football RPG that looks like a Game Boy Color. You arrive at the boarding house of Club Atlético Zapallitos with your cousin's borrowed boots, and in one season you have to get the club promoted, taking the bus to the strangest pitches in the league. It is free, and it runs in the browser, on a computer or a phone.

This is the first post in a series about how Gambeta was made, and I am starting with the music, because it is the part I enjoyed the most. The game has more than thirty songs and there is not a single audio file in it. I did not write the code: Claude did. I chose by ear.

## Four voices, and nothing else

The Game Boy has four sound channels: two pulse waves, one programmable wave and one of noise. Gambeta does the same with Web Audio. Every note is an oscillator that starts at the moment it plays: a square wave for the melody, a 25% pulse for the harmony, a triangle for the bass and filtered noise for the drums. Turn them off one by one:

<div data-toy="radio"><p><em>Interactive: songs from the game, with each of the four channels on or off, scrolling as they play. Needs JavaScript.</em></p></div>

The cassette is for the bus. The Turco, who drives it, has a tape deck with a broken speaker, and any song in the game can go through it: a narrow band, a bit of overdrive, tape hiss and two slow oscillators bending the pitch, like stretched tape.

## Any MIDI, four channels

The songs come from MIDIs. A MIDI has a dozen tracks with chords, and a Game Boy channel plays one note at a time, so the conversion is simple: each channel takes some tracks of the MIDI, from each chord the melody keeps the highest note and the bass the lowest one, and everything snaps to a grid of sixteenth notes. The hard part is not the code. It is deciding which track does what, and that can only be done by listening.

So Claude made me a page for it. I open a MIDI, every track has its ▶ to hear it alone, already in the Game Boy voice, and I tell it what it plays: melody, harmony, bass or drums. Then the section of the song, whether it has cymbals, and, if the MIDI's drums sound bad, a rhythm of our own: cumbia, rock, candombe, a march or the bombo of the terraces. This is that page, with the game's own converter. It opens with Live Is Life, the song Maradona warmed up to, which plays in the game's keepy-uppy minigame:

<div data-toy="converter"><p><em>Interactive: the game's MIDI converter. Drop any MIDI or karaoke file, hear each track alone, choose what each one plays and listen to it as a Game Boy. Needs JavaScript.</em></p></div>

Drop any MIDI you have there, it does not leave your browser. When it opens, the page guesses with a rule of thumb: channel 10 is the drums, the lowest track is the bass, the highest one with plenty of notes is the melody. With Live Is Life it gets the tracks right, and what the game adds is the section: from bar 17, for 65 bars. With most MIDIs the guess is only a place to start listening.

The real page has two things this one does not. A search box: I type the name of the song and it looks on the sites that give away MIDIs and karaokes. They were chosen by trying them: karaokes.com.ar for Argentine rock and cumbia, midiworld for the rest. midisfree has more, but cuts you off at three downloads a day. And a box to ask Claude for things in words, which is at the end.

## Not only MIDIs

Not everything I threw at it was a MIDI. Often it was a karaoke file, a `.kar`, which is a MIDI with the lyrics inside: *Las olas y el viento* for the coast and *Bestia pop* for the road came like that. Sometimes it was a Guitar Pro tab, a `.gp5`. Once it was a PDF with a choir score. And once, a link to a website.

The problem is almost always the same: the voice is missing. A karaoke does not have it, because the voice is yours. Then the melody comes from whatever doubles it: a flute, the strings, a trumpet. When nothing doubles it, you have to get it from somewhere else.

**A Guitar Pro tab.** For *Please Me*, which plays in the country club, the only MIDI was a transcription from audio and you could not understand anything. On Songsterr the tab had the vocal line. A Guitar Pro file is not a MIDI, but it is close: Claude wrote a thirty line script that reads the `.gp5`, one track per instrument, and joins the tied notes, which in a tab are two notes and in a song are one. I download the tab with my account and drag it into the page.

**A PDF with a choir score.** *En el país de la libertad*, by León Gieco, plays on the hill. The karaoke MIDI has the band and the harmonica, and no voice. So I threw a PDF at Claude: a choir arrangement of the song by Christian López. Claude read the score and wrote it into a script, note by note: the melody (the altos in the verses, the first sopranos in the chorus) and a second voice. It raised them from D to F sharp, where the MIDI is, and here the karaoke's lyrics were useful: each phrase starts where the lyrics say it is sung.

<div data-toy="gieco"><p><em>Interactive: the karaoke MIDI alone, then with the melody from the choir score, then faster. Needs JavaScript.</em></p></div>

The third button is mine: I liked it faster, and in the game it plays at 88.

**A sequence somebody played by hand.** The march that plays at Luz y Fuerza, the club where the lights keep going out, is on onlinesequencer.net, a site where people write songs in the browser. What the site gives you is a protobuf. Claude decoded the protobuf by hand, without a library, and found everything mixed in one instrument. It split it by volume, which is how the person who wrote it had built it: the loud notes are the melody, the middle ones the accompaniment, the soft and low ones the bass.

It had another problem. The person had played it by hand and drifted: by bar 31, the accompaniment was more than a sixteenth late, so after snapping to the grid every note landed one step behind. The accompaniment plays on every half bar, so the script measures how far each of its notes is from that grid, fits a straight line, and moves everything back.

<div data-toy="marcha"><p><em>Interactive: how late each note of the accompaniment is, with the line fitted to it, and the march as it was played, straightened and as techno. Needs JavaScript.</em></p></div>

Then I asked for it "a bit faster and a bit more techno", and when it came back, "a bit much, maybe slower". It ended at 132: a kick on every beat, a clap on two and four, the hi-hat on the offbeat and the bass pumping.

## Choosing by ear

Most of my work was listening and saying what was wrong. *Seguir viviendo sin tu amor*, by Spinetta, plays in the fourth round. The MIDI has no voice, and in the verses all that was left for the melody was three loose taps per bar. It sounded horrible. The verses have the same chords as the guitar riff, so Claude put the riff there and moved the taps to the harmony, which is what they do in the intro:

<div data-toy="spinetta"><p><em>Interactive: the verses of Seguir viviendo sin tu amor as the MIDI had them, and with the riff. Needs JavaScript.</em></p></div>

Other notes, from the log: Live Is Life lost its four bars of bass and drums at the start, and I asked for them back. The carnavalito written for the hill was "very fast and weird", and Gieco took its place. *Mi enfermedad* slowed down for walking around the neighbourhood was a downer, and went back to its tempo, with drums and chords.

Not everything comes from a MIDI. Where there was no song to put, Claude composed one: a chacarera for the farm, a chamamé, a murga for the derby. They are Python scripts that write the notes, and they copy nothing. Two of them did not survive my ear: the carnavalito, and the chamamé, which gave its place to *El tren del cielo*. The chacarera is in the radio at the top.

## Asking for it in words

The page also has a box to ask Claude for things, in words: "the melody should be the trumpet", "start at the chorus", "calmer". It runs the Claude Code on my computer, with no tools, so it only thinks, and it does not need a key. What it receives is a summary of the MIDI, with what is chosen right now and what I ask. This is the start of the one for Live Is Life, in Spanish, as it goes:

```text
MIDI: liveislife.mid, 82 compases (de 0 a 81), 90 bpm.
Pistas (indice: nombre, instrumento, notas, registro, donde toca):
  2: "Rhythm Guitar and Bass" (acoustic guitar (steel)), 1225 notas, C2-C5 (promedio B3), toca en los compases 5-54, 63-80
  3: "Na Na Na Na Na (Second Voice)" (lead 3 (calliope)), 286 notas, G4-G5 (promedio D#5), toca en los compases 7-54, 63-80
  4: "" (applause), 20 notas, D5-G5 (promedio F5), toca en los compases 55-61
  5: "Flat Akkord Sound" (fx 2 (soundtrack)), 329 notas, F4-C6 (promedio C5), toca en los compases 5-80
  6: "Singer" (rock organ), 273 notas, G5-C6 (promedio B5), toca en los compases 12-80
  7: "Audience Life" (applause), 24 notas, E4-E4 (promedio E4), toca en los compases 0-5, 81
  8: "Drums Fills" (bateria), 111 notas, B1-C#3 (promedio F2), toca en los compases 2-10, 16, 20-21, 46, 55-62, 66, 70-71, 80
  9: "Main Drum Patterns" (bateria), 724 notas, B1-A#2 (promedio E2), toca en los compases 1-54, 63-79
```

It answers with a JSON schema: one or two sentences for me, the new choices, which the page applies and plays, and a note for whatever the page cannot do, like where in the game the song plays. That note goes to the same inbox where I leave the rest of my notes for Claude, and another session does it in the code.

## Closing

More than thirty songs, from MIDIs and karaokes, one Guitar Pro tab, one choir score, one hand-decoded protobuf and a few Python scripts, and no audio files. You can hear them all in [Gambeta](https://gambeta.futbol). The keepy-uppy minigame is a rhythm game that reads the drums of the song that is playing, so Live Is Life is also a level.

If you have a MIDI of a song you like, drop it in the converter above and tell me how it sounds.

## Next in the series

This was the first post about how Gambeta was made. The next ones are about how you direct a game you are not writing: the page where I decide what goes in, the inbox of notes for Claude and the bible that keeps the world from contradicting itself. Then the match engine and the simulator that plays hundreds of matches to measure the difficulty, and the merch, drawn with the game's own sprites.

<script type="module" src="/gambeta-music/toys.js"></script>
