Matt Barber brbrofsvl at gmail.com
Tue Jun 24 07:32:52 CEST 2008

```Hello,

The speed of this conversation makes me a little uncomfortable.
Perhaps [tabread4~] is not so weird after all:  if I'm not mistaken,
this is algebraically identical to the interpolation used in csound's
opcodes (e.g. oscil3)... I'm pretty sure both are piecewise Lagrange
polynomial interpolators (with x_i values equal to -1, 0, 1, and 2,
and interpolation between x=0 and x=1).  There seems to be, then, at
least some consensus about what generic "cubic interpolation" means,
given csound's rather long history to sort this out (though, I'm
surprised they haven't pulled together some of the algebra to reduce
the number of divides... maybe this leads to a more accurate result?).
I would be a lot more comfortable if it could be established exactly
what kind of cubic interpolation is in the [tabread4c~] -- this would
help with the naming standards as well.  Whatever new algorithms
become available should be extended to the vd~ class (or copies
thereof) as well.

BTW, the naming difference between csound's "oscil3" and [tabread4~]
(one has 3 and the other 4) seems justified, since csound will
automatically calculate the two extra guard points you need (tables in
csound can come with one guard point, but not more, so the 3 is a
clear reminder that it's doing cubic interpolation), and in PD, the
guard points should be put in the table by hand (so the 4 is a
reminder that it's always using 4 points).  This is one important
reason [tabread_transpose~] and the like should not be implemented,
unless the guard points are automatically generated in the object
class.

For the value of the consumer I appended the relevant code snippets...

Pd code, from d_array.c:

a = wp[-1].w_float;
b = wp[0].w_float;
c = wp[1].w_float;
d = wp[2].w_float;
cminusb = c-b;
*out++ = b + frac * (
cminusb - 0.1666667f * (1.-frac) * (
(d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)

)
);

csound code, from OOps/ugens2.c:

MYFLT frsq = fract*fract;
MYFLT frcu = frsq*ym1;
MYFLT t1 = y2 + y0+y0+y0;
ar[n] = amp * (y0 + FL(0.5)*frcu +
fract*(y1 - frcu/FL(6.0) - t1/FL(6.0) - ym1/FL(3.0)) +
frsq*fract*(t1/FL(6.0) - FL(0.5)*y1) +
frsq*(FL(0.5)* y1 - y0));

> Date: Mon, 23 Jun 2008 14:17:36 +0200
> From: Roman Haefeli <reduzierer at yahoo.de>
> Subject: Re: [PD] better tabread4~
> To: pd-list at iem.at
> Message-ID: <1214223457.6003.11.camel at yoyo>
> Content-Type: text/plain
>
> On Mon, 2008-06-23 at 06:52 +0100, Andy Farnell wrote:
>>
>> Yes that'right, hmm I guess I knew that but said it in a woolly way
>>
>> Amend that to
>>
>> [tabread~] - "play back at exactly" the original rate
>> [tabread4~] - "play back at close to the orginal rate"
>> [tabread4c~] - "play back with wider transposition"
>
>
> i don't see any justification to keep [tabread4~] in this list. cyrille
> once mentioned that his new class isn't computationally more expensive.
> if there is a difference between [tabread4~] and [tabread4c~], then it