For a start I’d update to the latest version 4.5.1 which you can download from sonic-pi.net.
I my exprience (on a rather old PC running Windows 10 the audio performace on the built in audio is not great and does have quite a lot of latency. I believe you can update drivers, but a better audio card can also help reduce latency. Others may help here. I keep well away from Windows normally
To check things, a very simple program you can use is
use_synth :saw
set_audio_latency! -300
live_loop :min do
use_real_time
n,v = sync "/midi*/note_on"
play note: n,sustain: 0.4,release: 0.2,amp: v/127.0
end
This just sounds a note for a specified time each time a key is pressed. You can reduce the latency a bit by changing the set_audio_latency! line. By default I think this has parameter 0, but you could go say -300 or -400 to try amd improve things. On my Mac which has better built in audio latency this is not necessary.
Another program you can try which plays while the key is down by starting long notes and then cutting them when you release the key is below. This is experimental and can have some issues, but its not bad for a keyboard operated synth using a built in SP synth.
#experimental polysynth program by Robin Newman
plist=[] #list to contains references to notes to be killed
ns=[] #array to store note playing references
nv=[0]*128 #array to store state of note for a particlar pitch 1=on, 0 = 0ff
128.times do |i|
ns[i]=("n"+i.to_s).to_sym #set up array of symbols :n0 ...:n127
end
#puts ns #for testing
define :sv do |sym| #extract numeric value associated with symbol eg :n64 => 64
return sym.to_s[1..-1].to_i
end
#puts sv(ns[64]) #for testing
live_loop :midi_piano_on do #this loop starts 5 second notes for spcified pitches and stores reference
use_real_time
note, on = sync "/midi*/note_*" #change to match your controller
if on >0
puts note,nv[note]
if nv[note]==0 #check if new start for the note
nv[note]=1 #mark note as started for this pitch
use_synth :pulse
#max duration of note set to 5 on next line. Can increase if you wish.
x = play note,amp: on/127.0, sustain: 5 #play note
set ns[note],x #store reference in ns array
end
else
if nv[note]==1 #check if this pitch is on
nv[note]=0 #set this pitch off
plist << get(ns[note])
end
end
end
live_loop :notekill,auto_cue: false,delay: 0.25 do
use_real_time
if plist.length > 0 #check if notes to be killed
k=plist.pop
control k,amp: 0,amp_slide: 0.02 #fade note out in 0.02 seconds
sleep 0.02
kill k #kill the note referred to in ns array
end
sleep 0.01
end
Of course if you are trying to trigger expternal synths and then feed their audio back into Sonic Pi for further p[rocerssing then other factors come into play, liek the latency of your exteranl synth, and also the latency of your sound input card, and dealing with these depends very much on your setup. If you `re trying to sync to an external daw like ableton then you can use ableton link to syn the midi and you can use the global time warp control in the mertronome pane (in version 4.5.1) to sync the audios together