Stopping a running sample on midi note_off using kill is working fine. Is it possible to invoke the release time rather than it just stopping it dead? Not the biggest deal, but it would be very nice.
I think after receiving the signal you can loop 8 times (for instance) and use
control s, amp: (line 1, 0, steps: 8).tick to “simulate” a release.
Thank you that works pretty well.
some code to illustrate your post would be welcome we learn from others
Of course, see below. I’ve tweaked the idea in a couple of ways:
- Toggling the ‘obey note off’ feature using a special midi key (C3 in this case), so you can choose to let the sample run or not
- Rather than use a linear tail-off for the amplitude, a hard-coded log-type which is bit more natural.
This snippet uses my local samples rather than builtin, but easy switch out. This code isn’t bullet proof as I’m only saving a ref to one sample at a time, so you can fox it by hitting lots of keys at once. Ideally it could do with maintaining some kind of stack of refs. But it’s fine for what I want.
Hope this is of some use.
#Songo #MIDI keyboard-triggered samples use_bpm 180 d = $mymusicpath + "songo/stems/" set :obey_note_off, true live_loop "keys" do #Trigger samples based on the note_on #Choosing the sample based on the note played #Starting with C4=60 use_real_time note,volume = sync "/midi:mpk_mini:2:1/note_on" puts "note " + note.to_s + " volume " + volume.to_s a = 0.4 #Scale the sample volume. with_fx :reverb, mix: 0.0 do with_fx :echo, phase: 1.5, mix: 0.0, decay: 10.0 do case note when 60 s = sample d, "vox espeak I want free life", amp: a * 0.3 when 61 s = sample d, "vox i want free life", amp: a when 62 s = sample d, "vox i wonder why", amp: a when 63 s = sample d, "vox mmm", amp: a, release: 0.5 when 64 s = sample d, "vox the open air", amp: a when 65 s = sample d, "vox the row began", amp: a end set "keysample", s end #echo end #reverb end live_loop "toggle_obeynoteoff" do #Toggle the 'kill on note_off' feature using the C3 key use_real_time note,volume = sync "/midi:mpk_mini:2:1/note_off" if note == 48 then o = get[:obey_note_off] o = !o set :obey_note_off, o end end live_loop "kill" do #Kill the note on midi note_off #First use a loop to tail off the sample #and simulate a slow release use_real_time note,volume = sync "/midi:mpk_mini:2:1/note_off" in_thread do s = get[:keysample] o = get[:obey_note_off] if s and o then #Use a log-type tail off tailoff = [1.0, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01] 7.times do #control the sample, setting the amp lower and lower control s, amp: tailoff.tick * 0.4 sleep 0.5 end #Finally kill the sample kill s end end end