How can I start looping from a buffer with a message?

About symbols: it’s an alternative syntax for synthdef arguments, that makes it easier to specify their rate (e.g. tr is trigger rate, a convenient way to send triggers to synths). Find more info on this post about NamedControl.
About SendReply: I’m quite sure (not tested yet) that you can receive those OSC messages also in your client, regardless of it being sclang or not. I think it would be the way to achieve most flexibility and precision.

But ok, if you are ok setting up your buffers beforehand with a predefined length, then you could just have a synthdef that records the whole buffer when the synth is created, and then keeps looping. Something super simple like

SynthDef(\recLoop){|in=0,out=0,buf=0,gate=1|
	var sig = SoundIn.ar(0);
	var rec = RecordBuf.ar(sig,buf,loop:0);
	// start playback when rec is done
	var recDone = Done.kr(rec);
	var play = PlayBuf.ar(1,buf,1,recDone,loop:1);
	// this env helps avoiding clicks
	var env = EnvGen.kr(Env.asr(0.02,1,0.02),recDone*gate,doneAction:2);
	Out.ar(out, play * env);
}.add

This would record always “the future”: you create a synth and it starts recording. If you want to loop “the past”, then you need to have a cyclical buffer like we discussed before, and to handle it you need to copy to other buffers the material you want to loop, otherwise it will be overwritten at one point (soon, considering that you might not want a buffer to be longer than 5 minute).
I now realize that you could combine the two approaches:

  1. have a synth recording continuously to a cyclical buffer
  2. when you want to loop a certain duration of time, allocate a buffer of that length and create a synth like the one above, but record from the cyclical buffer rather than from an input:
// modified version to rec from source buffer
SynthDef(\recLoop){|in=0,out=0,buf=0,sourceBuf=0,sourceStart=0,gate=1|
	var sig = PlayBuf.ar(
		1,sourceBuf,1,1,sourceStart*BufSampleRate.ir(sourceBuf)
	);
	var rec = RecordBuf.ar(sig,buf,loop:0);
	// start playback when rec is done
	var recDone = Done.kr(rec);
	var play = PlayBuf.ar(1,buf,1,recDone,loop:1);
	// these envs helps avoiding clicks
	var recEnv = EnvGen.kr(Env.asr(0.02,1,0.02),1-recDone);
	var env = EnvGen.kr(Env.asr(0.02,1,0.02),recDone*gate,doneAction:2);
        // while recording, play rec, when rec is done, play play :)
	Out.ar(out, (rec*recEnv) + (play * env));
}.add

Maybe this is more like something you want?

1 Like