Latest version of Sonic Pi Hanging MIDI notes when stopping run

Hi everyone hope you’re all doing well and staying safe, I’m getting back into Sonic Pi after a long time away.
I’m running the latest version of the sonic pie pre-release with the latest version of Reaper on macOS Catalina.
In this case I am using Sonic Pi to run a generative sequence in to native instruments complete control in reaper, I’m using the below code:

live_loop :genmidi1 do
set :seed, 0
use_bpm 140
set :seed, (get(:seed) + 971) if tick % 16 == 0
use_random_seed get(:seed)
8.times do
midi scale(:c5, :minor_pentatonic).choose, sustain: 0.7,channel: 1
sleep 1
end
end

With the sustain value 0.7 and above, I find that when I stop running sonic-pi I am experiencing stuck midi notes with reaper, pressing stop in reaper does not stop the MIDI notes from sticking. How can I resolve this problem and what’s causing it?

Your help with this problem would be most welcome respect and blessings Trey.

Hi @soundwarrior!

When you say “latest version of the sonic pi pre-release”, it’s helpful to know numbers, just to know for sure which one you mean - like ‘Beta-6’ or similar. (Also, the latest official release was just the other day - version 3.3, so feel free to use that if you’re interested. Just note that there is currently a bug when using it with macOS Big Sur and the sample onset option, which shouldn’t affect you if you don’t upgrade macOS just yet).

Back in June 2020 some work was added, to flush MIDI messages which Sonic Pi might still be trying to send from its queue when the Stop button is pressed - though it’s possible your stuck notes are not exactly the same issue.

There is a command in Sonic Pi to stop all midi notes: midi_all_notes_off. Is this something that would be useful for you?

Hi Ethan, thank you for your reply. I’m not sure what the exact version number is but I know it’s the latest pre-release version released before the official version to Patran subscribers. The all notes off command maybe what I’m looking for is there any way to trigger it at the end of my live loop? Thank you very much for your help :slight_smile:

It depends on what you mean by ‘trigger it at the end of my live loop’. If you place midi_all_notes_off as the very last line inside the live_loop, then each time the loop has sent 8 notes to be played on your MIDI device (while sleeping for 1 beat between each), it will then send the message to your device to stop all midi notes, and cycle around again to send another 8 notes to your device. Is this what you had in mind?

Yes it is I think so :slight_smile: so do I placed the all notes off command after the sleep command and before the end command?
Thanks very much for all your help :slight_smile:

Yes, that’s what I meant. No worries!

Actually, I think there may be a bug here.
I started up Midi Monitor, and ran this on version 3.3 on Mac:

use_midi_defaults port: "midi_monitor_(untitled)", channel: 1
midi :e, sustain: 2

If I let it run to completion, I see a “Note on” followed by a “Note off”. However, if I press stop soon after I’ve pressed start, I only get a “Note on” message, and the note is never stopped.

EDIT:
I’ve tried the same code on Sonic Pi 3.2.0 and it also behaved the same - pressing stop while a midi note is playing prevented the Note Off message from being sent.
However, I also tried it on Sonic Pi 3.1.0, and there, the Note Off was always sent, even after the code is stopped. I think this is the expected behaviour.

I’ve filed an issue on GitHub, so hopefully this can be fixed.

Hi @emlyn , I’m sorry that this isn’t probably what you want to hear, but what you’re observing is actually correct behaviour.

The stop button stops all code. It also stops the synth engine. It also stops all MIDI out.

The behaviour you were expecting is that after you hit stop, your MIDI synths stop too.

Unfortunately Sonic Pi doesn’t know how to do that. In some cases it might be to ensure that every note on has a subsequent note off, so it would have to track that independently for each MIDI out device. You might suggest to always send an all notes off MIDI message, but to which MIDI outs? All of them? What if you had a MIDI out connected that Sonic Pi wasn’t explicitly controlling at that point. Should it stop that synth too? How should it know which synths to stop?

Sonic Pi therefore doesn’t try any of this but instead ensures that all unsent messages - including those scheduled for the near and far future are cancelled.

If you want to stop your MIDI synths, you need to first decide which commands you need to use for your particular setup and then send those.

I do think that having a nice way to trigger blocks of code such as described above after the stop button is hit would be useful - but it’s a way off at this point as it really needs a nice way to manage groups of threads independently so stop wouldn’t kill everything - just the group you’re working on.

2 Likes

Thanks for the explanation @samaaron.
I did consider that might have been the case, but understood this comment to mean that the note_off should be being sent (if that’s not the case, what do you mean here, @ethancrawford?):

Also, I tried the code on an older version of Sonic Pi (3.1.0), and there it behaves as I had expected - as if the midi command queues up the note_off message somewhere so that it still gets sent when the code is stopped. And as that feels like a more correct behaviour, I assumed that the new behaviour was a bug.

Sorry, that probably wasn’t a helpful explanation. I took the behaviour to mean that flushed meant ‘dropped’/‘not executed’. I just meant that if there are remaining instructions in the queue when stop is pressed, it’s like they are just deleted without being processed.
Apologies for the confusion - probably better that I leave the explanation to the person who wrote the code next time :joy:

Oh, I understand now! I had understood “flush” in the sense of file IO, where it’s still sent to its destination.
In that case, that would be why Sonic Pi 3.1 behaved differently, because it must have been prior to this change.

1 Like

Just to make sure - @samaaron do I have the right idea here? :joy: