Grimes' "Oblivion" in Sonic Pi

I found out about Sonic Pi through reddit recently and decided to give it a try, and it’s been a blast so far! I sing for fun and have been wanting to do a cover of Oblivion for a while, so I decided to code the instrumental for it as my first “real” Sonic Pi project. Here is the result:

Song: https://soundcloud.com/fuzz-genesis/oblivion-grimes-cover-made-in-sonic-pi
Code: https://github.com/fuzzgenesis/sonic_pi_experiments/blob/master/oblivion_instrumental.rb

I recorded/mixed all the vocals in Garageband, then imported them as one long sample and recorded the final song in Sonic Pi. The current version on Github is just the instrumental though.

If you have any feedback on the code I’d be interested to hear it, I feel like it could be way cleaner; the threads especially take up a ton of lines and aren’t super organized. I have a programming background but am not terribly familiar with Ruby, and there are probably some helpful Sonic Pi features I missed. I was mostly just focused on getting all the synths sounding more or less like the original, haha.

12 Likes

Wow! Nice work!

Thank you for sharing your code. If you don’t mind sharing, how long did you spend on the coding? Just curious, I have a similar coding background and am just getting started with Sonic Pi. Musically I play guitar and a few other things. I have some peripheral knowledge about synth and DSP concepts but not much firsthand experience - did you have a good sense of which synths and samples you would need from the start or was it trial-and-error?

1 Like

Hey @fuzz,

welcome to our community - it’s lovely to have you here!

Also, thank-you so much for sharing this cover of Oblivion - it’s truly fab! You’re really pushing the boundaries of what people have produced with Sonic Pi to date - amazing work!

Your code is really clean - I wouldn’t worry about it at all :slight_smile:

Truly inspiring work!!!

1 Like

That’s amazing, thanks for posting it! You must have put in a lot of effort to get it sounding so polished.
I’d say the code is absolutely fine, but as you ask for feedback, here are a couple of things you might like to try out:

with_fx (and I believe also play/sample/synth etc…) has an on: option to enable/disable it, so you can replace:

  if one_in(5)
    with_fx :echo, amp: 0.6, phase: 0.2, decay: 0.2, mix: 0.25 do
      kick 1
    end
  else
    kick 1
  end

with:

  with_fx :echo, amp: 0.6, phase: 0.2, decay: 0.2, mix: 0.25, on: one_in(5) do
    kick 1
  end

Also, when you want a synth for only one note, instead of switching it with use_synth, e.g.:

      use_synth :dsaw
      play note, amp: 0.15, sustain: 3, release: 2
      use_synth :tech_saws
      play note, amp: 0.05, sustain: 3, release: 2

you can just call the synth directly, like:

      synth :dsaw, note: note, amp: 0.15, sustain: 3, release: 2
      synth :tech_saws, note: note, amp: 0.05, sustain: 3, release: 2

Finally, in a few places you loop over all items in a ring, for example:

  idx = 0
  pattern.length.times do
    main_synth_fx :prophet, pattern[idx]
    main_synth_fx :fm, pattern[idx]
    idx = idx + 1
    sleep 0.5
  end

you can pass the counter into the code block to avoid having to keep track of it yourself:

  pattern.length.times do |idx|
    main_synth_fx :prophet, pattern[idx]
    main_synth_fx :fm, pattern[idx]
    sleep 0.5
  end

you can also use .each to get the items directly without having to index into the collection:

  pattern.each do |p|
    main_synth_fx :prophet, p
    main_synth_fx :fm, p
    sleep 0.5
  end

although that is a Ruby thing not explicitly supported by Sonic Pi, so comes with the usual caveat that it might disappear in a later version.

In any case there’s no “correct” way to do things, the best way is whatever works for you, and these are just some extra options to play with if you want to.

4 Likes

Thanks for some great tips. Gotta admit that I don’t “get” all of them quite yet. I do have a question about the line above: where is “note” defined?

These were all snippets from the original piece linked at the start of this thread, so it might help to look up where they come from in there for some context.
In this case it was inside a function (define :sparkle_synth do |note|), so note was a function parameter, but you can replace it with a symbol (e.g. :c) or a midi number (e.g. 60) or anything else you would usually pass to the play function.

1 Like

Makes me want to create a cover of something with Sonic Pi as well - but I don’t think my singing voice is good enough for that :joy:

Great stuff @fuzz! Really enjoyed listening.

1 Like

@ethancrawford

Sonic Pi needs a vocoder effect!

2 Likes

Hey thanks so much! I probably spent like 20 hours(? might be way off base) on it over a couple weeks. Honestly most of that time was spent listening to the original to figure out when various parts were supposed to come in / fade out, painstakingly adjusting sleep values, and re-playing. (That process really made me wish I was using a DAW, lol). The second largest chunk of time was spent doing trial and error with the synth sounds. I would basically go down the list of synths and take the first one that sounded remotely like what I wanted, and then tweak it with FX or add other sounds on top until I was happy. So overall the process was pretty brute-force, but I got it sounding like I wanted :slight_smile:

3 Likes

Waow, that is so awesome to hear from you!! Thank you for creating this amazing tool and making it free/open source!

1 Like

@emlyn Thank you for this feedback! That echo if statement was bothering me so much, I knew there had to be a nicer-looking way. These are all great tips and I really appreciate you taking the time to look through my code :slight_smile:

@ethancrawford Thank you! And instrumental covers are a thing, haha. @PiEaterAndPlayer is right though, a vocoder for Sonic Pi would be amazing.

2 Likes

True, yes! but having done instrumental music for a while, I feel that it would make an interesting change to play with vocals at some point :smile:

Re vocoders - there’s been a little interest in this for a while (we started discussing the implementation of one here: Prototype of a Vocoder in Sonic Pi - it’s just a matter of someone having the time to investigate/work on it :slightly_smiling_face:)

2 Likes