//  ------------------------------------------------------------------------
//
//  Copyright (C) 2009-2017 Fons Adriaensen <fons@linuxaudio.org>
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//  ------------------------------------------------------------------------


#ifndef __XOVER2_H
#define __XOVER2_H


// -------------------------------------------------------------------
//
// Second order Linkwitz-Riley crossover. Outputs are exaclty in phase
// and add up to a first order allpass.
// The 'f' parameter is the crossover frequency divided by the sample
// rate.
//
// -------------------------------------------------------------------


class LR2conf
{
public:

    LR2conf (void) : _c0 (0), _c1 (0) {}
    ~LR2conf (void) {}

    void init (float f);

private:

    friend class LR2filt;

    float _c0, _c1;
};


class LR2filt
{
public:

    LR2filt (void) { reset (); }
    ~LR2filt (void) {}

    void reset (void) { _z0 = _z1 = _z2 = 0; }
    void process (const LR2conf *C, int k,
		  const float *in, float *lp, float *hp);

private:

    float _z0, _z1, _z2;
};


//--------------------------------------------------------------- 
//
//  First order allpass, same phase response as LR2.
//
//---------------------------------------------------------------

class AP1conf
{
public:

    AP1conf (void) : _c0 (0) {}
    ~AP1conf (void) {}

    void init (float f);

private:

    friend class AP1filt;

    float _c0; 
};


class AP1filt
{
public:

    AP1filt (void) { reset (); }
    ~AP1filt (void) {}

    void reset (void) { _z0 = 0; }
    void process (const AP1conf *C, int k, float *p);

private:

    float _z0;
};


#endif

