Quartz Composer in SC
clean-up: #37
Thanks to Scott Wilson it is possible to load and embed Quartz Composer sketches in SuperCollider.
Below is an example that demonstrates how to use it with a camera input. You'll need the attached .qtz file and edit the path in the SuperCollider code.
note1: this is macOS only.
note2: this works on SC 3.7 and newer (or SC 3.5 if you replace QuartzComposerView
with SCQuartzComposerView
).
(
var width= 1024, height= 576;
w= Window("qc", Rect(100, 100, width, height)).front;
m= QuartzComposerView(w, Rect(0, 0, width, height));
//m.path= "~/Desktop/cam.qtz".standardizePath; //edit to match filepath
m.path= thisProcess.nowExecutingPath.dirname+/+"cam.qtz";
CmdPeriod.doOnce({w.close});
m.start;
m.inputKeys.postln; //should return [X, Y]
s.waitForBoot{
~speedx= 0.1;
~speedy= 0.11;
a= {|x= 0, y= 0| Pan2.ar(MoogFF.ar(Saw.ar(1-y.lag(0.1)*99+99), y.lag(0.1)*199+99, 3), x.lag(0.1)*2-1)}.play;
r= Routine({
inf.do{|i|
var x= sin(i*~speedx)*0.5+0.5;
var y= cos(i*~speedy)*0.5+0.5;
m.setInputValue(\X, x);
m.setInputValue(\Y, y);
a.set(\x, x, \y, y);
(1/60).wait;
};
}).play(AppClock);
};
)
~speedx= 0.02
~speedx= 0.4
~speedy= 0.05
~speedy= 0.5
r.stop;
a.free;
m.stop;
w.close;
In the above example frequency is mapped to video effect vertical movement, and panning to video effect horizontal movement.
update 200116: I found an older example that could play movie files and added it here as well. It will play back the smoothest if the movie file is compressed using a codec that compresses each frame individually. e.g. photoJPEG.
//macOS only
(
var x= 10, y= 10;
var width= 1280, height= 720;
var path= "somefolder/somefilm.mov";
var qtz= thisProcess.nowExecutingPath.dirname+/+"filmplayer2.qtz";
var win= Window("filmplayer", Rect(x, y, width, height), false, false);
var view= QuartzComposerView(win, Rect(0, 0, width, height));
view.path= qtz;
view.setInputValue('Movie_Location', path);
view.start;
view.front;
win.front;
CmdPeriod.doOnce({view.close});
)
//macOS only
(
var qtz= thisProcess.nowExecutingPath.dirname+/+"filmplayer2.qtz";
var win= Window("filmplayer2", Rect(100, 100, 640, 260));
var readButton= Button(win, Rect(10, 10, 100, 30)).states_([["read"]]);
var pathText= StaticText(win, Rect(10, 50, 300, 30));
var playButton= Button(win, Rect(10, 100, 100, 30)).states_([["enable"], ["disable"]]);
var durText= StaticText(win, Rect(10, 130, 300, 30)).string_("Dur:");
var posText= StaticText(win, Rect(10, 150, 300, 30)).string_("Pos:");
var qc= QuartzComposerView(win, Rect(310, 10, 320, 240));
qc.path= qtz;
readButton.action= {
playButton.valueAction= 0;
Dialog.openPanel({|path|
pathText.string= path;
qc.setInputValue('Movie_Location', path);
{
playButton.valueAction= 1;
durText.string= "Dur:"+qc.getOutputValue('Movie_Duration');
}.defer(0.5);
});
};
playButton.action= {|view|
qc.setInputValue('Enable', view.value);
};
Routine({
var lastPos;
inf.do{
var pos= qc.getOutputValue('Movie_Position');
if(pos!=lastPos, {
posText.string= "Pos:"+pos;
});
(1/25).wait;
};
}).play(AppClock);
qc.front;
win.front;
CmdPeriod.doOnce({win.close});
)

Attachments: | |
---|---|
cam.qtz.zip | |
filmplayer2.qtz.zip |