Re: spline wavetable generator

From: John Lazzaro (lazzaro@CS.Berkeley.EDU)
Date: Tue Oct 17 2000 - 14:35:49 EDT


> I'm not sure how the spline wavetable generator should be implemented

Here's a quick description of how sfront's spline generator is
implemented, which may be helpful. Note that sfront actually
implements all the generators in three places now:

-- Tables with constant values get computed in wtconst.c -- in
looking at SAOL source code, most table initializations are all
constant, and so most of the time this gets used.

-- Tables with variables in the initializations get custom code
generated for them, in the file wtparse.c

-- Tables coming in "dynamically" via SASL SA_access_units get
computed with the sfront/src/lib/csrc/tgen.c library. Right now,
this is only used for the -cin fstr option, which takes the SAOL
StructuredAudioSpecificCongfig block and generates C code for it,
but reads all SA_access_units out of the .mp4 dynamically.

In the sfront 0.67 distribution, see line 1481 of wtconst.c,
line 1972 of wtparse.c, and line 723 of src/lib/csrc/tgen.c
for the three spline implementations.

In a nutshell, here's the algorithm all three are implementing:

To compute the spline between two sets of triples (oldx, oldy, oldk)
and (x, y, k), we first compute the variables Q,R,S

            Q = 1.0F/(oldx - x);
            R = Q*(oldx*oldx - x*x) - 2.0F*oldx;
            R =1.0F/R;
            S = Q*(oldx*oldx - x*x) - 2.0F*x;
            S =1.0F/S;

Be sure to check for R and S being too close to zero before doing
the divides, it indicates a bad choice of spline coefficients by
the user and should be flagged as an error.

Now compute a,b,c,d:

            a = Q*(oldx*oldx*oldx-x*x*x)*(R-S);
            a += -3.0F*(R*oldx*oldx - S*x*x);
            a =1.0F/a;
            a *= Q*(oldy-y)*(R-S) - R*oldk + S*k;
            b = Q*(oldk-k)*0.5F;
            b += - 1.5F*a*Q*(oldx*oldx - x*x);
            c = oldk - 3.0F*a*oldx*oldx -2.0F*b*oldx;
            d = oldy-a*oldx*oldx*oldx-b*oldx*oldx-c*oldx;

Finally, compute y(x) for the values between oldx and x using:

y(x) = oldx*oldx*oldx*a + oldx*oldx*b + oldx*c + d

Finally some caveats:

-- No guarantees stated or implied on the accuracy of the equations,
but the curves they make seem to look OK

-- See the source code for details on edge conditions, error checks,
ect.

Hope this helps!

                                                        --john lazzaro

-------------------------------------------------------------------------
John Lazzaro -- Research Specialist -- CS Division -- EECS -- UC Berkeley
lazzaro [at] cs [dot] berkeley [dot] edu www.cs.berkeley.edu/~lazzaro
-------------------------------------------------------------------------



This archive was generated by hypermail 2b29 : Mon Jan 28 2002 - 12:03:59 EST