Hi
I’m new to Sonic Pi, but have made progress beyond what I was expecting in one day. However I’m stuck. I need to stop a sample that is currently playing, even though I wasn’t exactly expecting to. Why? I’m creating an Electronic Drum interface to replace the horrible built in tones from an electronic drum kit, and use its MIDI output to play the samples from Sonic Pi into a PA system. However, one feature is to be able to mute an already playing cymbal (the physical cymbal has a pad you press on to send initiate the mute). I receive a MIDI command which I can interpret as the Cymbal Mute trigger - but how do I stop (ideally initiate a release) to a sample that is part way through?? What command would work - everything I’ve found by searching allows a sample that has begun to complete…
1 Like
Try this
s=sample :loop_amen_full
sleep 1
kill s
If killing from a different loop or thread, just save the reference like this:
s=sample :loop_amen_full
set :s, s
sleep 1
kill get(:s)
1 Like
Fantastic Robin, many thanks - works straight off
The only issue I’ve found, is that if the sample hasn’t been run yet, we get an error “uninitialised constant SonicPi :: RuntimeMethods::[SampleName]”. It’s happy to repeatedly kill it even if already killed. If there is no easy way to write a check in the kill command line, I’ll have to just run it with zero time as an initialisation…
You can check if s has been set before trying to kiil eg
live_loop :test do
tick
puts look
s=sample :loop_amen_full if look==4
sleep 1
kill s if s != nil #s is nil if it has not yet been set
end
1 Like
Depending upon what you are actually wanting to do with midi triggers, the logic may be a bit different. If you can show your program I may be able to help further. Basically you will use the kill command, but you may need to store values of s and initialise s before you start the program running.
Hi Robin
Weirdly, it worked and yet now I’ve somehow broken it. Here is the full code - (at present I’m only using a Midi keyboard to simulate the triggers, I’m intending on replacing these later with the correct control and note codes)
Many Thanks, Tim
live_loop :drum_machine do
use_real_time #remove inbuilt latency
note, velocity = sync “/midi/launchkey_midi/0/1/note_on” #trigger on new note being played, get MIDI info
MyFinish = 1#DO I EVEN NEED THIS ANYMORE??
if note == 60 #Snare
if velocity >50 #Hit Hard
MySample = “C:/drums/snare/drum_snare_hard.flac”
else #Snare Hit Soft
MySample = “C:/drums/snare/drum_snare_soft.flac”
velocity = velocity *1.5 #If it is hit soft, then increase velocity to match the transition for the two samps
end
#else MySample = samps, note-48 #Select the sample that relates the the number hit on the keys (MIDI note minus 48)
S_Snare = sample MySample, amp:velocity /127.0 #Play the Sample
end
#Crash Cymbals:
if note == 61 or note == 62 #Crash1 or Crash 2
if velocity >50 #Hit Hard
MySample = “C:/drums/Cymbals/drum_cymbal_hard.flac”
MyRelease = (1-(velocity /(127.02))) * sample_duration(MySample)#Shorten the Crash based on how hard it has been hit
else #Hit Soft
MySample = “C:/drums/Cymbals/drum_cymbal_soft.flac”
MyRelease = (1-(velocity /(127.02))) * sample_duration(MySample)#Shorten the Crash based on how hard it has been hit
velocity = velocity *1.5 #If it is hit soft, then increase velocity to match the transition for the two samps
end
if note== 62 #Crash 2
MyRate = 1.1 #Increase speed to increase pitch
S_Cym2 = sample MySample, amp:velocity /127.0, release:MyRelease #Play the Sample
else
S_Cym1 = sample MySample, amp:velocity /127.0, release:MyRelease #Play the Sample
end
end
#Muting Cymbals:
if note == 71 #Whatever the Mute Command is
kill S_Cym1 if S_Cym1 != nil #Mute Cym1 Sample if it has been set
end
if note == 72 #Whatever the Mute Command is
kill S_Cym2 if S_Cym2 != nil #Mute Cym2 Sample if it has been set
end
end
Have fixed now by doing the following:
S_Cym1 = 0
Then in Live loop…
bla… bla…
kill S_Cym1 if S_Cym1 != 0 #Mute Cym1 Sample if it has been set