Making a resampler with RecordBuf

Hello all,

I am using RecordBuf to record audio input to buffers and then play them inside a Pdef in realtime. I would like to be able to record audio into 8 different buffers. Right now I have it working for 1 buffer, however I am running into a few issues. Below is an overview.

I created this GUI component with a ‘Resample’ button that uses .mouseDownAction to start recording when the button is pressed down:

image

Here is the code for this button. I am using sig = SoundIn.ar(0) and RecordBuf for this.

~resamplerButton = Button(w, Rect(10, 100, 80, 26))
	.states_([["Record", Color.black, Color.white]])
	.mouseDownAction_({
		a = {
			var sig;
			'Recording...'.postln;
			sig = SoundIn.ar(0);
			RecordBuf.ar(sig, ~bufbank[80], 0, \reclevel.kr(0.1), \prelevel.kr(0), 1, 1);
		}.play;
	})
	.action_({ arg butt, mod;
		'Finished recording'.postln;
		a.release(0.1);
	});

The audio is recording and being saved to ~bufbank[80], however the audio is very quiet. Also, when I press this button, I am getting overlap of the music playing + the sound that is being recorded and it becomes quite distorted. Is it possible to silently record this audio?

Secondly, I am routing all of my audio to this Master output channel:

~master1 = (
		SynthDef(\mastermix, {
			arg moogcut = 29000, gain = 0, highcut = 22, masterfader = 1, mix = 0.33, room = 0.5, damp = 0.5, delaytime = 0, pitchRatio = 1, pitchDispersion = 0, fader = 1;
			var sig;
			sig = In.ar(~patch4, 2);
			sig = FreeVerb.ar(sig, mix, room, damp);
			sig = Compander.ar(sig);
			sig = Limiter.ar(sig);
			sig = Out.ar(0, sig * masterfader);
		}).play(~master1);
	);

Instead of recording ‘SoundIn’, is it possible to Record the sound directly from ~master1? Would that make any difference?

And my last question- Right now I am defining the length of the buffer inside of Buffer.alloc. It is my understanding that the s.sampleRate represents the sample rate of the server, and multiplying it by 4 gives me the total number of samples for a 4-second buffer:

8.do({ arg i;
		~bufbank.add(Buffer.alloc(s, s.sampleRate * 4, 1));
	});

Is it possible to have the buffer be exactly equal to how long as the recording is?

Thank you all for your help.

\reclevel.kr(0.1) is, by default, making it 20 dB quieter than the input (-20 dB == 0.1).

I use live sampling a lot in my work. If you’re recording a mic, setting the preamp trim on the soundcard is crucial, to get a good solid signal but still leave some headroom for transients. Then, I dynamic-compress the xxxx out of it and amplify, to get more uniform dynamics. That last bit is optional, but you might add it eventually.

If you’re recording a mic, then the sound from your instrument is going into the air, then to the mic. The sound from the speakers is also going into the air, but you want to stop it from going into the mic. There’s… really no way to do that. Onstage, it can help to use a cardioid mic: if the speakers are at stage front, pointing toward the house, then you’re behind the back of the speakers, with the mic’s live zone pointing toward you and the dead zone pointing toward the speakers. That will reduce but not eliminate bleed. In a small home studio, you could use headphones.

Yes, but mind execution order.

Buffer memory has to be allocated in advance. Therefore, you have to know the (maximum) recording time in advance.

If you use Phasor + BufWr instead of RecordBuf, then Phasor tells you exactly how many samples had been recorded at the moment of stopping. Then, you can send that back to the language and rec_buf.copyData(...) into a new buffer, which you can size to match.

hjh

1 Like

Hey @jamshark70,

Thank you for all of your input. I think you answered most of my questions regarding RecordBuf.

Regarding this,

How would execution order come into play here? I did read through this document: Order of execution | SuperCollider 3.12.2 Help but I am not sure how it would apply in this case.

“The rule is simple: if you have a synth on the server (i.e. an “effect”) that depends on the output from another synth (the “source”), the effect must appear later in the chain of nodes on the server than the source.”

Would the effect in this case be the RecordBuf? In that case, order of execution should be fine then, because the source, PlayBuf, would have already played?


For more context, this is my node tree.

‘mainbuf’ is the PlayBuf SynthDef for the buffers I am currently playing and would also like to resample with RecordBuf. The sound gets routed through the channels to ‘mastermix’ depending on the “patch”. Right now the RecordBuf is outside of this, existing as temp__63, which I think might be causing problems…

I had updated my code earlier to try and record the ‘mastermix’ directly rather than SoundIn because of interference but was unable to get audio to save to the buffer. I was trying to use ~sig = In.ar(~patch4, 2) because this is the main bus or “patch” where all of the audio for ch1-ch3 is going to for the mastermix.

~patch4 = Bus.audio(s, 2);

~resamplerButton = Button(w, Rect(10, 100, 80, 26))
.states_([["Record", Color.black, Color.white]])
.mouseDownAction_({
	a = {
		var sig;
		'Recording...'.postln;
        // Instead of using SoundIn.ar(0), I am using In.ar(~patch4, 2). This is a bus where all of my audio is being routed for the Master channel
		sig = In.ar(~patch4, 2);
		RecordBuf.ar(sig, ~bufbank[80], \reclevel.kr(1), \prelevel.kr(0), 1, 1, doneAction: 0);
	}.play;
})
.action_({ arg butt, mod;
	'Finished recording'.postln;
	a.stop(0.1);
});

Does this look like the right direction? Do you think I should work on grouping the RecordBuf with the mainbuf?

Thanks again

The order of execution is shown in the node tree window, top to bottom.

Currently temp_63 is at the top, meaning that, in each processing cycle, it runs before everything else. Any signals written onto buses after this will not be available to In.ar.

Yes, the RecordBuf synth is the “effect” in that it consumes a signal produced by another synth. So it needs to come later in the node tree than any potential source. If the source will be the master mix synth at the end, then the recording synth needs to come after that.

hjh

1 Like

Got it. Thank you very much for your help again @jamshark70. Got this working by following order of execution!