Noticed some oddities with Ddup, not sure too what extent this qualifies as a bug or not.
Thought I’d post it here before I start obsessively poking around in the source.
Essentially I’m trying to write a demand-rate .fold; figured this should be easy enough, since basically (as per Wavefolder):
folded_output = wave(input)
give or take some gain and period adjustment.
This works fine when wave = sin; the output of feeding it a Dseries is a quantized sine wave,
as was to be expected:
{Demand.ar(Impulse.ar(2000), 0, sin(Dseries(0, 4pi/200, 200)))}.plot(0.1)
not so much when I try it with a triangle wave, which is what the .ar fold presumably does:
(
var tri = {|x| 2 * abs(x - floor(x + 0.5))}; // should fold into [0, 1]
{Demand.ar(Impulse.ar(2000), 0, tri.(Dseries(0, 1/200, 200)))}.plot(0.1)
)
Here the tri function eats through the demand at twice the rate, because the x variable is called twice in the tri function.
Ok fine: I’ll put a Ddup around the input and that should do it:
(
var tridup = {|d| var x = Ddup(2, d); 2 * abs(x - floor(x + 0.5))}; // should fold into [0, 1]
{Demand.ar(Impulse.ar(2000), 0, tridup.(Dseries(0, 1/200, 200)))}.plot(0.1)
)
Well almost. There’s this little weirdness around the peak that results from the two x’s not actually being in phase.
(
var tripoll = {|d| var x = Ddup(2, d); (2 * abs(x.dpoll("absx") - floor(x.dpoll("floorx") + 0.5))).dpoll("outx")}; // should fold into [0, 1]
{Demand.ar(Impulse.ar(2000), 0, tripoll.(Dseries(0, 1/200, 200)))}.plot(0.1)
)
Now the expected pattern of polled values should be that the floorx and absx that come between two outx’s should be of the same value.
But… it turns out they’re not in phase because of something that happens at the beginning, where 3 floorx and 2 absx are polled before we get the first outx.
Relevant poll output:
floorx: 0 block offset: 0
absx: 0 block offset: 0
floorx: 0.005 block offset: 0
absx: 0.005 block offset: 0
floorx: 0.01 block offset: 0
outx: 0.005 block offset: 0
absx: 0.01 block offset: 24
floorx: 0.015 block offset: 24
... so now we're no longer in phase
outx: 0.01 block offset: 24
absx: 0.015 block offset: 48
floorx: 0.02 block offset: 48
outx: 0.015 block offset: 48
... this becomes visible in the plot around the peak
outx: 0.96 block offset: 40
absx: 0.485 block offset: 0
floorx: 0.49 block offset: 0
outx: 0.97 block offset: 0
absx: 0.49 block offset: 24
floorx: 0.495 block offset: 24
... leap form 0.98 output to...
outx: 0.98 block offset: 24
absx: 0.495 block offset: 48
floorx: 0.5 block offset: 48
... 1.01 output (should be 0.99)
outx: 1.01 block offset: 48
absx: 0.5 block offset: 8
floorx: 0.505 block offset: 8
outx: 1 block offset: 8
absx: 0.505 block offset: 32
floorx: 0.51 block offset: 32
outx: 0.99 block offset: 32
absx: 0.51 block offset: 56
floorx: 0.515 block offset: 56
outx: 0.98 block offset: 56
So here’s what I either don’t understand or is a bug:
Why don’t all the polled DUGens get called the same number of times? Presumably it’s not an issue with Dpoll, because the plots confirm the values reported by it.
Any ideas? (I’ve attempted to use Dunique for this, but it seems that works only with respect to a Demand.ar, and not within Demand chains…)
EDIT:
I replaced floor by trunc and at least now the two values are “in phase”, even though the very first pair is still somehow swallowed. I guess it has to do with how the usual AbstractFunction methods work when dealing with DUGens…
Otoh I didn’t expect trunc to do what it turns out to be doing… I thought it would truncate toward zero, but it seems to be downward always. The more you know…