Gbsplay and the perfect looping ringtone

2011-06-28 21:06

There are three characteristics of a good telephone ring tone. It should be unique, so I don’t reach for my phone along with three other people in a room. It should be noticeable and easily picked out of background noise. It should be inoffensive and suitable for mixed company.

With that in mind, I decided to extract a loop from the Game Boy Camera for my new tone. I obtained a rip of the game’s music in GBS format, similar to the NES/Famicom’s NSF, and found a player for Unix-like operating systems, gbsplay. The player is actually a specialized emulator, emulating the Game Boy sound hardware for playback of the GBS file.

I found the track I wanted, the title screen music from Trippy-H, but had to find a way to get PCM audio out of gbsplay as a file. The manpage mentioned a “stdout” output mode, but there was no documentation of the format it puts out. After some experimentation, I determined the output to be headerless 16-bit audio encoded as signed integers with a sample rate of 88200Hz.

With this information, we can lower gbsplay’s verbosity level to zero (-qqq), pipe its output to SoX, and get a PCM/WAVE copy of track #48:

  1. gbsplay -qqq -o stdout "Gameboy Camera (1998)(Nintendo).gbs" 48 48 | sox -t raw -r 88.2k -e signed -b 16 - -t wav 48.wav

Play the file. It sounds exactly like the real thing!

Audacious editing the ringtone-to-be into a short loop.

A two minute-long ringtone isn’t ideal. Audacity, a free open-source audio editor, can trim our wav file into a short loop. In this case, the two-minute track trims to a loop just five seconds long. Test the loop with Audacity’s looping-play by pressing Shift+Play.

Now we can use an undocumented feature in Android that makes it loop Vorbis files gaplessly if they have a custom “ANDROID_LOOP” tag set to true. oggenc can do this for us. Add some other tags as well. The title tag (-t), for instance, will show up in the ringtone selection menu.

  1. oggenc 48.wav -t "Trippy-H" -a "Hirokazu 'Hip' Tanaka" -l "Pocket Camera" -c "ANDROID_LOOP=true"

Finally, the test!