Hi Oleg,

I don't yet know what benefits are offered by ZDFs that are not
already covered by the existing filter forms in filters.lib.  Search
for "Parametric Equalizers (Shelf, Peaking)" in that file, and
lowpass, highpass, allpass, and so on.  There's no bell filter,
however, because I don't know what that is.  The classic state
variable filter cases (lowpass, bandpass, highpass, notch) are
immediately obtained using tf2s, as derived in
https://ccrma.stanford.edu/~jos/svf/.

So, except for bell, which I'm happy to add if I can get some doc on
what it's for, all of these functions are available already.  Your zdf
forms presumably have different numerical properties in the LSBs, and
they might even result in more or less efficient Faust code.  Please
let us know if you can make a case for them relative to the existing
implementations.

By the way, I don't know why they are called "zero-delay filters".  I
just see second-order digital filters, but implemented in what looks
like a state-variable-inspired topology.  I suppose I need to read the
derivation of ZDFs, which I haven't yet, but I will if they do
something the other second-order forms can't do.

Note that filters.lib does have alternate forms available already
(ladder, lattice, etc.), and there is a literature explaining when and
how they are better and under what conditions.  I try to give my
favorite literature pointers in the comments in the Faust source.  Is
there such a literature for ZDFs?   If so, under what conditions do
they win over all the others?

Thanks,
- Julius


On Wed, Aug 22, 2018 at 8:44 PM Oleg Nesterov <o...@redhat.com> wrote:
>
> On 08/22, Julius Smith wrote:
> >
> > Hey, thanks for posting.  I made a faust2octave test program
> > (attached).  Everything looks good to me, assuming I guessed all the
> > names right.
>
> Great, thanks.
>
> do you think it can live in filters.lib? If yes, then I think
> "svf = environment" makes sense, so that you can use it like
>
>         process = fi.svf.lp(f,q);
>
> See the code below. Note that this version differs a little bit, it uses
> the second version described in that paper (see "algorithm using v1 to
> compute v2").
>
> iow
>
>         v2 = ic2eq + g*v1;                      (2)
>
> instead of
>
>         v2 = ic2eq + a2*ic1eq + a3*v3;          (1)
>
> I think it makes more sense for faust because it is simpler, and because
> quite possibly faust will turn (2) into (1) after aterm/mterm normalization
> anyway.
>
> I even verified that "all pass" generates the same code with this change.
>
> Oleg.
>
> -------------------------------------------------------------------------------
> svf = environment {
>         svf(T,F,Q,G) = tick ~ (_,_) : !,!,_,_,_ : si.dot(3, mix)
>         with {
>                 a1 = 1/(1 + g*(g + k));
>                 a2 = g*a1;
>
>                 tick(ic1eq, ic2eq, v0) =
>                         2*v1 - ic1eq,
>                         2*v2 - ic2eq,
>                         v0, v1, v2
>                 with {
>                         v1 = a1*ic1eq + a2*(v0 - ic2eq);
>                         v2 = ic2eq + g*v1;
>                 };
>
>                 A = pow(10.0, G / 40.0);
>
>                 g = tan(F * ma.PI / ma.SR) : case {
>                         (7) => /(sqrt(A));
>                         (8) => *(sqrt(A));
>                         (t) => _;
>                 } (T);
>
>                 k = case {
>                         (6) => 1/(Q*A);
>                         (t) => 1/Q;
>                 } (T);
>
>                 mix = case {
>                         (0) => 0, 0, 1;
>                         (1) => 0, 1, 0;
>                         (2) => 1, -k, -1;
>                         (3) => 1, -k, 0;
>                         (4) => 1, -k, -2;
>                         (5) => 1, -2*k, 0;
>                         (6) => 1, k*(A*A - 1), 0;
>                         (7) => 1, k*(A-1), A*A - 1;
>                         (8) => A*A, k*(1-A)*A, 1-A*A;
>                 } (T);
>         };
>
>         lp(f,q)         = svf(0, f,q,0);
>         bp(f,q)         = svf(1, f,q,0);
>         hp(f,q)         = svf(2, f,q,0);
>         notch(f,q)      = svf(3, f,q,0);
>         peak(f,q)       = svf(4, f,q,0);
>         ap(f,q)         = svf(5, f,q,0);
>         bell(f,q,g)     = svf(6, f,q,g);
>         ls(f,q,g)       = svf(7, f,q,g);
>         hs(f,q,g)       = svf(8, f,q,g);
> };
>
>


-- 

Julius O. Smith III <j...@ccrma.stanford.edu>
Professor of Music and, by courtesy, Electrical Engineering
CCRMA, Stanford University
http://ccrma.stanford.edu/~jos/

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Faudiostream-users mailing list
Faudiostream-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/faudiostream-users

Reply via email to