1 // -----------------------------------------------------------------------------
2 //
3 //  Copyright (C) 2006-2018 Fons Adriaensen <fons@linuxaudio.org>
4 //
5 //  This program is free software; you can redistribute it and/or modify
6 //  it under the terms of the GNU General Public License as published by
7 //  the Free Software Foundation; either version 2 of the License, or
8 //  (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 //
18 // -----------------------------------------------------------------------------
19 
20 
21 #ifndef __CONVOL44_H
22 #define __CONVOL44_H
23 
24 
25 #include <fftw3.h>
26 
27 
28 enum { CONV_OPT_SSE = 1, CONV_OPT_3DN = 2 };
29 
30 
31 class Convdata
32 {
33 public:
34 
35     Convdata (unsigned int part, unsigned int size, unsigned int opts);
36     ~Convdata (void);
37 
38     void init (float *data, unsigned int size, unsigned int step, float gain);
get_refc(void)39     int get_refc (void) const { return _refc; }
inc_refc(void)40     int inc_refc (void) { return ++_refc; }
dec_refc(void)41     int dec_refc (void) { return --_refc; }
42 
43 private:
44 
45     static void swap (fftwf_complex *p, unsigned int n);
46 
47     friend class Convol44;
48 
49     int                _refc;      // reference counter
50     unsigned int       _part;      // partition size in frames
51     unsigned int       _opts;      // optimization flags
52     unsigned int       _npar;      // number of partitions
53     float              _norm;      // gain normalization
54     fftwf_complex    **_fftd;      // transformed partitions
55 };
56 
57 
58 
59 class Convol44
60 {
61 public:
62 
63     Convol44 (unsigned int part, unsigned int size, unsigned int frag, unsigned int opts);
64     ~Convol44 (void);
65 
wr_ptr(unsigned int i)66     float *wr_ptr (unsigned int i) const { return _wr_ptr [i]; }
rd_ptr(unsigned int i)67     float *rd_ptr (unsigned int i) const { return _rd_ptr [i]; }
68     int set_conv (unsigned int ip, unsigned int op, Convdata *C);
69     void reset (void);
70     void process (void);
71 
72 private:
73 
74     void fwdfft (unsigned int j);
75     void mulacc (unsigned int j, unsigned int k, fftwf_complex *q);
76     void invfft (unsigned int k, fftwf_complex *q);
77 
78     // configuration
79     //
80     unsigned int       _part;        // partition size in frames
81     unsigned int       _npar;        // number of partitions
82     unsigned int       _frag;        // IO fragment size
83     unsigned int       _opts;        // optimization flags
84     unsigned int       _mode;        // fragments per partition
85     Convdata          *_conv [4][4]; // array of Convdata pointers
86     fftwf_plan         _fwd_plan;    // fftw plans
87     fftwf_plan         _rev_plan;    //
88 
89     // data buffers
90     //
91     float             *_inp_buff;    // input buffer
92     float             *_op1_buff;    // alternating output buffers
93     float             *_op2_buff;    //
94     fftwf_complex    **_fwd_buff;    // circular array of transformed input parts
95     fftwf_complex     *_md1_buff;    // multiplied data accumulators
96     fftwf_complex     *_md2_buff;    //
97 
98     // interface state
99     //
100     float             *_wr_ptr [4];   // current input pointer
101     float             *_rd_ptr [4];   // current output pointer
102 
103     // processing state
104     //
105     unsigned int       _ifrag;
106     unsigned int       _ipart;
107 };
108 
109 
110 #endif
111 
112