Hello! I have a bit af a trouble wrapping my head around how to properly build classes. I want to make a simple recorder class for live performance. How should I use and control the Ugens in the class? Spontaneously creating a SynthDef inside a class seems ugly to me, is there a best practice for this?
This is what I have tried to do so far, but it does not work.
SimpleRecorder { //relies on booted server
var <>server;
var <running=0, <resetTrig=0;
var sigIn, <>sigInBus;
var <ptr;
var <recBuf;
var <bufLenght;
*new { |serverIn, sigBus|
^super.new.server_(serverIn).sigInBus_(sigBus).init;
}
init {
bufLenght = server.sampleRate;
recBuf = Buffer.alloc(server, numFrames: bufLenght);
ptr = Phasor.ar(resetTrig, running, 1, bufLenght);
sigIn = SinOsc.ar(440);//In.ar(sigInBus);
BufWr.ar(sigIn, recBuf, ptr);
}
rec { //To-do: build using synth
running = 1;
resetTrig=0;
this.changed(\running, running); // broadcast event
}
pause {
running = 0;
this.changed(\running, running);
}
reset {
running = 0;
resetTrig=1;
this.changed(\running, running);
}
}
you could look at the source for the Recorder object for inspiration. (Recorder | SuperCollider 3.14.0 Help) It does in fact create its own temporary SynthDef.
TBH the intended usage of this class isn’t clear to me.
If init is meant to return unit generators, it suggests usage within a SynthDef.
But a Buffer should not be allocated inside a SynthDef. You can get away with it once, but if you try to reuse a SynthDef containing your SimpleRecorder, each instance will try to use the same Buffer… which is bad.
So, could you say a little more about the interface you intend? That is, what are the object’s inputs and outputs? What’s the context where you want to use the object? I think this needs to be a bit more clear before throwing code at the wall and hoping it sticks.
My guesses would be that it’s either for live-sampling (in-memory only – in this case the Phasor output needs to be made available elsewhere, and also use more than 1 second of storage), or to write to disk (in which case you’d need DiskOut, not BufWr). Either way there’s more stuff going on than is present in the first sketch.
IMO spontaneously creating a SynthDef inside a class is a good practice
SynthDefs are resources, to be created and discarded when needed. SynthDef itself is a complex class because its job is complex, but it’s also a fairly direct language-side representation of a GraphDef in the server. As such, it’s actually a low level object! There’s no need to avoid creating SynthDefs (and in fact, with SC’s design, it’s often impossible to do things without creating SynthDefs).