The latency of s.makeBundle and TempoClock

Dear developers and users,

In the following three code blocks,

(
// Code 1:
{
	var pitches = ([0, 2, 4, 5, 7, 9, 11, 12] + 60);
	pitches.do { |pitch|
		var synth;
		s.makeBundle(0.2, {
			synth = Synth(\default, [\freq, pitch.midicps])
		});
		0.3.wait;
		synth.release
	}
}.fork
)

(
// Code 2:
{
	var pitches = ([0, 2, 4, 5, 7, 9, 11, 12] + 60);
	pitches.do { |pitch|
		var synth;
		s.makeBundle(0.2 // 0.2 should be 0.1 to eliminate errors.
		,
		 {
			synth = Synth(\default, [\freq, pitch.midicps])
		});
		0.3.wait;
		synth.release
	}
}.fork(TempoClock(2))
)


(
// Code 3:
{
	var pitches = ([0, 2, 4, 5, 7, 9, 11, 12] + 60);
	pitches.do { |pitch|
		var synth;
		s.makeBundle(0.2, {
			synth = Synth(\default, [\freq, pitch.midicps])
		});
		0.3.wait;
		synth.release
	}
}.fork(TempoClock(0.25))
)

the second one (Code 2) returns the following errors:

-> a Routine
FAILURE IN SERVER /n_set Node 5480 not found
FAILURE IN SERVER /n_set Node 5481 not found
FAILURE IN SERVER /n_set Node 5482 not found
FAILURE IN SERVER /n_set Node 5483 not found
FAILURE IN SERVER /n_set Node 5484 not found
FAILURE IN SERVER /n_set Node 5485 not found
FAILURE IN SERVER /n_set Node 5486 not found
FAILURE IN SERVER /n_set Node 5487 not found

To avoid these errors, the latency should be reduced to 0.1. Why does this happen? How can I avoid this kind of error?

I know it is simpler to use Pbind for this example. I am comparing the variation of a simple example with ascending major scale examples, including Pbind examples.

Thank you in advance for your help!

Best,

You need to wrap synth.release in its own separate s.makeBundle(0.2, { ... }) as well. Any call that sends OSC should be pre-empted if accurate timing is desired.

1 Like

should be pre-empted

Do you maybe mean scheduled? I mainly know preemption from the context of multi-tasking (preemptive vs cooperative) where it means that the scheduler can interrupt one task to allow another task to execute. I am not sure what preemption would mean in the context of OSC messages.

1 Like

I am basically a small child when it comes to networked or concurrent programming so I am definitely misusing some terms. Noted!

I visualize it like this (+ is note-on, - is release, and tempo = 1 beat per second – the position in the chart shows when the message is performed):

0.0       0.5       1.0 (beats)
|.........|.........|
    +                 makeBundle timebase
      -               immediate-send timebase

… which is already a bug in the first example: your code seems to want the note to hold for 0.3 beats, but you only get 0.1 beat. (The absence of an error message doesn’t mean that it’s working.)

When tempo = 2, the time scale shrinks but the latency (always in seconds) does not:

0.0  0.5  1.0
|....|....|
    +       makeBundle timebase
   -        immediate-send timebase

The note-on is still at beat 0 + 0.2 seconds, but the release is now at 0.3 beats = 0.15 seconds – before the node is created! There’s the error message, and the stuck notes.

So the issue is simply to be consistent about the messaging timebase.

hjh

1 Like

@nathan @jamshark70

Thank you for your answers! I now easily understand that problem!