Audio input with event Tgrain

Hello,

I’m very new to SC and trying to use AudioIn to trigger a synth. My idea is to have an audio input, record it in a buffer, and then play it back in a pattern (it can be any synth, but in this case, i’m using Tgrain from the example )

Please let me know what buffer I have to use instead of .alloc

d= Buffer.alloc(s,44100*20.0,2);

(
SynthDef(\audioPure, {
arg in=0, out=0,deltime=0.7, mix = (-0.5), amp=3 ,record=1;
var sig, delay,rec;
sig= AudioIn.ar(1) *amp;
rec = RecordBuf.ar(sig, d, run:record, loop:1);
CombC.ar(rec,0.4,0.3,2,mul:5.0);
}).send(s);
)

(
{
var trate, dur, rate;
trate = MouseY.kr(2,200,1);
dur = 4 / trate;
rate = Dseq([10, 1, 1, 0.5, 0.5, 0.2, 0.1], inf);
TGrains.ar(2, Impulse.ar(trate), PlayBuf.ar(2,d), rate, MouseX.kr(0,BufDur.kr(b)), dur, Dseq([-1, 1], inf), 0.1, 2);
}.scope(zoom: 4);
)

hi velma!

there are a few things happening in this patch (some of which are kind of subtle actually).

the Buffer.alloc looks good except that there is a subtle thing in the documentation of TGrains that the buffer it uses should be mono and here you have allocated a stereo buffer. SC has one annoying behavior that it tends to just silently fail when there is a mismatch like that and it trips up a lot of people new to SC I think.

the other things to fix up:

  • looking at the documentation for TGrains you’ll see that the 3rd argument is meant to be a buffer number (rather than something that plays a buffer (in this case you have put PlayBuf)). This just means that Tgrains wants the actual buffer and it will deal with the playback of it. so you can swap out PlayBuf.ar(2,d) simply with d.bufnum (or use the shortcut of letting SC figure out the actual number by passing in the buffer directly so just d).

  • there is a typo in the BufDur.kr(b). I assume that should be d instead of b

  • the \audioPure SynthDef you create is simply the definition of a synth that can be created. you’ll need to actually create/instantiate a version of that SynthDef to get the buffer recorder actually running (note that the Tgrains function you ran in the second part is played automatically when you use .scope())

  • I also updated the AudioIn to SoundIn as AudioIn is no longer used and exists for legacy purposes. SoundIn is much more convenient.

here’s an updated version with those fixes:

// changed this to 1 channel rather than two because TGrains expects a mono buffer
d= Buffer.alloc(s,44100*20.0,1);

(
SynthDef(\audioPure, {
arg in=0, out=0,deltime=0.7, mix = (-0.5), amp=3 ,record=1;
var sig, delay,rec;
	// use SoundIn rather than AudioIn almost always
	sig= SoundIn.ar(1) *amp;
rec = RecordBuf.ar(sig, d.bufnum, run:record, loop:1);
CombC.ar(rec,0.4,0.3,2,mul:5.0);
}).send(s);
)

(
x.free;
x = {
var trate, dur, rate;
trate = MouseY.kr(2,200,1);
	
dur = 4 / trate;
	
rate = Dseq([10, 1, 1, 0.5, 0.5, 0.2, 0.1], inf);
	
	// passing d here directly instead of a PlayBuf.ar (and fixed the BufDur.kr(b) to BufDur.kr(d))
TGrains.ar(2, Impulse.ar(trate), d, rate, MouseX.kr(0, BufDur.kr(d)), dur, Dseq([-1, 1], inf), 0.1, 2);
	
}.scope(zoom: 4);
)

// start a running version of the SynthDef \audioPure
a = Synth(\audioPure);
1 Like

Hi Velma, along with what @scazan mentioned, in the audioPure synth, you shouldn’t take the output of RecordBuf and use it (I think?). Also the following CombC doesn’t do anything with its audio.
If you want to apply an effect to some sound, and then record it, you must do the effect before the recording.

This is how I would write what you are after. I’m using SynthDef.play to define and create a synthdef in one action. I’ve also wrapped the whole thing in s.waitForBoot and used s.sync.

(
s.waitForBoot {
	~buffer = Buffer.alloc(s, 44100*20);
	
	s.sync;
	
	~recorder = SynthDef(\recorder, {
		var sig = SoundIn.ar(\micIn.kr(0));
		RecordBuf.ar(sig * \amp.kr(1), \buf.kr(), loop: 1);
	}).play(args:[\amp, 1, \buf, ~buffer, \micIn, 0]);
	
	s.sync;
	
	~player = SynthDef(\player, {
		var triggerRate = MouseY.kr(2, 200, 1);
		var grains = TGrains.ar(
			numChannels: 2, 
			trigger: Impulse.ar(triggerRate),
			bufnum: \buf.kr(), 
			rate: Dseq([10, 1, 1, 0.5, 0.5, 0.2, 0.1], inf);,
			centerPos: MouseX.kr(0, BufDur.kr(\buf.kr())),
			dur: \overlap.kr(4) / triggerRate,
			pan: Dseq([-1, 1], inf),
			amp: 0.1,
			interp: 2
		);
		Out.ar(\out.kr(0), grains);
	}).play(~recorder, [\buf, ~buffer, \out, 0], \addAfter);
}
)
1 Like

Hello Scott and Jordan,

Thank you so much for your answer. @Scott, I got the audio signal in but can’t get the signal out. I tried Out.ar in the Synthdef, but I still don’t hear anything. What did I do wrong?

@Scott, your code does work! thank you so much. I’ll have to study how it works, but thank you.

Bests,
Velma.

One more question,

When I use SoundIn with any audio input, I don’t hear the signal out, but when I use AudioIn it works perfectly. However, I got a message that says " The definition of ‘Meta_AudioIn:ar’ is to be found here"

ps: I use Motu 8 channels as a sound card.
Any thoughts?

You need to give it the number 0 for the first mic input.

SoundIn.ar(\micIn.kr(0));
1 Like