// ----------------------------------------------------------------------------
//
//  Copyright (C) 2015-2018 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 __BINCONV_H
#define __BINCONV_H


#include <fftw3.h>


class Fdata
{
    friend class Binconv;

private:

    Fdata (int npar, int nbin);
    ~Fdata (void);
    void clear (void);

    int              _npar;  // Number of allocated partitions   
    int              _nact;  // Number of active partitions
    int              _nbin;  // Size of frequency domain array.
    fftwf_complex  **_data;  // Frequency domain arrays.  
};


class Binconv
{
public:

    enum { MAXDEGR = 8, MAXINP = 81, MAXSIZE = 2048 };
    
    Binconv (int degree, int size, int frag);
    ~Binconv (void);

    void reset (void);
    void process (float *inp [], float *out [2]);
    int  setimp (int inp, float gain, const float *data, int size, int step = 1);
    
private:

    void convadd (float *inp, int ind, fftwf_complex *F);

    int              _degr;      // AMB degree.
    int              _ninp;      // Number of inputs.
    int              _size;      // Maximum filter size.
    int              _frag;      // Partition size
    int              _lfft;      // FFT size
    int              _nbin;      // FFT bins
    int              _npar;      // Number of partitions
    int              _ipar;      // Current partition index.
    float           *_tfilt;     // Workspace
    float           *_tdomS;     // Workspace
    float           *_tdomD;     // Workspace
    fftwf_complex   *_faccS;     // Frequency domain accumulator
    fftwf_complex   *_faccD;     // Frequency domain accumulator
    float           *_saveS;     // Overlap/save buffer
    float           *_saveD;     // Overlap/save buffer
    fftwf_plan       _plan_r2c;  // FFT plans
    fftwf_plan       _plan_c2r;  //
    Fdata           *_fdataA [MAXINP]; // Frequency domain data for filters.
    Fdata           *_fdataB [MAXINP]; // Frequency domain data for inputs.
};    


#endif


