Generating retro arcade game-style music with Magenta.js
Tags: audio, gamedev, javascript
Published: 2022-05-21 01:41:42

In this article, games from the early 1980s or so are considered retro arcade games. Examples are Xevious and DigDug. The BGM of retro arcade games of these days often consisted of repeating short phrases of about 4 to 8 bars.

I thought I would like to have such BGM for my mini-games and, if possible, generate it automatically. Therefore, I was looking for a technology to create such BGM.

[WolframTones](https://tones.wolfram.com/about/how-it-works) is one such technology. WolframTones cuts out cellular automaton and turns them into melodies. It can easily create a variety of songs. However, it doesn't seem easy to reproduce specific phrases often seen in old games, such as a bass that reciprocates in perfect fifths with sixteenth notes, due to the characteristics of a cellular automaton.

An example of the latest technology is OpenAI's [Jukebox](https://openai.com/blog/jukebox/). However, this is not intended for retro games, as it generates musical waveforms, not musical scores.

The following technology I looked into was [Magenta](https://magenta.tensorflow.org/), a research project by Google that applies machine learning to music and pictures. [Magenta.js](https://hello-magenta.glitch.me/) is available as an implementation that can run in the Magenta browser.

Magenta.js has [MusicRNN](https://magenta.github.io/magenta-js/music/classes/_music_rnn_model_.musicrnn.html), which automatically generates the following phrases when entering a musical score. I thought that if I gave it a short score of a retro game, it would create another song like the background music of the retro game. So, I tried to prototype the following.

- [Short VGM generator](https://abagames.itch.io/short-vgm-generator)

Pressing the "Generate" button in the center of the screen generates a new phrase based on the phrase on the left of the screen. The generated phrase is displayed on the right side of the screen and played back. Although it is a simple phrase generation consisting of only two tracks (melody and bass), it can create music like retro game background music.

One problem is that I could not figure out how to input multiple tracks as original phrases in Magenta.js. Therefore, I created separate phrases for the melody and bass. I also adjusted the sound of the bass when the bass was dissonant with the melody. The bass sound is adjusted so that the frequency of the melody sound is in the ratio of 1 to 4. Unchecking the checkbox at the bottom of the screen eliminates this adjustment, thus generating a freer phrase.

Another problem was that the Magenta.js built-in player was not capable of simultaneous speech. Therefore, I use [Tone.js](https://tonejs.github.io/) for playback. I also find it easier to input phrases using MML, so I use [mml-iterator](https://github.com/mohayonao/mml-iterator) to parse MML and convert it into a form that Magenta.js can handle.

Please refer to the following repository if you wish to use the generated BGM in your game.

{% embed https://github.com/abagames/good-old-game-sound-generator %}

It would be nice to generate sound effects similarly, but since MusicRNN is only intended to create melodies, it does not seem possible to take the same approach.

- [Super Mario Melodies](http://www.losdoggies.com/archives/1302)

The above article has a score of Super Mario Bros. sound effects. The game's sound effects are too specific to be seen in a musical score. Therefore, finding relevant research on sound effect generation methods based on musical scores is probably tricky. Most of the existing sound effect generation tools are based on [sfxr](http://www.drpetter.se/project_sfxr.html)-based waveform generation methods, and I have not seen any that generate them as musical scores. Further research is needed on automatic sound effect generation for retro games.