It’s a little different, though maybe not in your usecase. Ndef’s are “node proxies”, which handle the creation and management of nodes on the server. For example, you can change the Ndef while the node is playing, and behind the scenes the Ndef will create a new node, fade it in, and then fade out the old node and release it. As such Ndef’s are good for live coding. The synth command just makes a node on the server. So either will work, but Ndef’s are more complicated…

1 Like

thank you…

yeah, last time I was doing more Live coding so ‘fell in love’ with Ndef :slight_smile:
so picked up those examples, but of course had forgotten the background.

so when playing this morning, indeed I found issues using Ndef due to the functionality you described, which was quickly fixed by using a simple synthdef - which was cool - thank you.
also means Im go go dig back into the jitproxy stuff again, to refamiarise myself - make sure im using the right tool for the job :wink:

having fun though , its nice to be jumping back into the SC…

1 Like

Hello!
Been quite a while since I posted on the forum, I recently moved to Chicago for school and have been very busy with classes. Anyways, I hope everyone is well!

So this semester I’m taking an audio programming course taught in SuperCollider, and while working on my final project, SuperCollider stopped receiving audio input.

I am working on macOS Mojave 10.14, and SuperCollider 3.9.3.
Here are my audio settings when booting the server:

Number of Devices: 6
0 : “Built-in Microph”
1 : “Built-in Output”
2 : “Soundflower (2ch)”
3 : “Soundflower (64ch)”
4 : “Pro Tools Aggregate I/O”
5 : “Aggregate Device”

“Built-in Microph” Input Device
Streams: 1
0 channels 2

“Built-in Output” Output Device
Streams: 1
0 channels 2

SC_AudioDriver: sample rate = 44100.000000, driver’s block size = 512
SuperCollider 3 server ready.

Here is an example of code I am trying to run:

x = {SoundIn.ar(0) }.play;

The Server Meter doesn’t show any input response.
Using other applications such as Ableton or Max I am able to get audio input normally.
I have tried killing all servers, closing the application, changing my input device (between my computer’s built in, and my external audio interface) and even uninstalling SuperCollider.
I spoke with my professor as well and she couldn’t figure it out either.

Any insight on what might be going on and possible fixes would be greatly appreciated!

1 Like

just a thought, mojave now requires an app permission to access audio input. this has to be requested in the app’s Info.plist.

maybe your SC biuld is not doing this; 3.9.3 was released back in april when only preview mojave builds were available, so i think this seems likely.

maybe worth trying a newer build

3 Likes

Nailed it, thank you so much!

2 Likes

And… since you wrote that, 3.10 is out…

2 Likes

Hello again!

So I am working on an audio input recorder and looper but am struggling to get it to work the way I would like.

I am trying to:

1)Record into a buffer
2)Use a function to copy the buffer to a second buffer
3)Loop the second second buffer and play it

I think the problem is somewhere in my copyBuf function.
Perhaps I can’t just pass buffers as arguments?

Here is my code:

~recBuf_1 = Buffer.alloc(s, 44100 * 12.0, 1); // Recording buffer 1
~loopBuf_1 = Buffer.alloc(s, 44100 * 12.0, 1); // Looping Buffer 1

// Recorder SynthDef
(
SynthDef(\simpleRecorder, {
	arg bufNum, run = 1, ;
    var sig;
	sig = SoundIn.ar(0!1);
    RecordBuf.ar(sig, bufNum, loop: 0);
}).add;
)

// Looper SynthDef
(
SynthDef(\simpleLooper, {
	arg  amp = 1.0, out = 0, bufNum, rate = 1.0, startPos = 0.0, loop = 1;
    var playBuf;
    playBuf = PlayBuf.ar(1, bufnum: bufNum, rate: rate, startPos: startPos, loop: loop)*amp;
    Out.ar(out, playBuf);
}).add;
)


//copyBuf function
(
FunctionDef( \copyBuf, {
	arg inBuf, outBuf;
	var tempArray;
	tempArray = \inBuf.loadToFloatArray(); //copy recBuf to tempArray
	\outBuf.loadCollection(tempArray); //copy tempArray to loopBuf
});
)



x = Synth(\simpleRecorder);
Function.value(\copyBuf, [~recBuf_1, ~loopBuf_1]);
y = Synth(\simpleLooper, [\bufNum: ~loopBuf_1.bufnum]);

I’m still very much a novice working with supercollider so any help would be greatly appreciated!
cheers!

1 Like

Try this:

Buffer.freeAll;
~recBuf_1 = Buffer.alloc(s, 44100 * 2, 1); // Recording buffer 1
~loopBuf_1 = Buffer.alloc(s, 44100 * 2, 1); // Looping Buffer 1

