Here’s a toy example that reproduces the problem I’m having with much longer functions:
use_bpm 60
define :myFunction do
midi_note_on 60, 100, port: "iac_driver_bus_1", channel: 1
sleep 1
midi_note_off 60, 127, port: "iac_driver_bus_1", channel: 1
end
live_loop :myLoop do
myFunction
end
MIDI Monitor reveals this plays back, at one point, as follows:
16.369 From Bus 1 Note On 1 C3 100
17.369 From Bus 1 Note Off 1 C3 127
17.370 From Bus 1 Note On 1 C3 100
18.369 From Bus 1 Note Off 1 C3 127
18.369 From Bus 1 Note On 1 C3 100
19.369 From Bus 1 Note On 1 C3 100
19.370 From Bus 1 Note Off 1 C3 127
20.369 From Bus 1 Note Off 1 C3 127
20.369 From Bus 1 Note On 1 C3 100
21.369 From Bus 1 Note Off 1 C3 127
Those first two Note On’s get followed by their Note Off’s as expected, but the third Note On has the fourth one sneak in right before its Note Off. As a result, the fourth Note On gets clipped because it gets offed by the other note’s Note Off. Somehow, that fourth Note On gets executed before the third Note Off, messing things up.
In my real code, this problem happens about 10% of the time, a Note On from a subsequent loop getting executed before the Note Off from a preceding loop. There’s no discernible pattern as to when it will happen. This kludge fixes the error:
live_loop :myLoop do
myFunction
sleep 0.001
end
but I’d like to understand why this happens, and if there’s a way to avoid this weird execution misordering without making a radical change to the way I’m doing things here. As I said, it’s a toy, and the larger project depends on working this way, with all sleep’s in the functions and none in the loops.