I had a go at stress testing this and found that I was wrong, I got a worse framerate with animate (2-3 fps) vs. task (8-9 fps) in this test:
// Version 1 - using animate
// Setup
(
~sf= Platform.resourceDir++"/sounds/a11wlk01.wav";
b = Buffer.read(s, ~sf);
w = Window("test", Rect(50, 370, 900, 300)).front;
)
// Build Views
(
d =();
d.numCopies = 900;
d.targetFrameRate = 10;
d.trans = 0.2; // view transparency
w.view.removeAll; // remove old
d.arrElapsed = 0 ! d.numCopies;
d.arrViews = nil ! d.numCopies;
d.arrTasks = nil ! d.numCopies;
d.frameCount = 0;
d.timeSinceStart = 0;
d.numCopies.do({arg i;
d.arrViews[i] = UserView(w, Rect(800.rand, 280.rand, 130, 20))
.background_(Color.black.alpha_(d.trans));
d.arrViews[i].drawFunc = {arg view;
var framerate, elapsed;
// print framerate of view 0 every second
if (i == 0, {
if (d.frameCount == 0, {
d.startTime = Main.elapsedTime;
d.printSecs = 0;
}, {
d.timeSinceStart = Main.elapsedTime - d.startTime;
if (d.printSecs != d.timeSinceStart.asInteger, {
d.printSecs = d.timeSinceStart.asInteger;
framerate = view.frameRate;
("Average frame rate =" + framerate.round(0.01)).postln;
});
});
d.frameCount = d.frameCount + 1;
});
Pen.fillColor = Color.red.alpha_(d.trans);
elapsed = (d.timeSinceStart / b.duration).min(1);
Pen.addRect(
Rect(0, 0, (view.bounds.width * elapsed), view.bounds.height)
);
Pen.fill;
};
});
Button(w, Rect(50, 80, 130, 20))
.states_([["play", Color.black, Color.green], ["stop", Color.black, Color.white.alpha_(0.3)]])
.action_({|v|
if(v.value == 1, {
d.frameCount = 0;
d.timeSinceStart = 0;
a = Synth(\sf, [\bufnum, b]);
d.numCopies.do({arg i;
d.arrViews[i].frameRate_(d.targetFrameRate);
d.arrViews[i].animate_(true);
});
}, {
a.free;
d.numCopies.do({arg i;
d.arrViews[i].animate_(false);
});
});
});
SynthDef(\sf, { |bufnum = 0|
Out.ar(0,PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), doneAction: Done.freeSelf));
}).add;
w.onClose= {b.free};
)
w.close;
//////////////////////////////////////////
// Version 2 - using Task
// setup
(
~sf= Platform.resourceDir++"/sounds/a11wlk01.wav";
b = Buffer.read(s, ~sf);
w = Window("test", Rect(50, 370, 900, 300)).front;
)
// Build Views
(
d =();
d.numCopies = 900;
d.targetFrameRate = 10;
// d.trans = 1; // view transparency
d.trans = 0.2; //
w.view.removeAll;
d.arrElapsed = 0 ! d.numCopies;
d.arrViews = nil ! d.numCopies;
d.arrTasks = nil ! d.numCopies;
d.frameCount = 0;
d.timeSinceStart = 0;
d.numCopies.do({arg i;
d.arrViews[i] = UserView(w, Rect(800.rand, 280.rand, 130, 20))
.background_(Color.black.alpha_(d.trans));
d.arrViews[i].drawFunc = {arg view;
var framerate;
// print framerate of view 0 every second
if (i == 0, {
if (d.frameCount == 0, {
d.startTime = Main.elapsedTime;
d.printSecs = 0;
}, {
d.timeSinceStart = Main.elapsedTime - d.startTime;
if (d.printSecs != d.timeSinceStart.asInteger, {
d.printSecs = d.timeSinceStart.asInteger;
framerate = d.frameCount / d.timeSinceStart;
("Average frame rate =" + framerate.round(0.01)).postln;
});
});
d.frameCount = d.frameCount + 1;
});
Pen.fillColor = Color.red.alpha_(d.trans);
Pen.addRect(
Rect(0, 0, (view.bounds.width * d.arrElapsed[i]), view.bounds.height)
);
Pen.fill;
};
d.arrTasks[i] = Task({
var mul = d.targetFrameRate, time;
time = b.duration;
(time*mul).do({|slice|
d.arrElapsed[i] = (slice + 1) / (time * mul);
d.arrViews[i].refresh;
(1 / mul).wait;
});
}, AppClock);
});
Button(w, Rect(50, 80, 130, 20))
.states_([["play", Color.black, Color.green], ["stop", Color.black, Color.white.alpha_(0.3)]])
.action_({|v|
if(v.value == 1, {
d.frameCount = 0;
d.timeSinceStart = 0;
a = Synth(\sf, [\bufnum, b]);
d.numCopies.do({arg i; d.arrTasks[i].play});
}, {
a.free;
d.numCopies.do({arg i; d.arrTasks[i].stop.reset});
});
});
SynthDef(\sf, { |bufnum = 0|
Out.ar(0,PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), doneAction: Done.freeSelf));
}).add;
w.onClose= {b.free};
)
Sorry for the noise.
Paul