Consistent C++ & Lua Namespace/Class names + documentation.
[ardour.git] / libs / ardour / ardour / dsp_filter.h
1 /*
2  * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  */
19 #ifndef _dsp_filter_h_
20 #define _dsp_filter_h_
21
22 #include <stdint.h>
23 #include <string.h>
24 #include <assert.h>
25 #include <glib.h>
26 #include "ardour/libardour_visibility.h"
27
28 namespace ARDOUR { namespace DSP {
29
30         /** C Shared Memory
31          *
32          * A convenience class representing a C array or float[] or int32_t[]
33          * data values. This is useful for lua scripts to perform DSP operations
34          * directly using C, C++.
35          * Access to this memory area is always 4 byte aligned: float, int.
36          *
37          * This memory area can also be shared between different instances.
38          *
39          * Since memory allocation is not realtime safe it should be
40          * allocated during dsp_init() or dsp_configure().
41          *
42          * The memory is free()ed automatically when the lua instance is
43          * destroyed.
44          */
45         class DspShm {
46                 public:
47                         DspShm ()
48                                 : _data (0)
49                                 , _size (0)
50                         {
51                                 assert (sizeof(float) == sizeof (int32_t));
52                                 assert (sizeof(float) == sizeof (int));
53                         }
54
55                         ~DspShm () {
56                                 free (_data);
57                         }
58
59                         /** [re] allocate memory in host's memory space
60                          *
61                          * @param s size, total number of float or integer elements to store.
62                          */
63                         void allocate (size_t s) {
64                                 _data = realloc (_data, sizeof(float) * s);
65                                 if (_data) { _size = s; }
66                         }
67
68                         /** clear memory (set to zero) */
69                         void clear () {
70                                 memset (_data, 0, sizeof(float) * _size);
71                         }
72
73                         /** access memory as float array
74                          *
75                          * @param off offset in shared memory region
76                          * @returns float[]
77                          */
78                         float* to_float (size_t off) {
79                                 if (off >= _size) { return 0; }
80                                 return &(((float*)_data)[off]);
81                         }
82
83                         /** access memory as integer array
84                          *
85                          * @param off offset in shared memory region
86                          * @returns int_32_t[]
87                          */
88                         int32_t* to_int (size_t off) {
89                                 if (off >= _size) { return 0; }
90                                 return &(((int32_t*)_data)[off]);
91                         }
92
93                         /** atomically set integer at offset
94                          *
95                          * This involves a memory barrier. This call
96                          * is intended for buffers which are
97                          * shared with another instance.
98                          *
99                          * @param off offset in shared memory region
100                          * @param val value to set
101                          */
102                         void atomic_set_int (size_t off, int32_t val) {
103                                 g_atomic_int_set (&(((int32_t*)_data)[off]), val);
104                         }
105
106                         /** atomically read integer at offset
107                          *
108                          * This involves a memory barrier. This call
109                          * is intended for buffers which are
110                          * shared with another instance.
111                          *
112                          * @param off offset in shared memory region
113                          * @returns value at offset
114                          */
115                         int32_t atomic_get_int (size_t off) {
116                                 return g_atomic_int_get (&(((int32_t*)_data)[off]));
117                         }
118
119                 private:
120                         void* _data;
121                         size_t _size;
122         };
123
124         void memset (float *data, const float val, const uint32_t n_samples);
125         void mmult (float *data, float *mult, const uint32_t n_samples);
126         void peaks (float *data, float &min, float &max, uint32_t n_samples);
127
128         float log_meter (float power);
129         float log_meter_coeff (float coeff);
130
131         /** 1st order Low Pass filter */
132         class LIBARDOUR_API LowPass {
133                 public:
134                         /** instantiate a LPF
135                          *
136                          * @param samplerate samplerate
137                          * @param freq cut-off frequency
138                          */
139                         LowPass (double samplerate, float freq);
140                         /** process audio data
141                          *
142                          * @param data pointer to audio-data
143                          * @param n_samples number of samples to process
144                          */
145                         void proc (float *data, const uint32_t n_samples);
146                         /** filter control data
147                          *
148                          * This is useful for parameter smoothing.
149                          *
150                          * @param data pointer to control-data array
151                          * @param val target value
152                          * @param array length
153                          */
154                         void ctrl (float *data, const float val, const uint32_t n_samples);
155                         /** update filter cut-off frequency
156                          *
157                          * @param freq cut-off frequency
158                          */
159                         void set_cutoff (float freq);
160                         /** reset filter state */
161                         void reset () { _z =  0.f; }
162                 private:
163                         float _rate;
164                         float _z;
165                         float _a;
166         };
167
168         /** Biquad Filter */
169         class LIBARDOUR_API BiQuad {
170                 public:
171                         enum Type {
172                                 LowPass,
173                                 HighPass,
174                                 BandPassSkirt,
175                                 BandPass0dB,
176                                 Notch,
177                                 AllPass,
178                                 Peaking,
179                                 LowShelf,
180                                 HighShelf
181                         };
182
183                         /** Instantiate Biquad Filter
184                          *
185                          * @param samplerate Samplerate
186                          */
187                         BiQuad (double samplerate);
188                         BiQuad (const BiQuad &other);
189
190                         /** process audio data
191                          *
192                          * @param data pointer to audio-data
193                          * @param n_samples number of samples to process
194                          */
195                         void run (float *data, const uint32_t n_samples);
196                         /** setup filter, compute coefficients
197                          *
198                          * @param t filter type
199                          * @param freq filter frequency
200                          * @param Q filter quality
201                          * @param gain filter gain
202                          */
203                         void compute (Type t, double freq, double Q, double gain);
204                         /** reset filter state */
205                         void reset () { _z1 = _z2 = 0.0; }
206                 private:
207                         double _rate;
208                         float  _z1, _z2;
209                         double _a1, _a2;
210                         double _b0, _b1, _b2;
211         };
212
213 } } /* namespace */
214 #endif