I am brand new to sonic pi and I’m requesting some assistance with some code pertaining to midi. I have an external sequencer connected to sonic pi via usb midi. When I press start/stop on my sequencer I see the corresponding messages and know they are connected via midi. I also hear my sequencer audio through my computer so I am good there too. When I run my code in sonic pi it waits for the incoming midi signal and pressing play on my sequencer starts the amen break code (which is the behavior I’m looking for), however pressing stop on my sequencer does not stop playback on sonic pi. Any and all help appreciated! Below is my code:
live_loop :midi_control do
use_real_time
start_msg = sync "/midi:m8_m8_midi_1_24_0/start"
if start_msg
puts "MIDI START RECEIVED"
run_sequence
end
stop_msg = sync "/midi:m8_m8_midi_1_24_0/stop"
if stop_msg
puts "MIDI STOP RECEIVED"
stop
end
end
live_loop :midi_notes do
use_real_time
note, velocity = sync "/midi:m8_m8_midi_1_24_0:1/note_on"
if note == 36
puts "Note_on RECEIVED"
set :sequence_running, true
run_sequence
end
note, velocity = sync "/midi:m8_m8_midi_1_24_0:1/note_off"
if note == 36
puts "Note_off RECEIVED"
set :sequence_running, false
end
end
define :run_sequence do
in_thread(amen: :my_sequence_thread) do
while get(:sequence_running) do
# Jungle
# Coded by Sam Aaron
use_bpm 50
with_fx :lpf, cutoff: 90 do
with_fx :reverb, mix: 0.5 do
with_fx :compressor, pre_amp: 40 do
with_fx :distortion, distort: 0.4 do
live_loop :jungle do
use_random_seed 667
4.times do
sample :loop_amen, beat_stretch: 1, rate: [1, 1, 1, -1].choose / 2.0, finish: 0.5, amp: 0.5
sample :loop_amen, beat_stretch: 1
sleep 1
end
end
end
end
end
end
end
end
end
define :stop_sequence do
set :sequence_running, false
end
I don’t think it’s possible to stop playback of a sample once it’s started. You can specify start and stop before you launch it but once it’s playing it will run till the end.
That being said it might be possible to mute it when you receive the stop message by setting the amp value of the running sample, I’m not on my pc right now but I think I can make this work.
I have since written new code that responds better, much cleaner too (i’ll post it later when im at my computer) for this use-case with the break as the sample i changed the loop playback to 1 so it would stop quicker.
however id really like to see your mute suggestion as that would come in handy in a variety of use-cases.
currently im having trouble successfully sending a midi note from sonic pi to my sequencer. i need to send a C1 on midi channel 10 from sonic pi to my sequencer to control the sequencer’s start/stop function however no variation of code i’ve written sends the note.
Since initially making my post I’ve made revisions that have accomplished most of what I’m aiming to accomplish, however I’m requesting further assistance with a new problem.
current process: run sonic pi code, code waits for the note_on from my tracker (connected via usb midi), note_on is triggered and the code executes the amen break in sync with my tracker. When a note_off triggers from my tracker the sample ends.
Okay cool that’s exactly what I want to accomplish, however the code cannot be edited live since it isn’t contained within a live_loop. How can I amend this code to accomplish live editing while maintaining note_on/note_off midi start/stop control?
set :sequence_running, false
live_loop :midi_notes do
use_real_time
note, velocity = sync "/midi:m8_m8_midi_1_24_0:1/note_on"
if note == 36
puts "NOTE ON"
set :sequence_running, true
run_sequence
end
note, velocity = sync "/midi:m8_m8_midi_1_24_0:1/note_off"
if note == 36
puts "NOTE OFF"
set :sequence_running, false
end
end
define :run_sequence do
in_thread(JUNGLE_TEST: :sequence_thread) do
while get(:sequence_running)
#JUNGLE
use_bpm 30
with_fx :lpf, cutoff: 90 do
with_fx :reverb, mix: 0.5 do
with_fx :compressor, pre_amp: 40 do
with_fx :distortion, distort: 0.6 do
use_random_seed 647
1.times do
sample :loop_amen, beat_stretch: 1, rate:[1,1,1,-1].choose / 2.0, finish: 0.5, amp: 0.5
sample :loop_amen, beat_stretch: 1
sleep 1
end
end
end
end
end
end
end
end
This code allows me to start samples with the drum pads on my midi controller and when I hit the stop button on my controller everything is muted immediately.
use_real_time
set :running_samples, []
define :mute_all_running_samples do
rs = get[:running_samples]
for s in rs do
control s, amp: 0
end
end
define :play_sample do |s_in|
s = sample s_in
rs = get[:running_samples]
rs = rs + [s]
set :running_samples, rs
end
live_loop :mute_listener do
note, value = sync "/midi:launchkey_61_launchkey_61_launchkey_midi_28_0:1/control_change"
if note == 114 and value == 0
mute_all_running_samples
end
end
live_loop :start_sample_listener do
note, value = sync "/midi:launchkey_61_launchkey_61_launchkey_midi_28_0:10/note_on"
if note == 36
play_sample :ambi_lunar_land
end
if note == 40
play_sample :loop_amen_full
end
if note == 41
play_sample :loop_3d_printer
end
end
thank you for the support, this code is brilliant. will definitely try implementing it with my tracker - updates to come. have you made any recordings using this code?
No recordings where I use this, just some fooling around. My kids love it when they can trigger samples from the drum pads on my midi keyboard, could use a sampler but I do most of my stuff in Sonic Pi.