Ardour  8.7-15-gadf511264b
dsp_filter.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016-2017 Robin Gareus <robin@gareus.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (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 along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 #ifndef _dsp_filter_h_
19 #define _dsp_filter_h_
20 
21 #include <atomic>
22 #include <cstdint>
23 #include <cstring>
24 #include <assert.h>
25 #include <glib.h>
26 #include <glibmm.h>
27 #include <fftw3.h>
28 
29 #include "pbd/malign.h"
30 
31 #include "ardour/buffer_set.h"
32 #include "ardour/chan_mapping.h"
34 #include "ardour/types.h"
35 
36 namespace ARDOUR { namespace DSP {
37 
55  class DspShm {
56  public:
57  DspShm (size_t s = 0)
58  : _data (0)
59  , _size (0)
60  {
61  assert (sizeof(float) == sizeof (int32_t));
62  assert (sizeof(float) == sizeof (int));
63  allocate (s);
64  }
65 
66  ~DspShm () {
68  }
69 
74  void allocate (size_t s) {
75  if (s == _size) { return; }
77  cache_aligned_malloc ((void**) &_data, sizeof (float) * s);
78  if (_data) { _size = s; }
79  }
80 
82  void clear () {
83  memset (_data, 0, sizeof(float) * _size);
84  }
85 
91  float* to_float (size_t off) {
92  if (off >= _size) { return 0; }
93  return &(((float*)_data)[off]);
94  }
95 
101  int32_t* to_int (size_t off) {
102  if (off >= _size) { return 0; }
103  return &(((int32_t*)_data)[off]);
104  }
105 
115  void atomic_set_int (size_t off, int32_t val) {
116  /* no read or write that precedes the write we are
117  about to do can be reordered past this fence.
118  */
119  std::atomic_thread_fence (std::memory_order_release);
120  ((int32_t*)_data)[off] = val;
121  }
122 
132  int32_t atomic_get_int (size_t off) {
133  /* no read that precedes the read we are
134  about to do can be reordered past this fence.
135  */
136  std::atomic_thread_fence (std::memory_order_acquire);
137  return (((int32_t*)_data)[off]);
138  }
139 
140  private:
141  void* _data;
142  size_t _size;
143  };
144 
146  void memset (float *data, const float val, const uint32_t n_samples);
154  void mmult (float *data, float *mult, const uint32_t n_samples);
162  void peaks (const float *data, float &min, float &max, uint32_t n_samples);
163 
169  float log_meter (float power);
175  float log_meter_coeff (float coeff);
176 
177  void process_map (BufferSet* bufs,
178  const ChanCount& n_out,
179  const ChanMapping& in_map,
180  const ChanMapping& out_map,
181  pframes_t nframes, samplecnt_t offset);
182 
185  public:
191  LowPass (double samplerate, float freq);
197  void proc (float *data, const uint32_t n_samples);
206  void ctrl (float *data, const float val, const uint32_t n_samples);
211  void set_cutoff (float freq);
213  void reset () { _z = 0.f; }
214  private:
215  float _rate;
216  float _z;
217  float _a;
218  };
219 
222  public:
223  enum Type {
236  MatchedPeaking
237  };
238 
243  Biquad (double samplerate);
244  Biquad (const Biquad &other);
245 
251  void run (float *data, const uint32_t n_samples);
259  void compute (Type t, double freq, double Q, double gain);
260 
262  void configure (double a1, double a2, double b0, double b1, double b2);
263 
264  /* copy coefficients from other instance, retain state */
265  void configure (Biquad const&);
266 
271  float dB_at_freq (float freq) const;
272 
274  void reset () { _z1 = _z2 = 0.0; }
275 
276  void coefficients (double& a1, double& a2, double& b0, double& b1, double& b2) const;
277  private:
278  void set_vicanek_poles (const double W0, const double Q, const double A = 1.0);
279  void calc_vicanek (const double W0, double& A0, double& A1, double& A2, double& phi0, double& phi1, double& phi2);
280 
281  double _rate;
282  float _z1, _z2;
283  double _a1, _a2;
284  double _b0, _b1, _b2;
285  };
286 
288  public:
289  FFTSpectrum (uint32_t window_size, double rate);
291 
299  void set_data_hann (float const * const data, const uint32_t n_samples, const uint32_t offset = 0);
300 
302  void execute ();
303 
309  float power_at_bin (const uint32_t bin, const float norm = 1.f) const;
310 
311  float freq_at_bin (const uint32_t bin) const {
312  return bin * _fft_freq_per_bin;
313  }
314 
315  private:
316  static Glib::Threads::Mutex fft_planner_lock;
317  float* hann_window;
318 
319  void init (uint32_t window_size, double rate);
320  void reset ();
321 
323  uint32_t _fft_data_size;
325 
326  float* _fft_data_in;
328  float* _fft_power;
329 
330  fftwf_plan _fftplan;
331  };
332 
334  public:
336 
337  enum Type {
341  };
342 
343  void run (float *data, const uint32_t n_samples);
344  void set_type (Type t);
345 
346  private:
347  uint32_t randi ();
348  float randf () { return (randi () / 1073741824.f) - 1.f; }
349  float grandf ();
350 
352  uint32_t _rseed;
353  /* pink-noise */
354  float _b0, _b1, _b2, _b3, _b4, _b5, _b6;
355  /* gaussian white */
356  bool _pass;
357  float _rn;
358 
359  };
360 
361 } } /* namespace */
362 #endif
void set_vicanek_poles(const double W0, const double Q, const double A=1.0)
void calc_vicanek(const double W0, double &A0, double &A1, double &A2, double &phi0, double &phi1, double &phi2)
Biquad(double samplerate)
void compute(Type t, double freq, double Q, double gain)
void run(float *data, const uint32_t n_samples)
void coefficients(double &a1, double &a2, double &b0, double &b1, double &b2) const
Biquad(const Biquad &other)
void configure(Biquad const &)
void configure(double a1, double a2, double b0, double b1, double b2)
float dB_at_freq(float freq) const
void allocate(size_t s)
Definition: dsp_filter.h:74
DspShm(size_t s=0)
Definition: dsp_filter.h:57
int32_t atomic_get_int(size_t off)
Definition: dsp_filter.h:132
void atomic_set_int(size_t off, int32_t val)
Definition: dsp_filter.h:115
float * to_float(size_t off)
Definition: dsp_filter.h:91
int32_t * to_int(size_t off)
Definition: dsp_filter.h:101
float power_at_bin(const uint32_t bin, const float norm=1.f) const
void set_data_hann(float const *const data, const uint32_t n_samples, const uint32_t offset=0)
FFTSpectrum(uint32_t window_size, double rate)
void init(uint32_t window_size, double rate)
static Glib::Threads::Mutex fft_planner_lock
Definition: dsp_filter.h:316
float freq_at_bin(const uint32_t bin) const
Definition: dsp_filter.h:311
void run(float *data, const uint32_t n_samples)
void set_cutoff(float freq)
LowPass(double samplerate, float freq)
void ctrl(float *data, const float val, const uint32_t n_samples)
void proc(float *data, const uint32_t n_samples)
#define LIBARDOUR_API
int cache_aligned_malloc(void **memptr, size_t size)
void cache_aligned_free(void *memptr)
float log_meter_coeff(float coeff)
void mmult(float *data, float *mult, const uint32_t n_samples)
float log_meter(float power)
void process_map(BufferSet *bufs, const ChanCount &n_out, const ChanMapping &in_map, const ChanMapping &out_map, pframes_t nframes, samplecnt_t offset)
void peaks(const float *data, float &min, float &max, uint32_t n_samples)
void memset(float *data, const float val, const uint32_t n_samples)
PBD::PropertyDescriptor< gain_t > gain
uint32_t pframes_t
Temporal::samplecnt_t samplecnt_t