Use_bpm is messing with :record fx

Wow. I love Sonic Pi. Been goofing with it on and off since I bought my first RPi. Big ups to Sam Aaron and the whole Sonic Pi community. It’s a miraculous piece of software and free. We live in a golden age. Thanks in advance to anyone who is reading this.

A recent issue has me so twisted, I had to join the community and post about it.

I’m learning to use live_audio and fx. Specifically, I’m working on using :record as a looping pedal for a guitar input. But my results are inconsistent. I’m beginning to think that the buffering is buggy on my machine/OS (details below). But I’m able to trip it up every time by using the “use_bpm” function.

If I run the code without use_bpm, the song will take off at 60 bpm and, 99% of the time, it will capture the loop and play it back to me. HOWEVER, if I add the use_bpm function and put in certain values, the :record fx fails to capture.

When it fails, the log shows that it is triggering the buffer for playback, but there is no audio.

Certain BPM’s will capture. Others will not.

Good BPM’s
-100, 90, 120, 112, 160
Bad BPM’s

  • 110,101,99,113 thru 119, 121, 130

I have been testing this for about 48 hours. Good BPM’s will reliably work. And bad BPM’s will reliably NOT work. WHY?!?!

Obviously, I haven’t tested every BPM. But in all my testing, I can’t see a pattern, beyond the fact that BPM’s that are multiples of 10 are more likely to work.

Here are the details about my setup

Hardware:
MacBook Pro
2.3 GHz Intel Processor
OSX 12.6 Monterey
Focusrite soundcard Scarlett 414

Sonic Pi 4.3.0

Code:

use_bpm 112

live_loop:drums do
  sample :bd_haus, cutoff: 70
  sleep 1
end

with_fx :reverb do
  with_fx :echo, phase: 0.74, decay: 4 do
    with_fx :record, buffer: buffer(:bname2, 8) do
      live_audio :foo
    end
  end
end

live_loop :guitar2 do
  sample buffer[:bname2]
  sleep 8
end

Bump. I am uncertain if this is due to an error in my code… or if it is rooted in the hardware.

If someone could tell me “I’ve read your code and that should NOT be happening”, then I guess I’d assume it is rooted in my hardware.

But my understanding of :record is limited. Perhaps I;'m not using it correctly.

Hello @ianridd,

I havent try :record code before but there is always odd errors on sonic pi. Sometimes you take an error one pc and you wont take an error other pc. It can change version of version or operating system to other operating system even sometimes you can take an error when your computer is unplugged and you wont take an error with plugged.

Neverthless you can try some codes for the bpm work properly.

  1. Suggest for you:
    Try to write top of your code :use_debug false
    This code block your log messages while working your code.

  2. Suggest for you:
    Try to make a bpm loop and sync with it your live loops. For example:

live_loop :metronom do
  sleep 1
end

live_loop :drums, sync: :metronom do
sample :bd_haus, cutoff: 70
sleep 1
end

This is the way to make your live_loop works with bpm properly.

You can try these codes, I hope it helps :innocent:

This is unfortunately the reality when you work with time-critical code on a wide variety of different hardware and software contexts. For example the different behaviour your describe wrt plugged/unplugged laptops is likely to do with the operating system engaging “energy savings mode” which slows down your computer to save battery. Unfortunately slowing down a time-critical app will make it fail in unexpected ways!

1 Like

Hi @ianridd,

it looks like you might be running into a race condition between starting recording into the buffer and playing back from the buffer.

Looking at your code there are no sleeps ‘above’ with_fx :record (note that the sleep in the :drums live loop doesn’t count as it’s in a separate thread/live_loop).

This means that the live audio is being requested to start being recorded at time 0.

Looking at the playback code in the :guitar2 live loop there is no call to sleep above the call to sample buffer[:bname2].

This means that the playback of the live-recorded sample is being requested to start at time 0.

The problem is also potentially made worse because the :record FX also needs to create the buffer the first time it is triggered. This also takes time.

As a first guess to fixing this, I’d try initialising the buffer before you start. I’d also start the playback of the buffer after a sleep time. For example:

use_bpm 112

buf = buffer(:bname2, 8)

live_loop:drums do
  sample :bd_haus, cutoff: 70
  sleep 1
end

with_fx :reverb do
  with_fx :echo, phase: 0.74, decay: 4 do
    with_fx :record, buffer: buf do
      live_audio :foo
    end
  end
end

live_loop :guitar2 do
  sleep 8
  sample buf
end
2 Likes

Thank you for these thoughtful replies.

I have implemented several suggestions and the stability has increased immensely.

I will post follow-up code when I get it dialed in.