[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-users] Changing GUI inside OSCFunc



Hi all,

I'm trying to interface with the VBAP class in order to write spatialisation
functions.
Specifically, I want to use the VBAP example code and change the x and y
coordinates so that instead of getting new values from mouse clicks they
will be update inside an OSCFunc.

This is my spatialisation function:

(
SynthDef.new(\QuadSine, { |out = 0, freq = 0.25|
	var cosx, sinx;
	cosx = SinOsc.kr(freq, pi/2).range(0,1);
	sinx = SinOsc.kr(freq).range(0,1);
	SendReply.kr(Impulse.kr(2), '/reply', [cosx, sinx]);
	Out.kr(out, [cosx, sinx]);
}).add;
)

And this is the OSCFunc:

(
OSCFunc.new({ |internalMsg|
	x = internalMsg[3]; y = internalMsg[4]; w.refresh;
	},
	'/reply'
);
)

I then make a new Synth:

t = Synth.new(\QuadSine, [\freq, 0.2]);

...and 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 '_QWidget_Refresh' failed.
Failed.
RECEIVER:
Instance of QTopView {    (0x1168606c8, gc=F8, fmt=00, flg=00, set=06)
  instance variables [35]
    qObject : RawPointer 0x10c30c2f0
    finalizer : instance of Finalizer (0x11746f108, size=2, set=1)
    virtualSlots : instance of Array (0x1169b3008, size=1, set=2)
    wasRemoved : false
    font : nil
    resize : Integer 1
    alpha : Float 1.000000   00000000 3FF00000
    decorator : instance of FlowLayout (0x1140f0eb8, size=8, set=3)
    layout : nil
    userCanClose : true
    deleteOnClose : true
    action : nil
    mouseDownAction : nil
    mouseUpAction : nil
    mouseEnterAction : nil
    mouseLeaveAction : nil
    mouseMoveAction : nil
    mouseOverAction : nil
    mouseWheelAction : nil
    keyDownAction : nil
    keyUpAction : nil
    keyModifiersChangedAction : nil
    keyTyped : nil
    focusGainedAction : nil
    focusLostAction : nil
    dragLabel : nil
    beginDragAction : nil
    canReceiveDragHandler : nil
    receiveDragHandler : nil
    toFrontAction : nil
    endFrontAction : nil
    onClose : nil
    onResize : nil
    onMove : nil
    window : instance of QWindow (0x1140ebd28, size=5, set=3)
}
CALL STACK:
	MethodError:reportError   0x117470738
		arg this = <instance of PrimitiveFailedError>
	Nil:handleError   0x117470898
		arg this = nil
		arg error = <instance of PrimitiveFailedError>
	Thread:handleError   0x117470948
		arg this = <instance of Thread>
		arg error = <instance of PrimitiveFailedError>
	Object:throw   0x1174709f8
		arg this = <instance of PrimitiveFailedError>
	Object:primitiveFailed   0x117470e18
		arg this = <instance of QTopView>
	QWindow:refresh   0x117470f78
		arg this = <instance of QWindow>
	OSCMessageDispatcher:value   0x11223abb8
		arg this = <instance of OSCMessageDispatcher>
		arg msg = [*5]
		arg time = 3056.155455196
		arg addr = <instance of NetAddr>
		arg recvPort = 57120
	Main:recvOSCmessage   0x1139b5b08
		arg this = <instance of Main>
		arg time = 3056.155455196
		arg replyAddr = <instance of NetAddr>
		arg recvPort = 57120
		arg msg = [*5]
^^ The preceding error dump is for ERROR: Primitive '_QWidget_Refresh'
failed.
Failed.
RECEIVER: a QTopView

I guess the important line is this (although I don't understand entirely
what it means):

ERROR: Qt: You can not use this Qt functionality in the current thread. Try
scheduling on AppClock instead.

...so apparently it's not possible to change the GUI like this.
Is there any way to go around this?

Here is the entire code:

/// GUI ///

