1 // ----------------------------------------------------------------------------
3 // Copyright (C) 2006-2018 Fons Adriaensen <fons@linuxaudio.org>
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 3 of the License, or
8 // (at your option) any later version.
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.
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/>.
18 // ----------------------------------------------------------------------------
21 #ifndef _ZITA_CONVOLVER_H
22 #define _ZITA_CONVOLVER_H
29 #include "zita-convolver/zconvolver_visibility.h"
31 namespace ArdourZita {
34 #ifdef ZCSEMA_IS_IMPLEMENTED
35 #undef ZCSEMA_IS_IMPLEMENTED
39 #if defined(__linux__) || defined(__GNU__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
41 #include <semaphore.h>
43 class LIBZCONVOLVER_API ZCsema
47 ZCsema (void) { init (0, 0); }
48 ~ZCsema (void) { sem_destroy (&_sema); }
50 ZCsema (const ZCsema&); // disabled
51 ZCsema& operator= (const ZCsema&); // disabled
53 int init (int s, int v) { return sem_init (&_sema, s, v); }
54 int post (void) { return sem_post (&_sema); }
55 int wait (void) { return sem_wait (&_sema); }
56 int trywait (void) { return sem_trywait (&_sema); }
63 #define ZCSEMA_IS_IMPLEMENTED
69 // NOTE: ***** I DO NOT REPEAT NOT PROVIDE SUPPORT FOR OSX *****
71 // The following code partially emulates the POSIX sem_t for which
72 // OSX has only a crippled implementation. It may or may not compile,
73 // and if it compiles it may or may not work correctly. Blame APPLE
74 // for not following POSIX standards.
76 class LIBZCONVOLVER_API ZCsema
80 ZCsema (void) : _count (0)
87 pthread_mutex_destroy (&_mutex);
88 pthread_cond_destroy (&_cond);
91 ZCsema (const ZCsema&); // disabled
92 ZCsema& operator= (const ZCsema&); // disabled
94 int init (int s, int v)
97 return pthread_mutex_init (&_mutex, 0) || pthread_cond_init (&_cond, 0);
102 pthread_mutex_lock (&_mutex);
104 if (_count == 1) pthread_cond_signal (&_cond);
105 pthread_mutex_unlock (&_mutex);
111 pthread_mutex_lock (&_mutex);
112 while (_count < 1) pthread_cond_wait (&_cond, &_mutex);
114 pthread_mutex_unlock (&_mutex);
120 if (pthread_mutex_trylock (&_mutex)) return -1;
123 pthread_mutex_unlock (&_mutex);
127 pthread_mutex_unlock (&_mutex);
134 pthread_mutex_t _mutex;
135 pthread_cond_t _cond;
138 #define ZCSEMA_IS_IMPLEMENTED
142 #ifndef ZCSEMA_IS_IMPLEMENTED
143 #error "The ZCsema class is not implemented."
147 // ----------------------------------------------------------------------------
150 class LIBZCONVOLVER_API Inpnode
154 friend class Convlevel;
156 Inpnode (uint16_t inp);
158 void alloc_ffta (uint16_t npar, int32_t size);
159 void free_ffta (void);
162 fftwf_complex **_ffta;
168 class LIBZCONVOLVER_API Macnode
172 friend class Convlevel;
174 Macnode (Inpnode *inpn);
176 void alloc_fftb (uint16_t npar);
177 void free_fftb (void);
182 fftwf_complex **_fftb;
187 class LIBZCONVOLVER_API Outnode
191 friend class Convlevel;
193 Outnode (uint16_t out, int32_t size);
203 class LIBZCONVOLVER_API Converror
214 Converror (int error) : _error (error) {}
222 class LIBZCONVOLVER_API Convlevel
226 friend class Convproc;
230 OPT_FFTW_MEASURE = 1,
245 void configure (int prio,
251 void impdata_write (uint32_t inp,
259 void impdata_clear (uint32_t inp,
262 void impdata_link (uint32_t inp1,
267 void reset (uint32_t inpsize,
272 void start (int absprio, int policy);
274 void process (bool sync);
276 int readout (bool sync, uint32_t skipcnt);
282 void fftswap (fftwf_complex *p);
284 void print (FILE *F);
286 static void *static_main (void *arg);
290 Macnode *findmacnode (uint32_t inp, uint32_t out, bool create);
293 volatile uint32_t _stat; // current processing state
294 int _prio; // relative priority
295 uint32_t _offs; // offset from start of impulse response
296 uint32_t _npar; // number of partitions
297 uint32_t _parsize; // partition and outbut buffer size
298 uint32_t _outsize; // step size for output buffer
299 uint32_t _outoffs; // offset into output buffer
300 uint32_t _inpsize; // size of shared input buffer
301 uint32_t _inpoffs; // offset into input buffer
302 uint32_t _options; // various options
303 uint32_t _ptind; // rotating partition index
304 uint32_t _opind; // rotating output buffer index
305 int _bits; // bit identifiying this level
306 int _wait; // number of unfinished cycles
307 pthread_t _pthr; // posix thread executing this level
308 ZCsema _trig; // sema used to trigger a cycle
309 ZCsema _done; // sema used to wait for a cycle
310 Inpnode *_inp_list; // linked list of active inputs
311 Outnode *_out_list; // linked list of active outputs
312 fftwf_plan _plan_r2c; // FFTW plan, forward FFT
313 fftwf_plan _plan_c2r; // FFTW plan, inverse FFT
314 float *_time_data; // workspace
315 float *_prep_data; // workspace
316 fftwf_complex *_freq_data; // workspace
317 float **_inpbuff; // array of shared input buffers
318 float **_outbuff; // array of shared output buffers
322 // ----------------------------------------------------------------------------
325 class LIBZCONVOLVER_API Convproc
342 FL_LATE = 0x0000FFFF,
348 OPT_FFTW_MEASURE = Convlevel::OPT_FFTW_MEASURE,
349 OPT_VECTOR_MODE = Convlevel::OPT_VECTOR_MODE,
350 OPT_LATE_CONTIN = Convlevel::OPT_LATE_CONTIN
365 uint32_t state (void) const
370 float *inpdata (uint32_t inp) const
372 return _inpbuff [inp] + _inpoffs;
375 float *outdata (uint32_t out) const
377 return _outbuff [out] + _outoffs;
380 int configure (uint32_t ninp,
388 int impdata_create (uint32_t inp,
395 int impdata_clear (uint32_t inp,
398 int impdata_update (uint32_t inp,
405 int impdata_link (uint32_t inp1,
410 // Deprecated, use impdata_link() instead.
411 int impdata_copy (uint32_t inp1,
416 return impdata_link (inp1, out1, inp2, out2);
419 void set_options (uint32_t options);
421 void set_skipcnt (uint32_t skipcnt);
425 int start_process (int abspri, int policy);
427 int process (bool sync = false);
429 int stop_process (void);
431 bool check_stop (void);
435 void print (FILE *F = stdout);
439 uint32_t _state; // current state
440 float *_inpbuff [MAXINP]; // input buffers
441 float *_outbuff [MAXOUT]; // output buffers
442 uint32_t _inpoffs; // current offset in input buffers
443 uint32_t _outoffs; // current offset in output buffers
444 uint32_t _options; // option bits
445 uint32_t _skipcnt; // number of frames to skip
446 uint32_t _ninp; // number of inputs
447 uint32_t _nout; // number of outputs
448 uint32_t _quantum; // processing block size
449 uint32_t _minpart; // smallest partition size
450 uint32_t _maxpart; // largest allowed partition size
451 uint32_t _nlevels; // number of partition sizes
452 uint32_t _inpsize; // size of input buffers
453 uint32_t _latecnt; // count of cycles ending too late
454 Convlevel *_convlev [MAXLEV]; // array of processors
457 static float _mac_cost;
458 static float _fft_cost;
462 // ----------------------------------------------------------------------------
464 } /* end namespace */