# Triggering from midi - is this example robust?

**URL:** <https://in-thread.sonic-pi.net/t/triggering-from-midi-is-this-example-robust/4432>\
**Category:** Support, Help & Resources\
**Created:** [September 28, 2020, 10:01am UTC](https://in-thread.sonic-pi.net/t/triggering-from-midi-is-this-example-robust/4432 "2020-09-28T10:01:30Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![soxsa](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/soxsa/32/1669_2.png) [@soxsa](https://in-thread.sonic-pi.net/u/soxsa)\
**Post date:** [September 28, 2020, 10:01am UTC](https://in-thread.sonic-pi.net/t/triggering-from-midi-is-this-example-robust/4432/1 "2020-09-28T10:01:30Z")

</div>

Could I get a quick thumbs up or nudge in the right direction?

The use case is: A remote computer running loops on a DAW. It broadcasts a midi note over the network using rtpMidi, at the start of a phrase, and want Sonic Pi loops to start up in time. My code below works fine - my question is if this is a robust way to do it. I don’t want to be relying on a fudge. In use, the loops start up a bit out of time (understandably) and settle down after just a couple of beats.

This is a crucial thing for me, if it’s good then all the doors are open to use Sonic Pi in a combo.

I’m using time\_warp to manage the total latency. Trial and error gave me 530ms which seems very long. I’ve got a bit a of laggy setup here but normally around 50ms with other software.

Thanks in advance for any advice.

```ruby
live_loop "miditrig" do
  use_real_time
  #Wait for the midi note from the DAW
  sync "/midi:rptmidi_remote:0:1/note_on"
  time_warp rt(-0.53) do
    cue "start"
  end
end

live_loop "main", sync: "/cue/start" do
  play :E6, release: 0.1
  #...Cue all the other loops...
  sleep 4
end

```

---

<div class="post-metadata">

**Author:** ![soxsa](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/soxsa/32/1669_2.png) [@soxsa](https://in-thread.sonic-pi.net/u/soxsa)\
**Post date:** [September 28, 2020, 4:50pm UTC](https://in-thread.sonic-pi.net/t/triggering-from-midi-is-this-example-robust/4432/2 "2020-09-28T16:50:35Z")

</div>

Extra bit of info. This works for midi channels 1 to 9 but not 10 to 16. I see the cues arrive in the cue window but they don’t trigger the sync.

---

<div class="post-metadata">

**Author:** ![samaaron](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/samaaron/32/7_2.png) [@samaaron](https://in-thread.sonic-pi.net/u/samaaron)\
**Post date:** [September 29, 2020, 8:24am UTC](https://in-thread.sonic-pi.net/t/triggering-from-midi-is-this-example-robust/4432/3 "2020-09-29T08:24:50Z")

</div>

Hi there,

if you’re trying to synchronise Sonic Pi’s internal synths with an external sound source (either from another app on the same computer or from an external sound source) you need to be aware that Sonic Pi, by default adds 500ms of latency to all synth and MIDI events. This is likely what you’re hearing. Of course, this is _in addition_ to the latency of your sound device which will vary depending on your hardware and settings.

This extra 500ms latency enables Sonic Pi to work correctly on very low powered machines. You can reduce it (this is essentially what `use_real_time` does) but that’s not always advisable as it can cause Sonic Pi to “run out of time” much more easily. It’s also important to point out that `use_real_time` only affects the current thread, so some threads can not have this latency applied and others have the default.

In your example the `miditrig` live loop has no latency applied, but that isn’t affecting it as it’s not sending any sound events (`play` / `synth`) or MIDI events `midi`). So it’s not needed here.

When you receive the `note_on` event, you rewind the clock 530ms and send an event. This obviously is physically impossible as you can’t actually go back in time. What it instead does is write an event into the Time State with an old time.

The `main` live loop waits for the `start` event. After it is written by the `miditrig` live loop, it is immediately available - but time still hasn’t gone backwards as it can’t. However, the `main` live loop has its clock set back in the past to match the time that the `start` was sent which is in the past. This means that the `main` live loop is now _late_ as its clock points to a time that is behind the actual time in the real world.

The `main` loop continues to spin round, attempting to catch up with the real time but still adding the 500ms of latency as it is _not_ in real time mode. This is why you initially hear things late but then slowly catch up.

To fix this you ideally want to send an event from your external DAW _before_ you want things to happen. This is similar to a band counting in. The leader of the band doesn’t just say “PLAY!”, they typically say, “Ready? 3, 2, 1, Play!”.

If you can send an event one bar ahead of time, then this will all be much easier.

Either way, you don’t actually need the `miditrig` live loop unless you want to do multiple cues during a performance. This would suffice:

```ruby
num_beats_in_bar = 4
sync "/midi:rptmidi_remote:0:1/note_on"
time_warp rt(-0.53) + num_beats_in_bar do
  cue :start
end

live_loop :main, sync: :start do
  play :E6, release: 0.1
  #...Cue all the other loops...
  sleep 4
end

```

---

<div class="post-metadata">

**Author:** ![soxsa](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/soxsa/32/1669_2.png) [@soxsa](https://in-thread.sonic-pi.net/u/soxsa)\
**Post date:** [September 30, 2020, 8:19am UTC](https://in-thread.sonic-pi.net/t/triggering-from-midi-is-this-example-robust/4432/4 "2020-09-30T08:19:18Z")

</div>

Perfect, thank you, I can work with that.

I found an interesting effect using your example of the cue not being in a loop. When I make some live changes in the following loops on that page, they don’t get played unless/until the midi note comes to cue it again. I think that makes sense - it’s about tuning into your model.

I want to optionally cue from broadcast midi or keyboard or start right away so I might put the control code on page 0 (if they are called pages, panels, whatever) and the musical code on other pages. That seems to avoid the problem, as the other pages seems to refresh/reload independently.

---

<div class="post-metadata">

**Author:** ![soxsa](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/soxsa/32/1669_2.png) [@soxsa](https://in-thread.sonic-pi.net/u/soxsa)\
**Post date:** [September 30, 2020, 10:43am UTC](https://in-thread.sonic-pi.net/t/triggering-from-midi-is-this-example-robust/4432/5 "2020-09-30T10:43:35Z")

</div>

Great, thanks, I’m taking ‘like’ to mean ‘this is correct’ 😄

Ok, I’m all good to go. I had another epiphany while doing this bit - I can do away with the DAW and do everything in Sonic Pi. The DAW is just running pre-composed phrases collected in ‘scenes’ in session mode. Its clever thing is to trigger the phrases in tempo - but Sonic Pi does that and with much more flexibility and control than any GUI can ever provide.

All systems go, many thanks for all the help.
