Multichannel Input - Granular Synthesis

Hello together,

I am using Eli Fieldsteel’s Granulator (SuperCollider Tutorial: 26. Granular Synthesis, Part II - YouTube) and I want to use 4 Input Channels from my external soundcard instead of just 1. I created four Input Bus Channels (s.options.numInputBusChannels = 4) and allocated those four channels also in SoundIn.ar(0…3), but I cannot get any signal from Input 2-4. Do I have to allocate in addition to that 4 channels to Buffer or am I missing something? Or do I have to create multiple Buffers instead of just one?

Would be super thankful for any help!

(
s.options.device = "Fireface UC Mac (23903196)";
s.options.numOutputBusChannels = 2;
s.options.numInputBusChannels = 4;
s.reboot;
s.meter;
)

b = Buffer.alloc(s, s.sampleRate * 5, 1); // b = Buffer.alloc(s, s.sampleRate * 5, 4); ???

(
~micBus = Bus.audio(s, 1);
~ptrBus = Bus.audio(s, 1);
)

(
SynthDef.new(\mic, {
	arg in = (0..3), out = 0, amp = 1;
	var sig;
	sig = SoundIn.ar(in) * amp;
	Out.ar(out, sig);
}).add;




SynthDef.new(\ptr, {
	arg out = 0, buf = 0;
	var sig;
	sig = Phasor.ar(0, BufRateScale.kr(buf), 0, BufFrames.kr(buf));
	Out.ar(out, sig);
}).add;


SynthDef.new(\rec, {
	arg ptrIn = 0, micIn = 0, buf = 0;
	var ptr, sig;
	ptr = In.ar(ptrIn, 1);
	sig = In.ar(micIn, 1);  
	BufWr.ar(sig, buf, ptr);
}).add;


SynthDef.new(\gran, {
	arg amp = 0.5, buf = 0, out = 0,
	atk = 1, rel = 1, gate = 1,
	sync = 1, dens = 40,
	baseDur = 0.05, durRand = 1,
	rate = 1, rateRand = 1,
	pan = 0, panRand = 0,
	grainEnv = (-1), ptrBus = 0, ptrSampleDelay = 2000,
	ptrRandSamples = 5000, minPtrDelay = 1000;

	var sig, env, densCtrl, durCtrl, rateCtrl, panCtrl,
	ptr, ptrRand, totalDelay, maxGrainDur;

	env = EnvGen.kr(Env.asr(atk, 1, rel), gate, doneAction: 2);
	densCtrl = Select.ar(sync, [Dust.ar(dens), Impulse.ar(dens)]);
	durCtrl = baseDur * LFNoise1.ar(100).exprange(1/durRand, durRand);
	rateCtrl = rate * LFNoise1.ar(100).exprange(1/rateRand, rateRand);
	panCtrl = pan + LFNoise1.kr(100).bipolar(panRand);

	ptrRand = LFNoise1.ar(100).bipolar(ptrRandSamples);
	totalDelay = max(ptrSampleDelay - ptrRand, minPtrDelay);

	ptr = In.ar(ptrBus, 1);
	ptr = ptr - totalDelay;
	ptr = ptr / BufFrames.kr(buf);

	maxGrainDur = (totalDelay / rateCtrl) / SampleRate.ir;
	durCtrl = min(durCtrl, maxGrainDur);

	sig = GrainBuf.ar(
		2,
		densCtrl,
		durCtrl,
		buf,
		rateCtrl,
		ptr,
		2,
		panCtrl,
		grainEnv
	);

	sig = sig * env * amp;
	Out.ar(out, sig);
}).add;
)

At which point, in your processing, do you realize you’ve lost those inputs ?
When you are monitoring your processing with your headphone ?
If your monitoring system is a 2 channels one (like a headphone) you could have an issue in your patch :

(
SynthDef.new(\mic, {
	arg in = (0..3), out = 0, amp = 1;
	var sig;
	sig = SoundIn.ar(in) * amp;
	Out.ar(out, sig);
}).add;

In this one, you have a 4-channels Input that you send to a 4-channels output. If you’re monitoring with a 2-channels system, without further mixing your 4 channels to 2, you will not hear the channels 2 and 3.
Without knowing how you intend to work with 4 channels, you might have a look at Splay or Mix to downsize your channels to 2 channels.

(
SynthDef.new(\mic, {
	arg in = (0..3), out = 0, amp = 1;
	var sig;
	sig = SoundIn.ar(in) * amp;
	Out.ar(out, Splay.ar(sig,0.8));
}).add;
1 Like

… accepts only mono buffers (per help file: “the buffer holding a mono audio signal. If using multi-channel files, use Buffer.readChannel”).

The only way is to have one buffer, and one GrainBuf, per channel.

There isn’t an integrated multichannel solution.

hjh

1 Like

Thank you! It works fine with Splay.ar.

SynthDef.new(\mic, {
	arg out = 0, amp = 1;
	var sig;
	sig = SoundIn.ar([0, 1, 2, 3]) * amp;
	sig = Splay.ar(sig, 0.8);
	Out.ar(out, sig);
}).add;