(
// Recorder SynthDef
SynthDef(\simpleRecorder, {
	arg bufNum, run = 1;
	var sig, doneTrig;
	sig = SoundIn.ar(0);
	RecordBuf.ar(sig, bufNum, loop: 0);

	// a little clean-up
	doneTrig = TDelay.kr(Impulse.kr(0), BufDur.ir(bufNum));
	SendReply.kr(doneTrig, '/rec/done');
	FreeSelf.kr(doneTrig);
}).add;

// Looper SynthDef
SynthDef(\simpleLooper, {
	arg amp = 1.0, out = 0, bufNum, rate = 1.0, startPos = 0.0, loop = 1;
	var playBuf;
	playBuf = PlayBuf.ar(1, bufnum: bufNum, rate: rate, startPos: startPos, loop: loop)*amp;
	Out.ar(out, playBuf);
}).add;
)

(
//copyBuf function
~copyBuf = {
	arg inBuf, outBuf;
	inBuf.loadToFloatArray(action: {
		arg x;
		outBuf.sendCollection(x);
	});
};

// catch notification that recording has finished
OSCdef.newMatching(\startLooper, {
	~copyBuf.value(~recBuf_1, ~loopBuf_1);
	y = Synth(\simpleLooper, [\bufNum: ~loopBuf_1]);
},"/rec/done").permanent_(true);
)


x = Synth(\simpleRecorder, [\bufNum, ~recBuf_1]);
2 Likes

Hey! Wow this is great, thanks so much for helping out!
Would you be able to explain a little what is going on with the OSCdef?
It like listens for the /rec/done message from the simpleRecorder, then runs the copyBuf function and creates the simpleLooper synth?

Yes that’s all it does. You can of course call copyBuf and instantiate the simpleLooper manually if you want as well.

1 Like

Hello!
Is there a way to check if a specific node exists in a group?
I am trying to create an if statement that does the following:
if the node doesn’t exist -> create a synth node
if the node already exists -> replace with a new synth node

I’m sure this is relatively simple but I can’t figure it out!

I don’t have my computer with me rn but I know there’s a method to print the node tree to the console…I usually have to swim on the doc system to remember it. Perhaps start with Server?

Hey! Yeah there definitely is, s.queryAllNodes I think. I was just running into issues implementing that info into a conditional statement.
But I kinda figured out a work around by registering the nodes with NodeWatcher and then the isRunning method. A little sloppy for how my code is structured because I need to create the Synths before I’m actually using them but it works so I’ll take it!

Look here: http://doc.sccode.org/Guides/NodeMessaging.html

I’d like to use my new Korg nanoKONTROL 2 for a SuperCollider project, but couldn’t figure out how to change only one key of my Pdef without setting up a new instance. Do you have any advice?

You can find my code on GitHub: https://github.com/kenokenobingo/studies.

Take a look at the helpfule for Pbindef I believe that will allow you to change only one key value at a time.

1 Like

Saw this video by Eli Fieldsteel recently, maybe the linked scripts in the description will be useful?

1 Like

hi keno,

considering context here, i assume that by changing a single key in your Pdef, you mean modulating it in response to MIDI data.

you can’t change a key in Pbind after it’s been created and started playing. when you write e.g. \dur, 0.1 in a Pbind, that \dur will always be 0.1 — it can’t be changed externally. instead, you can plug special patterns into keys so that you can modulate the parameters you want.

the quickest way in the context of a Pbind is to use Pfuncn, which executes a function over and over again. in this case we write a function which repeatedly returns the value of a variable. changing that variable modulates the parameter in the Pbind:

var dur = 1.0;

Pbind(*[
    instrument: \synth,
    dur: Pfuncn({ dur }, inf)
]).play;

// now setting 'dur' modulates the \dur key. example:
MIDIdef.cc(\dur, { |val, num, chan, src|
    dur = val.linlin(0, 255, 1.0, 3.0);
}, 14);

this is convenient enough when you only have one parameter to deal with, but it gets out of hand when you have 20 of them. for a more scalable approach, i would lump all modulatable keys into a single big event that you can modify at will. use Pfuncn to return it repeatedly and ensure you’re getting the latest updates, and then use Pbindf to supply additional keys.

var baseEvent;

baseEvent = (
    dur: 1.0,
    freq: 440,
    amp: 0.1
);

Pbindf(Pfuncn({ baseEvent }, inf), *[
    instrument: \pad,
    filterfreq: Pexprand(1000, 8000, inf)
]).play;

// now setting baseEvent[\dur] modulates the \dur key. example:
MIDIdef.cc(\dur, { |val, num, chan, src|
    baseEvent[\dur] = val.linlin(0, 255, 1.0, 3.0);
}, 14);

an important limitation is that this will not modulate parameters continuously — parameters are only read at the beginning of each note. the patterns system is a discrete sequencer and doesn’t really have a conception of continuously running control signals. if you do want continuous modulation, let me know and i can describe how to do that instead. (my solution involves instantiating all synths inside a Group and calling .set on that Group, which automatically broadcasts parameter modulations to the synths.)

5 Likes

Thank you so much for your answer, @nathan! I was hesitating to use a global variable as described in the documentation because I considered it bad style.
Continous modulation sounds awesome. If you can spare some time, I’d like to have a look at your approach.

Wow, haven’t discovered it yet!

1 Like