Sonic Pi midimachinery: Raspberry Pi 3 + Lpd8


I started trying Sonic Pi about a week ago. I have some programming experience, but very little. So I am the living proof it really is a great tool for learning. And learning can deliver results in no time.

My setup:

  • Raspberry Pi 3, upgraded to Stretch
  • Sonic Pi 3.0.1
  • Akai Lpd8 midi controller (the cheapest I could find).

Goal: what I wanted to achieve was a basic beat machine (no sequencing, for now, just boring techno style 1-1-1-1) and ambience sounds controlled by the midi controller.

You could probably run this code with another midi device, if you do a little mapping. Anything with 8 turning knobs and some pads will probably work.

Problems with code below:

  • high (actually low, it should be inverted) tempo will result in high latency and can crash the midi_in thread
  • high tempo combined with large reverb room will crash very soon with pretty much any sample.
  • there could still be occasions the value for an opt: can be out of range. This will make the thread stop.
  • Fast paced knob turning on many knobs at once will make the midi_in thread fall behind time and crash

Anyhow, I’m pretty new to it. And would love to hear your feedback. I probably wrote pretty amateur-hour code, but if you have suggestions on how to make things better: I’ld love to hear about them. Especially suggestions for latency reduction and reduction of crash probability :wink:

Other thing I would very much like to do is “remember” variable value of already running threads on restart. Now, if I restart already running code the amp, tempo, etc. sometimes gets set back to default values (first line) again. Which is annoying for usage.


tempo = 0.5; sampleIdx = 0; voices = 1; amp = 0.5; randomiser = 1; ambiSelectie = 0; reverbRoom = 0; panner = 0

load_samples [:ambi_choir, :ambi_dark_woosh, :ambi_drone,:ambi_glass_hum, :ambi_glass_rub, :ambi_haunted_hum, :ambi_lunar_land, :ambi_piano, :ambi_soft_buzz, :ambi_swoosh, :bass_dnb_f, :bass_drop_c, :bass_hard_c, :bass_hit_c, :bass_thick_c, :bass_trance_c, :bass_voxy_c, :bass_voxy_hit_c, :bass_woodsy_c, :bd_808, :bd_ada, :bd_boom, :bd_fat, :bd_gas, :bd_haus, :bd_klub, :bd_pure, :bd_sone, :bd_tek, :bd_zome, :bd_zum, :drum_bass_hard, :drum_bass_soft, :drum_cowbell, :drum_cymbal_closed, :drum_cymbal_hard, :drum_cymbal_open, :drum_cymbal_pedal, :drum_cymbal_soft, :drum_heavy_kick, :drum_roll, :drum_snare_hard, :drum_snare_soft, :drum_splash_hard, :drum_splash_soft, :drum_tom_hi_hard, :drum_tom_hi_soft, :drum_tom_lo_hard, :drum_tom_lo_soft, :drum_tom_mid_hard, :drum_tom_mid_soft, :elec_beep, :elec_bell, :elec_blip, :elec_blip2, :elec_blup, :elec_bong, :elec_chime, :elec_cymbal, :elec_filt_snare, :elec_flip, :elec_fuzz_tom, :elec_hi_snare, :elec_hollow_kick, :elec_lo_snare, :elec_mid_snare, :elec_ping, :elec_plip]

varSamples = [:ambi_choir, :ambi_dark_woosh, :ambi_drone,:ambi_glass_hum, :ambi_glass_rub, :ambi_haunted_hum, :ambi_lunar_land, :ambi_piano, :ambi_soft_buzz, :ambi_swoosh, :bass_dnb_f, :bass_drop_c, :bass_hard_c, :bass_hit_c, :bass_thick_c, :bass_trance_c, :bass_voxy_c, :bass_voxy_hit_c, :bass_woodsy_c, :bd_808, :bd_ada, :bd_boom, :bd_fat, :bd_gas, :bd_haus, :bd_klub, :bd_pure, :bd_sone, :bd_tek, :bd_zome, :bd_zum, :drum_bass_hard, :drum_bass_soft, :drum_cowbell, :drum_cymbal_closed, :drum_cymbal_hard, :drum_cymbal_open, :drum_cymbal_pedal, :drum_cymbal_soft, :drum_heavy_kick, :drum_roll, :drum_snare_hard, :drum_snare_soft, :drum_splash_hard, :drum_splash_soft, :drum_tom_hi_hard, :drum_tom_hi_soft, :drum_tom_lo_hard, :drum_tom_lo_soft, :drum_tom_mid_hard, :drum_tom_mid_soft, :elec_beep, :elec_bell, :elec_blip, :elec_blip2, :elec_blup, :elec_bong, :elec_chime, :elec_cymbal, :elec_filt_snare, :elec_flip, :elec_fuzz_tom, :elec_hi_snare, :elec_hollow_kick, :elec_lo_snare, :elec_mid_snare, :elec_ping, :elec_plip]

