Change a sample volume in mid-flight

I’m using sonic pi for live playing with midi controllers. What a joy to have a fully programmable thing rather than just learning what you can/can’t do with some (expensive) hardware device :slight_smile:

I have some long samples, multi-bar and wanted to be able to change the volume in mid-flight. Maybe other things too. I share here in case anyone wants to do that too, or for comments. Maybe there’s other ways to do it.

Needs a bit of explanation. I have some custom functions that pick up values from midi knobs e.g. isknob() is true if a knob is just above zero. knobnormalised() returns a value between 0 and 1.

The sample ‘bandoneon.ogg’ is 16 bars long, so the loop is sync’d to play once every 16 bars.

I’ve encased the sample in a with_fx :level block, and included a 2nd loop that runs concurrently and picks up the knob volume every beat, then applies the volume to the Level FX.

It works! Hopefully helpful to someone - or any alt ideas gratefully received.

live_loop :bandeon do
  sync :bar16
  
  if isknob(5) then
    with_fx :level do |level|
      
      sample d, "bandoneon.ogg", amp: 1.0, release: 0.3
      
      in_thread do
        64.times do
          control level, amp: knobnormalised(5)
          sleep 1
        end
      end
    end
  end
end
1 Like

Nice!
In case you want to control some other parameter that can’t be easily done with an fx, you can also control the sample directly:

samp = sample :loop_amen_full, amp: 1.0

in_thread do
  20.times do
    control samp, amp: rand(), pan: rand(2)-1
    sleep 0.5
  end
end

(simplified from your code so that it runs on its own, but you can easily adapt it back if you choose).

1 Like

Ah thanks, much better. I didn’t know you could control the sample directly while it was running. That’s very neat :+1:

Also, I don’t think I need to run the control loop in a thread if I just make sure it’s finished by the next sync so e.g. 19.times do…