Readbuf+phasor loop cross point detection with HPZ1 not working as expected

hi

I am using a phasor and readbuf. I need to find out the loop cross point. For this I use SendReply with HPZ1.ar(HPZ1.ar(phasor).sign). However in some cases I get the cross point reported well before the Phasor reaches the end. This is the synth and the OSC to receives the replies

SynthDef( \rPlayerLoop, { arg out=0, buffer=0, amp=1, pan=0, start=0, end=1, rate=0, dir=1, index=0;

	var left, right, phasor, dur = BufFrames.kr(buffer);

	phasor = Phasor.ar( 1, rate * BufRateScale.kr(buffer), start*dur, end*dur, resetPos: dur);

	SendReply.ar( HPZ1.ar(HPZ1.ar(phasor).sign), '/xloop', 1, index, phasor/dur); //loop point
	SendReply.kr( LFPulse.kr(60, 0), '/pos', [phasor, dur], index); //fps 12

	#left, right = BufRd.ar( 2, buffer, phasor ) * amp;
	Out.ar(out, Balance2.ar(left, right, pan));
}).load;

p = Synth.tail(Server.default, \rPlayerLoop,
	[\buffer, b, \start, 0, \end, 1, \amp, 1, \rate, 1,
		\pan, 0, \index, 666, \out, 0, ]);

c = OSCdef(\xloop++666, {|msg, time, addr, recvPort|
	if (msg[2]==666, {
		msg.postln
	});
}, '/xloop');

e = OSCdef(\playhead++666, {|msg, time, addr, recvPort|
	if (666==msg[2], { msg[3..5].postln });
}, '/pos');

I am also using a SendReply with a LFPulse to get the position of the phasor to compare its values with the moment when the HPZ1 reports the loop cross point. The funny thing is that sometimes it seems to work fine but others it does not. I cannot make sense of the difference.

For instance with a 3 min sound Buffer I get that the loop cross point is reported [ /xloop, 1000, 666, 1.0 ] at the same time these values are sent from the /pos SendReply [ 8412045.0, 9623808.0 ]. So it is basically telling me it has reached the end when there are a lot of frames left to actually get there… But in other cases it seems to work fine, I wonder if this has to do with the length of the buffers (the longer the less accurate?).

I wonder if the HPZ1.ar(HPZ1.ar(phasor).sign) is correct or it is missing something.

thanks for any help

enrike

What about the samplerate of the server (48.000) vs samplerate of the files (44.100)? any chances this might be causing it?

You are sending osc messages back to sclang 60 times a second, I wonder if this has something to do with it. You could use a trigger sent from sclang to trigger the osc message whenever you need the value or send the values to a control bus and get it from sclang with .get. I am not sure this is the solution but in any case I would suspect the 60 osc messages a second can cause problems.

(Sorry I am answering myself) yes the sample rate seems to be the problem. I changed the server to 44100 to match the files’ rate and it works fine that wat. I guess I need to change the synth to take into consideration the actual server rate

yeah I guess I am a bit over the top in my test but that should probably produce random errors and the error was very consistent, it always ended at the same point.

I have not done testing on long buffers but using this seems to do the job.

SendReply.ar( Trig.ar(phasor >= ( dur - 1)), '/xloop', 1, index, phasor/dur);

…but then again, I am not sure when you are trying to achieve in the bigger picture…

yep. I just tried a few times with samples of different lengths and so far it works fine. thanks!!

Btw the 1.0 is misleading here because the arguments to the SendReply.ar are in the wrong order. This isn’t actually phasor/dur.

I found in the past that Phasor can exhibit strange behavior with a nonzero start and reset point. That could cause the discrepancy you’re observing.

hjh

thanks! I think I will stick the the solution proposed by Thor