Setting Cursor in SoundFileView via Phasor

Hey!

I have the following problem:
I would like to get the current phase position of the phasor to control a cursor in the SoundFileView.

(
a = SynthDef(\1, {|rate = 1, startPosition = 0, endPosition = 10000|
	
	BufRd.ar(1, b, Phasor.ar(0, BufRateScale.kr(b)*rate, startPosition, endPosition));
	
	//this is for sending the values of the phasor to the OSCFunc
	SendReply.kr(Impulse.kr(3), '/cursor', Phasor.ar(0, BufRateScale.kr(b)*rate, startPosition, endPosition));
	
}).add
)

//I would like to get the values via an OSCFunc, to control the timeCursorPosition.
//Would that be a good approach?

//this works
o = OSCFunc({ |msg| msg[3].postln; }, '/cursor');

// this doesnt work
o = OSCFunc({ |msg| v.timeCursorPosition = msg[3] }, '/cursor');

//when I use "v.timeCursorPosition= msg[3]", I get the following error

/*ERROR: Qt: You can not use this Qt functionality in the current thread. Try scheduling on AppClock instead.
ERROR: Primitive '_QObject_SetProperty' failed.*/

// I tried to use AppClock, but I couldnt make it work

Have you tried this?

o = OSCFunc({ |msg| {v.timeCursorPosition = msg[3]}.defer }, '/cursor');

.defer schedules it on the AppClock. It works for me, not sure if it is the best approach though. Another option is to write your position on a Bus and poll that Bus in a routine:

b = Bus.control(s,1);

(
SynthDef(\1, {|kOut=0, rate = 1, startPosition = 0, endPosition = 100000|
	var phase = Phasor.ar(0, BufRateScale.kr(b)*rate, startPosition, endPosition);
	BufRd.ar(1, b, phase);

	Out.kr(kOut, phase);
}).play(s,[kOut:b])
)


~pollTime = 0.05
t = Task{
	loop{
		a.timeCursorPosition = b.getSynchronous();
		(~pollTime ? 0.1).wait;
	}
}.play(AppClock)

t.pause
t.play
~pollTime = 0.01
~pollTime = 1
t.stop
2 Likes

. defer is the correct approach when updating a GUI from any responder (OSC, MIDI, etc.).

Probably the error message itself should recommend .defer but it currently doesn’t.

hjh

2 Likes