Hi all -
MacBook Air M1 chip
Ventura 13.3
SPi 4.3.0
I am an Adv Beginner with Sonic Pi. And I’ve been working for the last five months at integrating SPi with my current workflow, including using Logic Pro. I am enamored with Live Coding. I am eager to sponsor some AlgoRave events in my area. But I recognize that my coding skills need to improve dramatically before I can realistically start something like that.
So here’s my latest challenge. I am using a live_loop to run chord changes. Using time state (set/get) to push chord changes out which can then be read by various instruments. I have live_loops for each of several instruments. They parse the current chord and play individual notes (via virtual MIDI in my DAW).
It’s the timing that is not quite right. And I feel like I need to deepen my understanding of how SPi prioritizes the various loops.
Problem: My chord changes are arriving late. When my song moves from Am to Dm, the first note of the measure is still playing :a1, from prior chord. By the second note of the measure, the chord change has been received. Everything plays fine, until the next chord change. Then again, the change is not received until the second note of the measure.
Note: to simulate the chord change, you have to go to the :chordChanger loop and change the reference to :chord1 to :chord2. Then refresh the code. This is by design. I want to control chord changes on the fly.
Can someone help me to understand the ‘why’ behind this issue? I have had similar problems crop up in different ways.
Thanks for everyone’s patience in helping me out with this. Y’all are the best!
use_bpm 120
# sequencer
live_loop :chordChanger do
set :bassChord, get[:chord1]
set :bass1Rhythm, get[:bassRhythm1]
set :bass2Rhythm, get[:bassRhythm2]
sleep 16
end
# kick
in_thread do
sync :oneBar
live_loop :kick do
vel = 110
kick vel if [1,1,0,0,1,0,0,0].tick == 1
sleep 0.5
end end
in_thread do
sync :oneBar
live_loop :snare do
snare 110 if [0,1].tick == 1
sleep 1
end end
set :bassRhythm1, [1,1,2,1,0,1,0,1, 3,1,0,1,0,1,4,1]
set :bassRhythm2, [1,1,1,1]
set :bassNotes, [ 0,0,1,0, 0,0,2,0, 0,0,3,0]
set :chord1, [:a1,:d2,:c2,:g1]
set :chord2, [:d2,:f2,:e2,:c2]
# bass1
in_thread do
sync :fourBar
live_loop :bass1 do
chordVar = get[:bassChord]
noteX = :a1
if get[:bassRhythm1].tick != 0 then
noteX = chordVar[get[:bass1Rhythm].look - 1]
bass1 noteX, 110
end
sleep 0.5
tick_reset :noteTick if look(:noteTick) >= 11
end end
#bass2
in_thread do
sync :fourBar
live_loop :bass2 do
chordVar = get[:bassChord]
noteX = :a1
if get[:bass2Rhythm].tick != 0 then
noteX = chordVar[get[:bass2Rhythm].look - 1]
bass2 noteX, 30
end
sleep 0.5
tick_reset :noteTick if look(:noteTick) >= 11
end end
#hihat
in_thread do
sync :oneBar
live_loop :hat do
hihat 100
sleep 0.25
end end
define :bass1 do |note,amp|
midi note, port: "logic_pro_virtual_in", channel: 2, vel: amp
end
define :bass2 do |note,amp|
puts "bass2 amp = "+amp.to_s
midi note, port: "logic_pro_virtual_in", channel: 3, vel: amp
end
define :kick do |vel|
midi 36, port: "logic_pro_virtual_in", channel: 10, vel: vel
end
define :snare do |vel|
midi 40, port: "logic_pro_virtual_in", channel: 10, vel: vel
end
define :hihat do |vel|
midi 42, port: "logic_pro_virtual_in", channel: 10, vel: vel
end
define :fx1 do |vel|
midi 57, port: "logic_pro_virtual_in", channel: 10, vel: vel
end
define :snare2 do |vel|
midi 39, port: "logic_pro_virtual_in", channel: 10, vel: vel
end
in_thread do
live_loop :counter do
tick
if look % 32 == 0 then
puts "Eight bar"
cue :eightBar
end
if look % 16 == 0 then
puts "Four bar"
cue :fourBar
end
if look % 4 == 0 then
puts "One bar"
cue :oneBar
end
sleep 1
end
end