random audio generation and the game "Dreamworld Adventure"

Introduction

I've been experimenting with semirandom music generation for a few years.

My own goals have been to produce something I can sing to and also have sheet music for. I love sheet music.

However, I recently found out about the music for the old game "Dreamworld Adventure."

As soon as I heard it, I recognized the tell-tale sound of semirandom music.

Because of that, I was inspired to release an album of semirandom music. "Blanket Solutions." Not quite an album-a-day, but 19 minutes with 6 . tracks .

Differences between mine and theirs

If you compared the two, you'd find some clear differences.

My own stuff repeats patterns in sequence. There's a "chorus" pattern, a "verse" pattern, and a structure that may include an intro, outro, and bridge. (I didn't use any bridges on my recent album.)

The video game has nothing like that. No structure. No repetition.

Because I have a structure, and I wanted some additional variance, in addition to generating the chords, the tune, and the base line, I also generate a "drone" track that exists for every other vocal unit, regardless of whether it is a chorus or verse.

Four tracks. In the "mkrandom.sh" version here, there's two more generated, a very weak attempt at drums -- one I ignore and program directly in LMMS -- and a marker track to help with singing. The marker track signals the start of each vocal unit so that I can have a visual clue of where I am in my DAW. Since my album was instrumental, though, that was unneeded.

(In the included sample OGG file, I only have the relevant bass and melody tracks enabled, but the LMMS project has all tracks mapped to native LMMS virtual instruments -- using MIDI ties it to a specific external SF2 file -- so you should feel free to experiment. The only place it diverges from the MIDI is that instead of the MIDI-contained drum track, I emulated it natively within LMMS.)

Minimizing the differences

What happens when I strip out the structured repetition and the unneeded tracks?

It turns out, I find a whole bunch of bugs. I also drop around 1,100 lines of code. (Dropping over 80% of the lines of code.)

It was not quite like the sound track, though. I was using a walking bass line, and the bass line in the game is different. Still, simple to fix.

The resulting script is "mkost.sh". I confirmed that this sounds close to the original sound track. It's much tinier than my original script.

Going too far

Can it be smaller? What if I drop all notion of chords and just keep it in the key of C?

That's in the "mklite.sh" script, and while it does reduce some lines, it does not sound better.

Keeping to a chord makes it sound far more like a song, as well as more like the game.

Concluding the experiment

So, we're left with a 230 line Bourne shell script to get a pretty close approximation to the sound of "Dreamworld Adventure." (This is the mkost.sh script.)

It's my belief that, rather than some grand generative system for the music, the author whipped this up because he couldn't write music of his own. There's a concept of music -- chords are used, after all -- but the implementation is very much like the rest of the game, sort of lopsided.

There's distinctly a randomized component to the music. But, where I added more interest to the song by adding repetition and additional voices, I believe there may be different canned variations added in the game's soundtrack. (This explains the appearance of a scale or other structure inserted that sometimes appears in the game's sound track.)

Again, for the game, I believe that sometimes a random number is hit, and a canned pattern is inserted.

Further experiments on your own

Dependencies:

  1. A Bourne-type shell (GNU Bash 2.x and above should work. Maybe earlier, too) -- to generate .ly files.

  2. Lilypond -- to compile the .ly file to .midi

  3. LMMS -- to import .midi to .mmpz, and then render the .mmpz to .ogg.

  4. A music player -- Something that can play .ogg files.

  5. A functioning auditory system. -- Though without this, you can ditch LMMS and work with other tools to render MIDI in to a format you can enjoy.

What I have here are three Bourne shell scripts. (I used BASH and did not test for BASH-specific features. The smaller scripts use arrays, but not the newer [[ test operator. If BASH-specific, it should still work with old versions.)

They generate Lilypond source code which should be piped to a file. (./mkost.sh > ost.ly and the like.)

The Lilypond source file needs processed by the lilypond command. My original was designed to generate random sheet music for songs, so will produce PDF files as well as a MIDI file. The mkost.sh script will only produce a MIDI file. (lilypond ost.ly producing ost.midi.)

The MIDI file will sound nothing like the video game, though. You need to start LMMS, import the MIDI file, and assign each of the two tracks either the same or different instruments. (LMMS has a number of virtual instruments, some of the bundled instrument configurations should be good-enough to compare with the game's sound track.) LMMS can then export the track for listening elsewhere.

With the correct virtual instrument, the LMMS output will sound pretty much like the video game.

Again: It is a 230 line shell script. This can be seen as a starting point to a generative music experiment, as you can tweak things to try to make it more (or less) like the video game's soundtrack. This should be easy enough to rewrite in pretty much any half-decent scripting language. If you make a variant of this for yourself, give me a shout, either yam655 on yam655.com or @yam655@sonomu.club in the Fediverse.

My own mkrandom.sh script is an example of how getting too complicated in a Bourne shell script can lead you to some trouble. Using something which makes testing easier would be useful. I'm planning a Python 3 version for a later post.

Other files

  • random.ogg

    🎧 LMMS generated audio from the 'random.mmpz' file (03:12)

  • random.mmpz

    LMMS project with mkrandom.sh sample MIDI after import/cleaning

  • random.ly

    🎼 mkrandom.sh sample output used to generate more concrete examples

  • random-lead.pdf

    🎼 mkrandom.sh also produces lead sheets, this is from the 'random.ly' sample

  • random-import.pdf

    🎼 mkrandom.sh produces this PDF with all instruments as an aid in development

  • random-import.midi

    mkrandom.sh sample output, after Lilypond compilation

  • ost.ogg

    🎧 LMMS generated audio from the 'ost.mmpz' file (02:17)

  • ost.mmpz

    LMMS project with mkost.sh sample MIDI after import/cleaning

  • ost.midi

    mkost.sh sample output after Lilypond compilation

  • ost.ly

    mkost.sh sample output used to generate more concrete examples

  • mkrandom.sh

    Shell script used to release 'Blanket Solutions'

  • mkost.sh

    Shell script for Lilypond generation in key of C with chord knowledge

  • mklite.sh

    Shell script for Lilypond generation in key of C without chord knowledge

  • lite.ogg

    🎧 LMMS generated audio from the 'lite.mmpz' file (02:16)

  • lite.mmpz

    LMMS project with mklite.sh sample MIDI after import/cleaning

  • lite.midi

    mklite.sh sample output, after Lilypond compilation

  • lite.ly

    mklite.sh sample output used to generate more concrete examples


🏡Home | 📚Blog | 🏬Products | 📝Services