🎼Functionally programming The King of Pop

Posted August 2017

Where were we?

In the previous post, we looked at the Haskell library Euterpea to create simple music using (functional) programming techniques. In this part, we’ll take some of these ideas further, and try to create something a little more like real (pop) music. As it’s concentrating more on the audio side than the coding side, I assume a little music / audio knowledge.

The King of Pop

It seems appropriate in the current light of EPA-destruction and climate treaty withdrawals that the mid-90s ode to the salvation of the planet by the late King of Pop himself, Michael Jackson.

Jackson’s most successful single in the UK

Bad

Of course, it is completely inappropriate to choose this song, as:

  • It’s almost five minutes long
  • Has an epic, non-conventional song structure
  • That key change mid-song…
  • It’s heavily produced – layered synths, R&B-like sections, rock guitars, live drums, strings sections, sound effects, gospel choirs, a harp (!), brass sections
  • Lots of funk elements (which rely on years of player experience), i.e. hidden complexity. This is a problem with code too.

But then, it wouldn’t be fun without a few challenges! We’ll concentrate on the earlier sections more than the epic ending, and lots of bits will be simplified (sorry!).

Making some music

Chords

  • 3-voices
  • Reference chords
  • In the right key

Drum Patterns

Luckily, the drum pattern here is relatively simple. The subtleties and performance are another matter, but we’re in the business of approximating here.

I find that the list format of line is useful for drum patterns, and it’s best if possible to keep these even measures, or you go mad. Eighth notes are good here, so let’s adopt that.

Just like clean coding, I find well named music variables can help understand the code. Here I’ve used vaguely onomatopoeiac names for drums, and later extracted these to allow duration variations; yes, I think I’ve just coined higher-ordered percussion. WAT.

Once we have that vocabulary defined, it’s easy to talk about simple drum patterns!

Note how we did the fill by re-using existing eighth-note definitions and using the tempo modifier to double the speed of the whole phrase. DRY in action! (the fill itself needs some work though, sorry, purists).

The cut function is very useful – note how it can take non-integer durations too - so reusing drum patterns is easy, as you can cut off the end (adding a fill instead) rather than duplicating a large part of the content. More DRY, essentially.

Your turn

Try it in your REPL:

playDevS channel $ rest qn :+: beat

Note that:

  • we add a small rest to help with the hiccups with some MIDI synths when starting playback
  • playDevS is the strict variant of playDev, which does timing better (see the interesting arguments around this behaviour from the creators).

Hi-hats

Layering sounds in MIDI

Note: this is not even vaguely a good idea. Your results will definitely differ. Rendering the output is the only guarantee, and even that’s not so much fun. So that said we’ll continue.

Thicken drums

I found the soundfont I was using (Timidity plus FreePat, I think) was nice in places but lacked some thickness in the drums, so creating that huge 90s drum sounds was challenging.

  • Thicker bass drums by layering a low tom (!), more like an 808 kick TBH, on to the bassdrum at a lower volume when we wanted the full weight of the drums (chorus, outro, etc)
  • Layering the electric snare on top of the acoustic one made a nice sound
  • The clap sound for the (second) bridge / pre-chorus I eventually got closer to (oh – the actual clap was totally broken for me) by using a little rimshot (too thin / short by itself), a high wood block at low volume to give the reverby strong percussive sound, with a bit of Cabasa (a latin shaker-like instrument) for the missing noise in the upper part of the spectrum. Phew.
  • Also for the second bridge, the drummer uses a gentle but very tight closed hihat. The sound I had was far too open (splashy / sizzly) even when closed. For the very tight sound I ended up overlaying a mute triangle (sharp decay, high tone) with a very quiet closed hihat. Not ideal, but better.

Phatten the bass

Subharmonics (octaves below the actual note) are nice when used well. This is a very blunt way of doing this. Remember we haven’t got any signal processing capabilities here – we’re committed to 100% General MIDI!

Spread the pads

Now I will confess a complete lack of knowledge around arranging pads and strings, so most of this feels very wrong. Perhaps someone out there can advise better practices.

The idea was to take the simple three-part harmonies and replicate across instruments, layering and mixing to get nearer to the sound. Several parts were transposed an octave up (transpose 12) to occupy more of the spectrum. Some parts had tension notes (e.g. sus9), which generally were only in the upper registers, sounded a bit too muddy otherwise. All in all, I had to keep turning the volumes down, it’s easy to drown the mix in midrange, when the actual song is very full.

What about us?

Drum fills

Percussion is tricky, and fills are definitely hard to learn or notate. As always it helps to be able to hear the parts individually (this drumming video is useful).

Eventually it comes down to the amount of time you can devote to obsessing over the exact fills – whether it’s getting them exactly right, or even bothering with the variations at all. Session musicians are often very, very good at what they do (without grabbing the spotlight)!

A useful tip was to run the whole thing at double speed using tempo 2, meaning that the eighth-note shortcuts defined earlier are re-usable for sixteenth notes.

Basslines

As an former / occasional dabbler in bass guitar and various bass-driven genres (Drum n Bass especially), I’ve long been aware the subtleties of “simple” basslines. As usual though, this one caught me out completely: the main four notes (A♭, B, D♭… and E♭) are simple… but the excellent rendition on the track has complexity in the form of timing nuances (funk!), dynamics, ornaments and variations / fills that make this sequencing very hard. I’m not going to lie: a huge amount of trial and error, and referencing bass tabs was necessary.

Repetition and sections

In the previous post I explained how coding could be used to avoid repetition in the notation of the music (at the expense of some complexity, of course). With the amount of variation that crept in, the usefulness of this actually decreased quite a lot, but never mind…

Simply assigning variables usefully, and using combinators like

  • times, and also cut (especially if forever is involved)
  • transpose (especially: transpose 12)
  • tempo 2 (doubling the speed)

Phrasing

It’s worth mentioning the phrase function. This allows us to add all sorts of performance-type changes including dynamics like Crescendos, staccato (I used a phrase [Art $ Staccato 0.9] to dampen bass strings – though this is a real fudge as any even beginner bass players know not to let notes ring, plus the common slide or glissando used here isn’t possible AFAICT).

Processing

Euterpea / GHC -> MID -> Timidity -> OGG -> HTML 5

And now

The song