Typing to Sonic Pi drum pattern code generator

#1

I’m starting to look at how I can get something usable running in Sonic Pi really quickly, which I can then expand on.

I’ve started with a simple idea. I’ve written a small external program into which I can type a basic drum pattern, using j=bass drum and k=snare drum. It then analyses the rhythm and produces some Sonic Pi code which is automatically copied, and can be pasted in Sonic Pi.

My idea for this program is to develop it a bit, so that I can type in a rhythm in real time, then have some code generated which is an extension of that rhythm. E.g. hats and cymbals will be added generatively and hopefully sympathetically, and variations of the beat generated so that a rough track structure is there. And, then things can be added to it in real time during performance.

My intention is to keep extending this, so that (eventually, in my dreams) it’ll be a matter of typing in a germ of a rhythmic idea, and code will be generated which allows immediate control through set commands of various options and variations.

It looks something like this at present, but this is just an initial try.

2 Likes
#2

And of course, as these things go, as soon as I see the screenshot above, I realise what I should have done - make it easier to change drum sounds and mix. And of course it’s done now.

I should point out that I’m fully committed to doing a lot of live coding, not to come up with an alternative. This little program is just supposed to give me a starting point.

#3

It’s a really cool project and a very original addition to Sonic-Pi. I think you should try to rename the topic so people can immediately understand what you are talking about. Before clicking, I was thinking that you were experiencing the typical Timing Exception: thread got too far behind time.

1 Like
#4

Thanks. It’s just a rough thing at the moment, but already it’s turning out to be useful. By ‘typing along’ to some music playing on my computer, I’ve been able to work out some drum patterns that I couldn’t quite work out. Sadly I’m not yet good enough at recognising patterns that I can’t yet hear something and immediately know what the beat is.

Edit: the following small beat is something that started in the above interface, and then got modified in Sonic Pi. Already I’m seeing things I can do. Adding a filter, a mono fx, and a distorter provides interesting ways of sonically modifying loops, including live. I’m going to add some checkboxes to my interface to automatically add those fx if requested.

# Created by ReceiveKeyPress

use_bpm 115.9676

bassdrumsample = :bd_haus
snaredrumsample = :sn_dolf

bassdrumpan = 0
snaredrumpan = 0.7

bassdrumamp = 1
snaredrumamp = 1

set :distort_value, 0.3
set :cutoff_value, 130
set :mono_value, 1.0

live_loop :autodrums do
  sync :loop
  
  with_fx :mono, mix: get( :mono_value ) do |mn|
    set :monoator, mn
    with_fx :rlpf, res: 0.7, cutoff: get( :cutoff_value ) do |lpf|
      set :lpfator, lpf
      with_fx :distortion, distort_slide: 2, distort: get( :distort_value ), mix: 1.0 do |ds|
        set :distorter, ds
        
        at [0.0, 0.5, 1.5, 1.75, 2.25, 2.5, 4.0,
        4.5, 5.5, 5.75, 6.25, 6.5, 6.76] do
          sample bassdrumsample, pan: bassdrumpan, amp: bassdrumamp
        end
        at [1.0, 2.25, 3.0, 5.0, 6.25, 7.0, 7.75] do
          sample snaredrumsample, pan: snaredrumpan, amp: snaredrumamp
        end
        
        with_fx :echo, decay: 2, mix: 0.4 do
          2.times do
            use_random_seed 1234
            
            16.times do
              sample :drum_cymbal_closed, pan: -0.7 if one_in(2)
              sleep 0.25
            end
          end
        end
      end
    end
  end
end

live_loop :timing do
  cue :loop
  sample :vinyl_hiss, beat_stretch: 4
  sleep 4
end

with the get and sets, it’s then easy to control the loop live in another buffer, using code like:

ds = get :distorter
set :distort_value, 0.3
control ds, distort: get( :distort_value )

mn = get :monoator
set :mono_value, 0
control mn, mix: get( :mono_value )

lpf = get :lpfator
set :cutoff_value, 120
control lpf, cutoff: get( :cutoff_value )
2 Likes