[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-users] Re: ERROR: SynthDef xxx not found: Please help



Battuta,

It seems you are following my video tutorial no. 3 and having some trouble.
I admit that this particular section of the video would benefit from more
detail and description; it goes by rather quickly. Let me try to explain
what's going on in the pulseTest SynthDef, why the other examples in this
thread don't work, and maybe offer some additional help.

Here is the original code:

(
SynthDef.new(\pulseTest, {
	arg ampHz=4, fund=40, maxPartial=4, width=0.5;
	var amp1, amp2, freq1, freq2, sig1, sig2;
	amp1 = LFPulse.kr(ampHz, 0, 0.12) * 0.75;
	amp2 = LFPulse.kr(ampHz, 0.5, 0.12) * 0.75;
	freq1 = LFNoise0.kr(4).exprange(fund, fund*maxPartial).round(fund);
	freq2 = LFNoise0.kr(4).exprange(fund, fund*maxPartial).round(fund);
	freq1 = freq1*LFPulse.kr(8, add:1);
	freq2 =  freq2*LFPulse.kr(6, add:1);
	sig1 = Pulse.ar(freq1, width, amp1);
	sig2 = Pulse.ar(freq2, width, amp2);
	sig1 = FreeVerb.ar(sig1, 0.7, 0.8, 0.25);
	sig2 = FreeVerb.ar(sig2, 0.7, 0.8, 0.25);
	Out.ar(0, sig1);
	Out.ar(1, sig2);
}).add;
)

Synth.new(\pulseTest);

As a general rule, particularly with new users, you should always make
certain to read the code thoroughly and intimately understand the signal
flow, and don't make changes unless you really understand what you are doing
-- there are an infinite number of ways to damage your ears and speakers
with SC.

Here is the correct code again, with comments:

(
SynthDef.new(\pulseTest, {
	
	//here we declare arguments that will
	//be used for UGen controls
	arg ampHz=4, fund=40, maxPartial=4, width=0.5;
	
	//and here we declare variables that will be
	//used to store signals and other data
	var amp1, amp2, freq1, freq2, sig1, sig2;
	
	//two individual pulse waves will control the amplitude of two
	//different sounds; this will create a repeating "on-off" quality
	amp1 = LFPulse.kr(ampHz, 0, 0.12) * 0.75;
	amp2 = LFPulse.kr(ampHz, 0.5, 0.12) * 0.75;
	
	//two non-interpolating noise generators randomly output values
	//between fund and maxPartial, rounded to the nearest multiple of 
	//fund. Values are chosen 4 times per second.
	freq1 = LFNoise0.kr(4).exprange(fund, fund*maxPartial).round(fund);
	freq2 = LFNoise0.kr(4).exprange(fund, fund*maxPartial).round(fund);
	
	//these two pulse waves have a value of 1 added to them, so their output
	//alternates between 1 and 2 (normally this is 0 to 1). This value is
	//multiplied by the frequency variables above, so each freq variable
	//regularly jumps up by an octave, then back down. The first pulse wave
	//does 8 octave jumps per second, the second does 6.
	freq1 = freq1*LFPulse.kr(8, add:1);
	freq2 =  freq2*LFPulse.kr(6, add:1);
	
	//here are the actual sound sources, which are audio-rate pulse waves.
	//our amp/freq variables from earlier are used to control this sound.
	sig1 = Pulse.ar(freq1, width, amp1);
	sig2 = Pulse.ar(freq2, width, amp2);
	
	//reverb is applied to each sound source.
	sig1 = FreeVerb.ar(sig1, 0.7, 0.8, 0.25);
	sig2 = FreeVerb.ar(sig2, 0.7, 0.8, 0.25);
	
	//sig1 is sent to output 0 (left speaker), and sig2 is sent
	//to output 1 (right speaker).
	Out.ar(0, sig1);
	Out.ar(1, sig2);
}).add;
)

Synth.new(\pulseTest);

//an example of playing the Synth with non-default argument value(s)
//in this case, our noise generator has a higher upper bound on its
//output range, so our resulting sound encounters a greater range of
//harmonic partials.
Synth.new(\pulseTest, [\maxPartial, 20]);

