As a lover of both rhythm games and trombone, of course I got Trombone Champ. Naturally, I wondered: can I control it on an actual trombone?
This video isn't new; I posted it a year ago on Twitter but that site is dead to me now. This longer-form content also gives me an opportunity to better explain the mechanics behind the video.
First, the trombone controller.
You'd think that you could easily control Trombone Champ by just detecting how far out the slide is, but you'd be wrong.
Trombone Champ songs have a two octave range, which is 39 notes; imagine splitting up a trombone slide into that many pieces. The slide on a tenor trombone is ~27 inches long, so each pitch would be less than an inch away from each other. That's too precise to be all that accurate. (Of course, people made controllers like this anyways, but you can see how much they struggle to get all the notes right.)
What if you could just play the notes on an actual trombone and detect the pitch?
It turns out the range of pitches in Trombone Champ go from low C (in the staff) to high C (way above the staff). Is that possible to play on trombone? Some streamer in the "make wacky controllers for influencer points" industry said that this range is impossible to play IRL but that's simply not true. High C is very doable; the highest note I can play is actually a few notes above it, and I'm not a professional trombone player.
As such, for me, it was easiest to play the actual pitches on my trombone, and translate those into input.
With the method settled, let's look at the code.
It's extremely slapdash. I'm not a member of the "make wacky controller for influencer points" industry; I'm in the "I bet I could hack this together in an hour" industry (last seen on Hacker News declaring "I could build THAT in a weekend"). This code was not designed to stand the test of time; it was designed to stand up to a two minute song, then fall over due to a slight summer breeze.
I setup the game window in a very specific spot on my computer (so I could figure out where each mouse position equated to which tone). I then used
Robot to send mouse events to the game. When I detect sound, I press the mouse down; when the sound ends, I lift it up again. Then I simply detect the pitch and, based on that, determine the Y-position of the mouse cursor.
Ah, but "simply detecting the pitch" turns out to be the extremely hard part of this problem. I thought this would be stupid easy - tuners exist, after all! But no, of course digital signal processing is hard. (Well, it might not be hard for someone who knows anything at all about processing audio, but all I know is how to hit "record" in Audacity).
I found a library, TarsosDSP, which provided the algorithms I needed (or at least, were good enough to hack this together). I'll be honest: I just played with configuration values until the pitches it detected seemed close enough.
The last tricky bit: pitches do not scale linearly. A low C is ~130hz, middle C is ~261hz, and high C is ~523hz. Thus I had to translate the pitches (log scale) into a linear scale to get the right position to place the mouse.
All that being done, I was too excited to try it out to properly transcribe or memorize the music ahead of time. Thus, I was playing it all by ear, which is why I flubbed some of the notes. Also, the pitch detection was laggy - it would sometimes take it a couple hundred milliseconds to catch up, meaning my input was always a little behind.
(I didn't render the actual trombone into the recording, either, because it's really distracting hearing both a real trombone and the silly Trombone Champ trombone at the same time. Obviously the silly one is more fun to hear.)
Anyways, that's that. Hope you enjoyed this silly endeavor.