Iām still no further ahead regarding the theory but this seems to solve my immediate issue.
Ok, hereās an attempt to clarify a bit more (hope it doesnāt do the opposite and blur)
BufDur(b)
is the same as writing BufDur.new(b)
and this does not evaluate to a number - it gives you a new object. try it by runningā¦
BufDur(b); //-> a BufDur
So in for example .linexp(0.0,1.0, 1,BufDur(b))
the linexp method canāt really know what the value for the fourth argument should be. It expects a number but we give it a new object.
In a parallel universe linexp might give you a warning or crash here, but our linexp doesnāt complain so itās not easy to spot the error. It just swallows the new object and fail silently or you get some unexpected result.
That line must be written .linexp(0.0,1.0, 1, b.duration)
for it to work. Then the linexp method will get the duration of b as a proper floating-point value for the fourth argument.
When to use b.duration
over BufDur.kr(b)
is a separate question. It has to do with language vs server code.
Because BufDur is a UGen it is only useful inside a synthesis graph i.e. within a SynthDef/Ndef or {}.play construction. Think of a BufDur as something that sends out a continuous signal.
Your Ndef(\tgrains).set
and Ndef(\tgrains).addSpec
are both language side code though so a signal there wonāt work. You will want to use b.duration there as it returns a single value.
compareā¦
s.boot;
b = Buffer.alloc(s, 1000); //one thousand samples, 1000/44100ā0.0227 (or whatever sr you use)
//sclang side...
b.duration
//a single number
//as b.duration returns a number it also can be used inside a synth...
Ndef(\a, {b.duration.poll; DC.ar(0)}).play
Ndef(\a).clear
//but then that particular duration value is hardcoded into the definition - no good for general purpose code
//it is better practice to use a BufDur ugen inside of a synth...
Ndef(\b, {BufDur.kr(b).poll; DC.ar(0)}).play
Ndef(\b).clear
//even though in this example it make no difference. Just as bad we have now hardcoded the buffer number b into the definition.
//the whole reason to use BufDur though is that you can use an argument and query the duration of any buffer...
Ndef(\c, {|buf| BufDur.kr(buf).poll; DC.ar(0)}).set(\buf, b).play
c = Buffer.alloc(s, 2000);
Ndef(\c).set(\buf, c);
Ndef(\c).clear
//now your synth code is generic and you can use it with any buffer (also swap buffers while the synth is running)
and last hereās a common error that we all run into from time to timeā¦
Ndef(\d, {BufDur(b).poll; DC.ar(0)}).play //BAD
Ndef(\d).clear
//this is how BufDur fail silently - BufDur(b) need a rate - either .ir or .kr
_f
#|
fredrikolofsson.com musicalfieldsforever.com