Let's take a look at your modified version and unpack the mistakes:

(
SynthDef.new(\pulseTest, {
	arg fund=40, maxPartial=8, width=0.5;
	var freq1, freq2, sig1, sig2;
	freq1 = LFNoise0.kr(4).exprange(fund, fund*maxPartial).round(fund);
	freq1 = LFNoise0.kr(4).exprange(fund, fund*maxPartial).round(fund);
	freq1 = freq1*LFPulse.kr(8, add:1);
	freq2 = freq2*LFPulse.kr(6, add:1);
	sig1 = FreeVerb.ar(sig1, 0.7, 0.8, 0.25);
	sig2 = FreeVerb.ar(sig2, 0.7, 0.8, 0.25);
	Out.ar(0, sig1);
	Out.ar(1, sig2);
}).add;
)

First, in line 5, freq1 is given a value of LFNoise0. Then, in line 6, the
exact same thing happens again. This is redundant, but won't necessarily
return an error message. Obviously, you meant to begin line 6 with freq2
instead of freq1. The problem here is that freq2 does not get assigned a
value (and remains equal to "nil"), so line 8 returns an error indicating
that the multiplication operator can't be resolved (nil multiplied by a
number is not defined).

Second, a similar problem, you never give sig1 or sig2 a value before using
them as an input source for FreeVerb. Like freq2, sig1 and sig2 initially
have a nil value, so applying reverb to them doesn't make sense. You've got
an undefined thing, and you're telling SC "hey, apply reverb to this thing
that doesn't exist yet." -- SC complains, as it should.

Ultimately, the biggest problem with your modification is that you have
removed the audio-rate sound source (Pulse.ar) entirely. It is not possible
to produce sound using a SynthDef unless an audio-rate sound source is a
part of it.

Let's take a look at Dan's modification -- DO NOT EVALUATE this one.

(
SynthDef.new(\pulseTest, {
	arg fund=40, maxPartial=8, width=0.5;
	var freq1, freq2, sig1, sig2;
	freq1 = LFNoise0.kr(4).exprange(fund, fund*maxPartial).round(fund);
	freq2 = LFNoise0.kr(4).exprange(fund, fund*maxPartial).round(fund);
	sig1 = freq1*LFPulse.ar(8, add:1);
	sig2 = freq2*LFPulse.ar(6, add:1);
	sig1 = FreeVerb.ar(sig1, 0.7, 0.8, 0.25);
	sig2 = FreeVerb.ar(sig2, 0.7, 0.8, 0.25);
	Out.ar(0, sig1);
	Out.ar(1, sig2);
}).add;
)

Dan has correctly identified the lack of audio-rate signals, and with the
best of intentions, has attempted to put them there for you. However, Dan's
example outputs a waveform whose output range is completely inappropriate
and dangerous for speakers (and ears):

freq1 and freq2 range between fund and fund*maxPartial, which are 40 and
40*8=320 by default. Then, these UGens are multiplied by audio-rate pulse
waves that range from 1 to 2, so the new, audio-rate output ranges between
40 and 40*8*2=640. After going through reverb UGens, these signals are sent
to your poor helpless speakers, resulting in crushingly distorted impulses.
Signals going to hardware outputs should never exceed ±1.

I understand the temptation to change code arbitrarily to "see what
happens," but it is irresponsible and definitely inadvisable. You should
always have a concrete idea/goal in mind when creating and modifying code. 

I agree with Andrea that you ought to familiarize yourself with basic,
general aspects of SC if you are having trouble understanding a synthesis
example like this. By the way, Andrea has a fantastic intro to SC, which I
highly recommend:

https://introtoscbook.files.wordpress.com/2015/04/introscsample61.pdf

Eli





--
View this message in context: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/ERROR-SynthDef-xxx-not-found-Please-help-tp7629648p7629655.html
Sent from the SuperCollider Users New (Use this!!!!) mailing list archive at Nabble.com.

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: https://listarc.bham.ac.uk/marchives/sc-users/
search: https://listarc.bham.ac.uk/lists/sc-users/search/