(
var speakerList, x=200, y=150, targx=200, targy=150;
var atorad = (2pi) / 360, rtoang = 360.0 / (2pi);
var targRotate, actRotate, targPoint, actPoint;
var maxShiftPerFrame = 20, frameInterval = 0.01;
var resched = false, count = 0;
var panBus, widthBus, recButton;
var a, b, c, e;

maxShiftPerFrame = maxShiftPerFrame * atorad;
actPoint = Point(x, y) - Point(200, 200);
panBus = Bus.control;
widthBus = Bus.control.set(60);

w = Window.new("Quad Spatializer", Rect(128, 64, 400, 450)).front;
w.view.background_(Color.grey(0.3));
w.view.decorator = FlowLayout(w.view.bounds);
speakerList = [[-50, "L"], [50, "R"], [-130, "Ls"], [130, "Rs"]];
c = UserView.new(w,Rect(0, 0, 400, 380));
c.canFocus = false;

c.drawFunc = {
    Color.grey(0.8).set;
    // draw the speaker layout
    Pen.translate(200,200);
    ((actPoint.theta + (0.5pi)).wrap2(pi) *
rtoang).round(0.01).asString.drawCenteredIn(Rect.aboutPoint(0@170, 30, 10),
Font.new("Arial", 10), Color.grey(0.8));
    Pen.strokeOval(Rect.aboutPoint(0@0, 150, 150));
    Pen.rotate(pi);
    speakerList.do({|spkr|
        Pen.use({
            Pen.rotate(spkr[0] * atorad);
            Pen.moveTo(0@170);
            Pen.strokeRect(r = Rect.aboutPoint(0@170, 30, 10));
            if(spkr[0].abs < 90, {
                Pen.use({
                    Pen.translate(0, 170);
                    Pen.rotate(pi);
                    spkr[1].drawCenteredIn(Rect.aboutPoint(0@0, 30, 10),
                        GUI.font.new("Arial", 10), Color.grey(0.8));
                });
            },{
                spkr[1].drawCenteredIn(r, GUI.font.new("Arial", 10),
Color.grey(0.8));
            });
        });
    });

    Pen.moveTo(0@0);

    // draw the pan point
    Pen.rotate(actPoint.theta + 0.5pi);
    targPoint = Point(x, y) - Point(200, 200);
    // trunc to avoid loops due to fp math
    targRotate = (targPoint.theta - actPoint.theta).trunc(1e-15);
    // wrap around
    if(targRotate.abs > pi, {targRotate = (2pi - targRotate.abs) *
targRotate.sign.neg});
    actRotate = targRotate.clip2(maxShiftPerFrame).trunc(1e-15);
    actPoint = actPoint.rotate(actRotate);
    Pen.rotate(actRotate);
    Pen.lineTo(0@150);
    Pen.stroke;
    Pen.fillOval(Rect.aboutPoint(0@150, 7, 7));
    Pen.addWedge(0@0, 140, neg(e.value * 0.5) * atorad + 0.5pi, e.value *
atorad);
    Pen.stroke;
    Color.grey(0.8).alpha_(0.1).set;
    Pen.addWedge(0@0, 140, neg(e.value * 0.5) * atorad + 0.5pi, e.value *
atorad);
    Pen.fill;

    if((actRotate.abs > 0), {AppClock.sched(frameInterval, {w.refresh})},
{count = 0;});
    if(count%4 == 0, {panBus.set((actPoint.theta + (0.5pi)).wrap2(pi) *
rtoang)});
};

e = EZSlider.new(w, 380@20, "Stereo Width", [0, 180].asSpec, {arg ez;
widthBus.set(ez.value); w.refresh}, labelWidth: 80);
e.labelView.setProperty(\stringColor,Color.grey(0.8));

w.refresh;
)

/// Spatialisation SynthDef ///
(
SynthDef.new(\QuadSine, { |out = 0, freq = 0.25|
	var cosx, sinx;
	cosx = SinOsc.kr(freq, pi/2).range(0,1);
	sinx = SinOsc.kr(freq).range(0,1);
	SendReply.kr(Impulse.kr(2), '/reply', [cosx, sinx]);
	Out.kr(out, [cosx, sinx]);
}).add;
)

/// OSCFunc responds to new values generated from \QuadSine ///
(
OSCFunc.new({ |internalMsg|
	x = internalMsg[3]; y = internalMsg[4]; w.refresh;
	},
	'/reply'
);
)

t = Synth.new(\QuadSine, [\freq, 0.2]);



Thanks much!
omer



--
View this message in context: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Changing-GUI-inside-OSCFunc-tp7621864.html
Sent from the SuperCollider Users New (Use this!!!!) mailing list archive at Nabble.com.

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: https://listarc.bham.ac.uk/marchives/sc-users/
search: https://listarc.bham.ac.uk/lists/sc-users/search/