How to send MIDI notes simultaneously without a glissando effect

I’ve successfully followed the method shown in this thread to play groups of MIDI notes at once:
How to send midi chords through vsti, via Sonic Pi?

# Use: midi_chord chord(:c4,:major), sustain:0.2
define :midi_chord do |notes, *args|
  notes.each do |note|
    midi note, *args
  end
end

But when I play a group of notes they don’t sound simultaneously - there is a slight delay that gives a sweeping, harp-like glissando instead. Is there anything I can do to prevent this and play them all at once?

That’s strange! It’s been a while since you posted it—were you able to figure it out? When I tested just now, it played the notes simultaneously, so I’m not sure where this issue is coming from on your setup.

(Unfortunately my setup is probably uncommon: preview build of Sonic Pi 5 on Arch Linux 6.5.3-zen, Pipewire 1:0.3.80, Ardour 7.5. The synth was “ACE Reasonable Synth” via LV2.)

I note that by default the midi function sends events on all 16 channels, so the three-note chord in your test is actually 48 notes. Any chance something was getting overwhelmed by that many simultaneous events? You can try changing the test command to midi_chord chord(:c4,:major), sustain:0.2, channel: 1 to see whether that makes a difference.

Hey thanks for your suggestion! I just gave it a try there and unfortunately I’m still getting the sweeping gliss effect. I’m sending the MIDI to both my built-in soundcard / general MIDI sounds and to a Novation Launchpad MK2 (to light LEDS with note on messages). Whether I send to both ports simultaneously, or just one of them, I get the same staggered effect. It’s really odd.

Odd indeed. Would you mind posting the entire code buffer, along with the function invocation? Just wondering if something else could be disrupting it somehow…

1 Like

Gladly, thanks so much for your help :slight_smile:

Here’s my code - just playing a pile of MIDI notes together, but they stagger. It’s not musical or anything - just a big cluster corresponding to LEDs on the Launchpad I’m lighting up!

use_real_time

define :midi_chord do |notes, *args|
  notes.each do |note|
    midi note, *args
  end
end

live_loop :draw do
  midi_chord [3,4,18,19,20,21,33,35,36,38,49,51,52,54,65,66,67,68,69,70,82,83,84,85], sustain:2, velocity:120
  sleep 2.5
end

I have tried outputting just to my built-in soundcard, just to the Launchpad/LEDs, to both at once, and to just one channel too. In every instance, there is a noticable delay between each note. If you comment out use_real_time it’s particularly noticable.

I suspect this is because, as described on another thread, the midi command is basically something like:

send a note on
sleep for sustain length
send a note off

So the sleep in each midi note is delaying everything, instead of playing simultaneously.

Just getting back to this, and hooray! I can reproduce the issue. I’m on a different machine, running Windows 10 and Sonic Pi 4.0.3, but I wouldn’t be surprised if it happened on my Linux machine too: it was just subtle enough that it might not have been noticeable with a 3-note chord, but it’s pretty unmistakable with this 23-note one. I should have tried commenting out use_real_time though; you’re right about the difference.

Your theory about the midi function is reasonable, but I’m not sure: the function uses time_warp to schedule the note_on and note_off commands. There’s no sleep, so it shouldn’t block the thread. (You can see it in the file Sonic Pi/app/server/ruby/lib/sonicpi/lang/midi.rb, around line 1436 depending on the version.)

I think it might rather have something to do with the way Sonic Pi handles the array construct. When I was testing just now, I noticed that I could get the notes to sound simultaneously by converting the array to a ring and then reversing it! But only on the second loop and subsequently. :woozy_face:

use_real_time

define :midi_chord do |notes, *args|
  notes.each do |note|
    midi note, *args
  end
end

live_loop :draw do
  midi_chord ring(3,4,18,19,20,21,33,35,36,38,49,51,52,54,65,66,67,68,69,70,82,83,84,85).reverse, sustain:2, velocity:120
  sleep 2.5
end

Truly, I have no idea what could cause this. But is there any chance it could serve as a workaround for now?

1 Like

Wow, this is so interesting - thank you for sharing your expertise and delving into this with me! I’m fascinated to learn that the problem probably isn’t the midi function. Managing to narrow it down to something about the way arrays are handled is awesome! And this workaround is truly witchcraft…I’ve no idea either, but I’m very much looking forward to giving it a go. I’ll let you know how it works out!

1 Like