The pulse signal is the way to temporally sync MIDI devices.
The easiest thing to do would be to send out a MIDI clock signal to your external synth. Check out the fn
midi_clock_beat which will send 1 beats worth of pulses (24 in total) in the current BPM over MIDI. You’d just need to place this in a live loop:
live_loop :midi_clock do
Note that this will send midi clock pulses to all connected MIDI devices. Check the docs for the
midi_clock_beat for examples on how to send to a single specific device, MIDI port or MIDI channel.
Alternatively, you can indeed turn a knob on your synth and have it affect the BPM within Sonic Pi. To do this, you need to first realise that Sonic Pi has no global BPM. Each thread (or live loop) has its own independent BPM. Also, you need to know that you can’t change the BPM of a thread externally - in other words, thread A can’t change the BPM of thread B. A thread can only change its own BPM via the
use_bpm fn. You will have to ask for the most recent MIDI value via the
get fn and then convert it into a BPM and use that value. For example:
live_loop :foo do
n, v = get "/midi/**/control_change"
bpm = v * 2. # bpm is now the range 0 -> 255
# insert rhythmic code here!
Note that this will introduce latency between knob changes and BPM changes for 2 reasons:
- You have to wait for your live loop to spin round before you change the BPM (if your live loop spins round every 8 beats, you’ll have to wait up to 8 beats to hear the change)
- Given that this live loop is doing time-critical things, it schedules all events 0.5s ahead of time. There will therefore be a 0.5s latency between knob twiddling and BPM change. This can be reduced by lowering the schedule ahead time using the
set_sched_ahead_time! to use a lower value than 0.5. Note, that on slower systems this might introduce timing issues.
Hope that this helps.