varAmbiSamples = [:ambi_choir, :ambi_dark_woosh, :ambi_drone,:ambi_glass_hum, :ambi_glass_rub, :ambi_haunted_hum, :ambi_lunar_land, :ambi_piano, :ambi_soft_buzz, :ambi_swoosh]

sleep 3

in_thread(name: :midiIn) do

live_loop :midiIn do


ch, val = get "/midi/lpd8_midi_1/1/1/control_change"

if ch == 1 then

sampleIdx = val

puts "sample:"

puts varSamples[sampleIdx]


if ch == 2 then

tempo = quantise ((val / 127.0) * 4) + 0.2, 0.2

puts "tempo:"

puts tempo


if ch == 3 then

voices = quantise val / 25, 1

puts "voices:"

puts voices


if ch == 4 then

amp = val / 127.0 + 0.1

puts "amp:"

puts amp


if ch == 5 then

randomiser = val / 3.0

puts "randomiser:"

puts randomiser


if ch == 6 then

ambiSelectie = val

puts "ambiSelectie:"

puts varAmbiSamples[ambiSelectie]


if ch == 7 then

panner = quantise (val / 64.0) - 1, 0.1

puts "panner:"

puts panner


if ch == 8 then

reverbRoom = val / 127.0

puts "reverbRoom:"

puts reverbRoom


sleep 0.1



in_thread(name: :piano) do

live_loop :piano do


note, velocity = sync "/midi/lpd8_midi_1/1/1/note_on"

sync :noiseBringer

rrand_i(1, 4).times do

sleep tempo / 8

sample :drum_cymbal_open, amp: amp / 4, rate: (velocity / 127) + 0.4

sample varAmbiSamples[ambiSelectie], amp: amp /2, rate: note / randomiser, pan: panner

puts "note / randomiser:"

puts note / randomiser

sleep tempo / 8

sample :drum_cymbal_pedal, amp: amp / 4, rate: (velocity / 127) + 0.4

sleep tempo / 8

sample varAmbiSamples[ambiSelectie], rate: note / (randomiser - rrand(0, 10)), pan: panner

sleep tempo / 8

sample :elec_blup, amp: amp / 4, rate: (velocity / 127) + 0.4

sleep tempo / 8

sample :elec_filt_snare, amp: amp / 3, rate: (velocity / 127) + 0.4

sleep tempo / 8

sleep tempo / 8

sleep tempo / 8




in_thread(name: :noiseBringer) do

live_loop :noiseBringer do

with_fx :reverb, room: reverbRoom do

voices.times do

sample varSamples[sampleIdx], amp: amp

if voices > 1 then

if amp > 0.25 then

sample varSamples[sampleIdx], amp: amp

sample varSamples[sampleIdx], amp: amp - 0.2, rate: 0.9



sample varSamples[sampleIdx], amp: amp + 0.2



sleep tempo

cue :noiseBringer

Hi there.
Could you edit and repost your code please. You need to paste it inside three reverse tick ` characters

` ` `

on a line just before the code starts (without spaces between them)
and then a further three reverse tick characters

` ` `

on a line after the end of the code (without spaces between them)
I think you you have posted the code directly and it has altered the " characters to smart quotes so the code does not work unless you alter them back again. Posting the working code between the two lines of three reverse tick characters will preserve the formatting correctly.

(I put the code into a text editor and did search and replace to correct the " and it ran OK on my Sonic PI, although I don’t have that particular controller to try out.

NB only the code needs to be in the section inside the three tick characters, the discussion text preceding it is fine.

it’s an interesting first post, and shows you are really getting into Sonic PI after only 1 week.

I edited the post directly to add the quotes, but @robin.newman is right, a little bit of formatting helps a lot :slight_smile: