[arch-commits] Commit in zam-plugins/trunk (3 files)

David Runge dvzrv at archlinux.org
Mon Jul 23 18:45:39 UTC 2018


    Date: Monday, July 23, 2018 @ 18:45:38
  Author: dvzrv
Revision: 363204

upgpkg: zam-plugins 3.10-4

Rebuilding against zita-convolver 4.0.0 (with upstream patches).

Added:
  zam-plugins/trunk/system-zita-convolver.patch
  zam-plugins/trunk/zita-convolver4.patch
Modified:
  zam-plugins/trunk/PKGBUILD

-----------------------------+
 PKGBUILD                    |   16 
 system-zita-convolver.patch |  155 +++
 zita-convolver4.patch       | 1994 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 2159 insertions(+), 6 deletions(-)

Modified: PKGBUILD
===================================================================
--- PKGBUILD	2018-07-23 18:15:01 UTC (rev 363203)
+++ PKGBUILD	2018-07-23 18:45:38 UTC (rev 363204)
@@ -10,9 +10,13 @@
 depends=('jack' 'libglvnd' 'liblo' 'zita-convolver')
 makedepends=('git' 'ladspa' 'libx11' 'libgl' 'lv2')
 source=("$pkgname-$pkgver::git+https://github.com/zamaudio/${pkgname}.git#tag=${pkgver}"
-        "git+https://github.com/distrho/dpf.git")
-md5sums=('SKIP'
-         'SKIP')
+        "git+https://github.com/distrho/dpf.git"
+        'zita-convolver4.patch'
+        'system-zita-convolver.patch')
+sha512sums=('SKIP'
+            'SKIP'
+            '21bba1704ddf912146e3a6ce58752236f40695f592cffd50814cbc8083e8d97d8ed4791362990883a59f98b538bde32c320059f5db58061dbbcfddad9003ee02'
+            'bb3f3f2f0c5ce0c80755016566ffc2ea1436646ab69cd6f8cd82ea1b221d67490599264964edca062a9e3c19861f99d7c8f12cf51829e0432a9658c8adcf63f3')
 
 prepare() {
   cd "$pkgname-$pkgver"
@@ -19,13 +23,13 @@
   git submodule init
   git config submodule.dpf.url "${srcdir}/dpf"
   git submodule update
-  # use system zita-convolver
-  sed -e 's|\"../../lib/zita-convolver-3.1.0/zita-convolver.h\"|<zita-convolver.h>|' \
-    -i plugins/Zam{Verb,HeadX2}/convolution.{cpp,hpp}
+  patch -Np1 -i ../zita-convolver4.patch
+  patch -Np1 -i ../system-zita-convolver.patch
 }
 
 build() {
   cd "$pkgname-$pkgver"
+  export USE_SYSTEM_LIBS=1
   make
 }
 

Added: system-zita-convolver.patch
===================================================================
--- system-zita-convolver.patch	                        (rev 0)
+++ system-zita-convolver.patch	2018-07-23 18:45:38 UTC (rev 363204)
@@ -0,0 +1,155 @@
+From fbdbf082fef6c5e9cd7796c8e6726c8e98c7c040 Mon Sep 17 00:00:00 2001
+From: Guido Aulisi <guido.aulisi at gmail.com>
+Date: Wed, 28 Feb 2018 12:28:26 +0100
+Subject: [PATCH 3/3] Allow using system provided zita convolver library
+
+v.2: Rebase onto newer zita-convolver
+---
+ Makefile.mk                       |  9 +++++++++
+ plugins/ZamHeadX2/Makefile        | 12 ++++++++++--
+ plugins/ZamHeadX2/convolution.cpp |  1 -
+ plugins/ZamHeadX2/convolution.hpp |  4 ++++
+ plugins/ZamVerb/Makefile          | 12 ++++++++++--
+ plugins/ZamVerb/convolution.cpp   |  1 -
+ plugins/ZamVerb/convolution.hpp   |  4 ++++
+ 7 files changed, 37 insertions(+), 6 deletions(-)
+
+diff --git a/Makefile.mk b/Makefile.mk
+index 7588326..b53ca4e 100644
+--- a/Makefile.mk
++++ b/Makefile.mk
+@@ -85,6 +85,15 @@ ifeq ($(LINUX),true)
+ HAVE_DGL   = $(shell pkg-config --exists gl x11 && echo true)
+ HAVE_JACK  = $(shell pkg-config --exists jack   && echo true)
+ HAVE_LIBLO = $(shell pkg-config --exists liblo  && echo true)
++
++# Allow to use system provided libs
++ifeq ($(USE_SYSTEM_LIBS),1)
++HAVE_ZITA_CONVOLVER = true
++ZITA_CONVOLVER_LIBS = -lzita-convolver
++BASE_FLAGS += -I/usr/include
++export HAVE_ZITA_CONVOLVER
++endif
++
+ endif
+ 
+ ifeq ($(MACOS),true)
+diff --git a/plugins/ZamHeadX2/Makefile b/plugins/ZamHeadX2/Makefile
+index 8500534..28e6931 100644
+--- a/plugins/ZamHeadX2/Makefile
++++ b/plugins/ZamHeadX2/Makefile
+@@ -12,8 +12,11 @@ NAME = ZamHeadX2
+ # --------------------------------------------------------------
+ # Files to build
+ 
+-OBJS_DSP = \
+-	../../lib/zita-convolver-4.0.0/zita-convolver.cpp.o \
++ifneq ($(HAVE_ZITA_CONVOLVER),true)
++OBJS_DSP = ../../lib/zita-convolver-4.0.0/zita-convolver.cpp.o
++endif
++
++OBJS_DSP += \
+ 	convolution.cpp.o \
+ 	ZamHeadX2Plugin.cpp.o
+ 
+@@ -38,6 +41,11 @@ else
+ TARGETS += lv2_dsp
+ endif
+ 
++ifeq ($(HAVE_ZITA_CONVOLVER),true)
++BASE_FLAGS += -DHAVE_ZITA_CONVOLVER
++LINK_FLAGS += $(ZITA_CONVOLVER_LIBS)
++endif
++
+ TARGETS += vst
+ 
+ all: $(TARGETS)
+diff --git a/plugins/ZamHeadX2/convolution.cpp b/plugins/ZamHeadX2/convolution.cpp
+index 0026ba2..8c42acc 100644
+--- a/plugins/ZamHeadX2/convolution.cpp
++++ b/plugins/ZamHeadX2/convolution.cpp
+@@ -42,7 +42,6 @@
+ #include <pthread.h>
+ #include <assert.h>
+ 
+-#include "../../lib/zita-convolver-4.0.0/zita-convolver.h"
+ #include <samplerate.h>
+ #include "convolution.hpp"
+ 
+diff --git a/plugins/ZamHeadX2/convolution.hpp b/plugins/ZamHeadX2/convolution.hpp
+index 80be8e6..8cdcd71 100644
+--- a/plugins/ZamHeadX2/convolution.hpp
++++ b/plugins/ZamHeadX2/convolution.hpp
+@@ -19,7 +19,11 @@
+ #ifndef CONVOLUTION_H_
+ #define CONVOLUTION_H_
+ 
++#ifdef HAVE_ZITA_CONVOLVER
++#include <zita-convolver.h>
++#else
+ #include "../../lib/zita-convolver-4.0.0/zita-convolver.h"
++#endif
+ 
+ #define MAX_CHANNEL_MAPS (4)
+ #define VERBOSE_printf(x, ...)
+diff --git a/plugins/ZamVerb/Makefile b/plugins/ZamVerb/Makefile
+index eacc080..a08e334 100644
+--- a/plugins/ZamVerb/Makefile
++++ b/plugins/ZamVerb/Makefile
+@@ -15,8 +15,11 @@ NAME = ZamVerb
+ OBJS_DSP = \
+ 	ZamVerbPlugin.cpp.o \
+ 	ZamVerbImpulses.cpp.o \
+-	convolution.cpp.o \
+-	../../lib/zita-convolver-4.0.0/zita-convolver.cpp.o
++	convolution.cpp.o
++
++ifneq ($(HAVE_ZITA_CONVOLVER),true)
++OBJS_DSP += ../../lib/zita-convolver-4.0.0/zita-convolver.cpp.o
++endif
+ 
+ OBJS_UI  = \
+ 	ZamVerbArtwork.cpp.o \
+@@ -39,6 +42,11 @@ else
+ TARGETS += lv2_dsp
+ endif
+ 
++ifeq ($(HAVE_ZITA_CONVOLVER),true)
++BASE_FLAGS += -DHAVE_ZITA_CONVOLVER
++LINK_FLAGS += $(ZITA_CONVOLVER_LIBS)
++endif
++
+ TARGETS += vst
+ 
+ all: $(TARGETS)
+diff --git a/plugins/ZamVerb/convolution.cpp b/plugins/ZamVerb/convolution.cpp
+index 27374e0..8357037 100644
+--- a/plugins/ZamVerb/convolution.cpp
++++ b/plugins/ZamVerb/convolution.cpp
+@@ -42,7 +42,6 @@
+ #include <pthread.h>
+ #include <assert.h>
+ 
+-#include "../../lib/zita-convolver-4.0.0/zita-convolver.h"
+ #include <samplerate.h>
+ #include "convolution.hpp"
+ #include "ZamVerbImpulses.hpp"
+diff --git a/plugins/ZamVerb/convolution.hpp b/plugins/ZamVerb/convolution.hpp
+index 1c89971..cfb3755 100644
+--- a/plugins/ZamVerb/convolution.hpp
++++ b/plugins/ZamVerb/convolution.hpp
+@@ -19,7 +19,11 @@
+ #ifndef CONVOLUTION_H_
+ #define CONVOLUTION_H_
+ 
++#ifdef HAVE_ZITA_CONVOLVER
++#include <zita-convolver.h>
++#else
+ #include "../../lib/zita-convolver-4.0.0/zita-convolver.h"
++#endif
+ 
+ #define MAX_CHANNEL_MAPS (4)
+ #define VERBOSE_printf(x, ...)
+-- 
+2.18.0
+

Added: zita-convolver4.patch
===================================================================
--- zita-convolver4.patch	                        (rev 0)
+++ zita-convolver4.patch	2018-07-23 18:45:38 UTC (rev 363204)
@@ -0,0 +1,1994 @@
+From 71d221b7560c53d48bacf77a1624c467d816b413 Mon Sep 17 00:00:00 2001
+From: Damien Zammit <damien at zamaudio.com>
+Date: Sat, 9 Jun 2018 17:27:56 +1000
+Subject: [PATCH 1/3] lib: Update to zita-convolver 4.0.0
+
+---
+ Makefile                                      |   2 +-
+ lib/zita-convolver-3.1.0/zita-convolver.h     | 471 -----------------
+ .../zcsema-osx-win-compat.h                   |  40 ++
+ .../zita-convolver.cpp                        | 465 +++++++++--------
+ lib/zita-convolver-4.0.0/zita-convolver.h     | 475 ++++++++++++++++++
+ plugins/ZamHeadX2/Makefile                    |   2 +-
+ plugins/ZamHeadX2/convolution.cpp             |  10 +-
+ plugins/ZamHeadX2/convolution.hpp             |   2 +-
+ plugins/ZamVerb/Makefile                      |   2 +-
+ plugins/ZamVerb/convolution.cpp               |  10 +-
+ plugins/ZamVerb/convolution.hpp               |   2 +-
+ 11 files changed, 783 insertions(+), 698 deletions(-)
+ delete mode 100644 lib/zita-convolver-3.1.0/zita-convolver.h
+ create mode 100644 lib/zita-convolver-4.0.0/zcsema-osx-win-compat.h
+ rename lib/{zita-convolver-3.1.0 => zita-convolver-4.0.0}/zita-convolver.cpp (68%)
+ create mode 100644 lib/zita-convolver-4.0.0/zita-convolver.h
+
+diff --git a/Makefile b/Makefile
+index fc8991b..3220651 100644
+--- a/Makefile
++++ b/Makefile
+@@ -68,7 +68,7 @@ ifeq ($(HAVE_DGL),true)
+ 	$(MAKE) clean -C dpf/dgl
+ endif
+ 	$(MAKE) clean -C dpf/utils/lv2-ttl-generator
+-	rm -f lib/zita-convolver-3.1.0/*.o lib/zita-convolver-3.1.0/*.d
++	rm -f lib/zita-convolver-4.0.0/*.o lib/zita-convolver-4.0.0/*.d
+ 	rm -f plugins/ZamSFZ/libsfz/*.o plugins/ZamSFZ/libsfz/*.d
+ 
+ # --------------------------------------------------------------
+diff --git a/lib/zita-convolver-3.1.0/zita-convolver.h b/lib/zita-convolver-3.1.0/zita-convolver.h
+deleted file mode 100644
+index 37f4d03..0000000
+--- a/lib/zita-convolver-3.1.0/zita-convolver.h
++++ /dev/null
+@@ -1,471 +0,0 @@
+-// ----------------------------------------------------------------------------
+-//
+-//  Copyright (C) 2006-2011 Fons Adriaensen <fons at 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 _ZITA_CONVOLVER_H
+-#define _ZITA_CONVOLVER_H
+-
+-#define _POSIX_PTHREAD_SEMANTICS
+-
+-#include <errno.h>
+-#include <pthread.h>
+-#include <fftw3.h>
+-
+-
+-#define ZITA_CONVOLVER_MAJOR_VERSION 3
+-#define ZITA_CONVOLVER_MINOR_VERSION 1
+-
+-
+-extern int zita_convolver_major_version (void);
+-extern int zita_convolver_minor_version (void);
+-
+-
+-// ----------------------------------------------------------------------------
+-
+-
+-#ifdef ZCSEMA_IS_IMPLEMENTED
+-#undef ZCSEMA_IS_IMPLEMENTED
+-#endif
+-
+-
+-#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__GNU__) || defined(__WIN32__)
+-
+-// NOTE: __FreeBSD_kernel__  and __GNU__ were added by the Debian maintainers
+-// (the latter for the HURD version of Debian). Things are reported to work
+-// with some applications but probably have not been tested in depth.
+-// __WIN32__ was added by DZ for MingW
+-
+-#include <semaphore.h>
+-
+-class ZCsema
+-{
+-public:
+-
+-    ZCsema (void) { init (0, 0); }
+-    ~ZCsema (void) { sem_destroy (&_sema); }
+-
+-    ZCsema (const ZCsema&); // disabled
+-    ZCsema& operator= (const ZCsema&); // disabled
+-
+-    int init (int s, int v) { return sem_init (&_sema, s, v); }
+-    int post (void) { return sem_post (&_sema); }
+-    int wait (void) { return sem_wait (&_sema); }
+-    int trywait (void) { return sem_trywait (&_sema); }
+-
+-private:
+-
+-    sem_t  _sema;
+-};
+-
+-#define ZCSEMA_IS_IMPLEMENTED
+-#endif
+-
+-
+-// ADDED BY DZ TO MAKE IT COMPILE FOR OSX 10.5 or Windows
+-#if defined(__APPLE__) || defined(__WIN32__)
+-inline int posix_memalign(void **memptr, size_t alignment, size_t size)
+-{
+-   *memptr = malloc(size);
+-   if (*memptr == NULL)
+-       return ENOMEM;
+-   return 0;
+-}
+-#endif
+-
+-
+-#ifdef __APPLE__
+-
+-// NOTE:  ***** I DO NOT REPEAT NOT PROVIDE SUPPORT FOR OSX *****
+-// 
+-// The following code partially emulates the POSIX sem_t for which
+-// OSX has only a crippled implementation. It may or may not compile,
+-// and if it compiles it may or may not work correctly. Blame APPLE
+-// for not following POSIX standards.
+-
+-class ZCsema
+-{
+-public:
+-
+-    ZCsema (void) : _count (0)
+-    {
+-        init (0, 0);
+-    }
+-
+-    ~ZCsema (void)
+-    {
+-        pthread_mutex_destroy (&_mutex);
+-        pthread_cond_destroy (&_cond);
+-    }
+-
+-    ZCsema (const ZCsema&); // disabled
+-    ZCsema& operator= (const ZCsema&); // disabled
+-
+-    int init (int s, int v)
+-    {
+-	_count = v;
+-        return pthread_mutex_init (&_mutex, 0) || pthread_cond_init (&_cond, 0);
+-    }
+-
+-    int post (void)
+-    {
+-	pthread_mutex_lock (&_mutex);
+-	_count++;
+-	if (_count == 1) pthread_cond_signal (&_cond);
+-	pthread_mutex_unlock (&_mutex);
+-	return 0;
+-    }
+-
+-    int wait (void)
+-    {
+-	pthread_mutex_lock (&_mutex);
+-	while (_count < 1) pthread_cond_wait (&_cond, &_mutex);
+-	_count--;
+-	pthread_mutex_unlock (&_mutex);
+-	return 0;
+-    }
+-
+-    int trywait (void)
+-    {
+-	if (pthread_mutex_trylock (&_mutex)) return -1;
+-	if (_count < 1)
+-	{
+-	    pthread_mutex_unlock (&_mutex);
+-	    return -1;
+-	}
+-        _count--;
+-        pthread_mutex_unlock (&_mutex);
+-        return 0;
+-    }
+-
+-private:
+-
+-    int              _count;
+-    pthread_mutex_t  _mutex;
+-    pthread_cond_t   _cond;
+-};
+-
+-#define ZCSEMA_IS_IMPLEMENTED
+-#endif
+-
+-
+-#ifndef ZCSEMA_IS_IMPLEMENTED
+-#error "The ZCsema class is not implemented."
+-#endif
+-
+-
+-// ----------------------------------------------------------------------------
+-
+-
+-class Inpnode   
+-{
+-private:
+-
+-    friend class Convlevel;
+-
+-    Inpnode        *_next;
+-    fftwf_complex **_ffta;
+-    unsigned int    _inp;
+-};
+-
+-
+-class Macnode  
+-{
+-private:
+-
+-    friend class Convlevel;
+-
+-    Macnode        *_next;
+-    Inpnode        *_inpn;
+-    fftwf_complex **_fftb;
+-    bool            _copy;
+-};
+-
+-
+-class Outnode   
+-{
+-private:
+-
+-    friend class Convlevel;
+-
+-    Outnode        *_next;
+-    Macnode        *_list;
+-    float          *_buff [3];
+-    unsigned int    _out;
+-};
+-
+-
+-class Converror
+-{
+-public:
+-
+-    enum
+-    {
+-	BAD_STATE = -1,
+-	BAD_PARAM = -2,
+-        MEM_ALLOC = -3
+-    };
+-
+-private:
+-
+-    friend class Convlevel;
+-    friend class Convproc;
+-
+-    Converror (int error) : _error (error) {}
+-
+-    int _error;
+-};
+-
+-
+-class Convlevel
+-{
+-private:
+-
+-    friend class Convproc;
+-
+-    enum 
+-    {
+-        OPT_FFTW_MEASURE = 1,
+-        OPT_VECTOR_MODE  = 2
+-    };
+-
+-    enum
+-    {
+-        ST_IDLE,
+-        ST_TERM,
+-        ST_PROC
+-    };
+-
+-    Convlevel (void);
+-    ~Convlevel (void);
+-
+-    void *alloc_aligned (size_t size);
+-
+-    void configure (int prio,
+-                    unsigned int offs,
+-                    unsigned int npar,
+-                    unsigned int parsize,
+-		    unsigned int options);
+-
+-    void impdata_create (unsigned int inp,
+-                         unsigned int out,
+-                         unsigned int step,
+-                         float *data,
+-                         int ind0,
+-                         int ind1); 
+-
+-    void impdata_update (unsigned int inp,
+-                         unsigned int out,
+-                         unsigned int step,
+-                         float *data,
+-                         int ind0,
+-                         int ind1); 
+-
+-    void impdata_copy (unsigned int inp1,
+-                       unsigned int out1,
+-                       unsigned int inp2,
+-                       unsigned int out2);
+-
+-    void reset (unsigned int inpsize,
+-                unsigned int outsize,
+-	        float **inpbuff,
+-	        float **outbuff);
+-
+-    void start (int absprio, int policy);
+-
+-    void process (bool sync);
+-
+-    int  readout (bool sync, unsigned int skipcnt);
+-
+-    void stop (void);
+-
+-    void cleanup (void);
+-
+-    void fftswap (fftwf_complex *p);
+-
+-    void print (FILE *F);
+-
+-    static void *static_main (void *arg);
+-
+-    void main (void);
+-
+-    Macnode *findmacnode (unsigned int inp, unsigned int out, bool create);
+-
+-    volatile unsigned int _stat;           // current processing state
+-    int                   _prio;           // relative priority
+-    unsigned int          _offs;           // offset from start of impulse response
+-    unsigned int          _npar;           // number of partitions
+-    unsigned int          _parsize;        // partition and outbut buffer size
+-    unsigned int          _outsize;        // step size for output buffer
+-    unsigned int          _outoffs;        // offset into output buffer
+-    unsigned int          _inpsize;        // size of shared input buffer 
+-    unsigned int          _inpoffs;        // offset into input buffer
+-    unsigned int          _options;        // various options
+-    unsigned int          _ptind;          // rotating partition index
+-    unsigned int          _opind;          // rotating output buffer index
+-    int                   _bits;           // bit identifiying this level
+-    int                   _wait;           // number of unfinished cycles
+-    pthread_t             _pthr;           // posix thread executing this level
+-    ZCsema                _trig;           // sema used to trigger a cycle
+-    ZCsema                _done;           // sema used to wait for a cycle
+-    Inpnode              *_inp_list;       // linked list of active inputs
+-    Outnode              *_out_list;       // linked list of active outputs
+-    fftwf_plan            _plan_r2c;       // FFTW plan, forward FFT
+-    fftwf_plan            _plan_c2r;       // FFTW plan, inverse FFT
+-    float                *_time_data;      // workspace
+-    float                *_prep_data;      // workspace
+-    fftwf_complex        *_freq_data;      // workspace
+-    float               **_inpbuff;        // array of shared input buffers
+-    float               **_outbuff;        // array of shared output buffers
+-};
+-
+-
+-// ----------------------------------------------------------------------------
+-
+-
+-class Convproc
+-{
+-public:
+-
+-    Convproc (void);
+-    ~Convproc (void);
+-
+-    enum
+-    {
+-        ST_IDLE,
+-	ST_STOP,
+-        ST_WAIT,
+-        ST_PROC
+-    };
+-
+-    enum
+-    {
+-        FL_LATE = 0x0000FFFF,
+-	FL_LOAD = 0x01000000
+-    };
+-
+-    enum 
+-    {
+-        OPT_FFTW_MEASURE = Convlevel::OPT_FFTW_MEASURE, 
+-        OPT_VECTOR_MODE  = Convlevel::OPT_VECTOR_MODE
+-    };
+-
+-    enum
+-    {
+-	MAXINP   = 64,
+-	MAXOUT   = 64,
+-	MAXLEV   = 8,
+-	MINPART  = 64,
+-	MAXPART  = 8192,
+-	MAXDIVIS = 16,
+-	MINQUANT = 16,
+-	MAXQUANT = 8192
+-    };
+-
+-    unsigned int state (void) const
+-    {
+-	return _state;
+-    }
+-
+-    float *inpdata (unsigned int inp) const
+-    {
+-	return _inpbuff [inp] + _inpoffs;
+-    }
+-
+-    float *outdata (unsigned int out) const
+-    {
+-	return _outbuff [out] + _outoffs;
+-    }
+-
+-    void set_density (float density);
+-
+-    void set_options (unsigned int options);
+-
+-    void set_skipcnt (unsigned int skipcnt);
+-
+-    int configure (unsigned int ninp,
+-                   unsigned int nout,
+-                   unsigned int maxsize,
+-                   unsigned int quantum,
+-                   unsigned int minpart,
+-                   unsigned int maxpart);
+-
+-    int impdata_create (unsigned int inp,
+-                        unsigned int out,
+-                        unsigned int step,
+-                        float       *data,
+-                        int          ind0,
+-                        int          ind1); 
+-
+-    int impdata_update (unsigned int inp,
+-                        unsigned int out,
+-                        unsigned int step,
+-                        float       *data,
+-                        int          ind0,
+-                        int          ind1); 
+-
+-    int impdata_copy (unsigned int inp1,
+-                      unsigned int out1,
+-                      unsigned int inp2,
+-                      unsigned int out2);
+-
+-    int reset (void);
+-
+-    int start_process (int abspri, int policy);
+-
+-    int process (bool sync = false);
+-
+-    int stop_process (void);
+-
+-    bool check_stop (void);
+-
+-    int cleanup (void);
+-
+-    void print (FILE *F = stdout);
+-
+-    static float _mac_cost;
+-    static float _fft_cost;
+-
+-private:
+-
+-    unsigned int    _state;                   // current state
+-    float          *_inpbuff [MAXINP];        // input buffers
+-    float          *_outbuff [MAXOUT];        // output buffers
+-    unsigned int    _inpoffs;                 // current offset in input buffers
+-    unsigned int    _outoffs;                 // current offset in output buffers
+-    unsigned int    _options;                 // option bits
+-    unsigned int    _skipcnt;                 // number of frames to skip 
+-    float           _density;                 // matrix density hint
+-    unsigned int    _ninp;                    // number of inputs
+-    unsigned int    _nout;                    // number of outputs
+-    unsigned int    _quantum;                 // processing block size
+-    unsigned int    _minpart;                 // smallest partition size
+-    unsigned int    _maxpart;                 // largest allowed partition size
+-    unsigned int    _nlevels;                 // number of partition sizes
+-    unsigned int    _inpsize;                 // size of input buffers
+-    unsigned int    _latecnt;                 // count of cycles ending too late
+-    Convlevel      *_convlev [MAXLEV];        // array of processors 
+-    void           *_dummy [64];
+-};
+-
+-
+-// ----------------------------------------------------------------------------
+-
+-
+-#endif
+-
+diff --git a/lib/zita-convolver-4.0.0/zcsema-osx-win-compat.h b/lib/zita-convolver-4.0.0/zcsema-osx-win-compat.h
+new file mode 100644
+index 0000000..807f6b8
+--- /dev/null
++++ b/lib/zita-convolver-4.0.0/zcsema-osx-win-compat.h
+@@ -0,0 +1,40 @@
++#if defined(__WIN32__)
++
++#include <semaphore.h>
++
++class ZCsema
++{
++public:
++
++    ZCsema (void) { init (0, 0); }
++    ~ZCsema (void) { sem_destroy (&_sema); }
++
++    ZCsema (const ZCsema&); // disabled
++    ZCsema& operator= (const ZCsema&); // disabled
++
++    int init (int s, int v) { return sem_init (&_sema, s, v); }
++    int post (void) { return sem_post (&_sema); }
++    int wait (void) { return sem_wait (&_sema); }
++    int trywait (void) { return sem_trywait (&_sema); }
++
++private:
++
++    sem_t  _sema;
++};
++
++#define ZCSEMA_IS_IMPLEMENTED
++#endif
++
++
++// ADDED BY DZ TO MAKE IT COMPILE FOR OSX 10.5 or Windows
++#if defined(__APPLE__) || defined(__WIN32__)
++#include <errno.h>
++
++inline int posix_memalign(void **memptr, size_t alignment, size_t size)
++{
++   *memptr = malloc(size);
++   if (*memptr == NULL)
++       return ENOMEM;
++   return 0;
++}
++#endif
+diff --git a/lib/zita-convolver-3.1.0/zita-convolver.cpp b/lib/zita-convolver-4.0.0/zita-convolver.cpp
+similarity index 68%
+rename from lib/zita-convolver-3.1.0/zita-convolver.cpp
+rename to lib/zita-convolver-4.0.0/zita-convolver.cpp
+index a5155de..202533d 100644
+--- a/lib/zita-convolver-3.1.0/zita-convolver.cpp
++++ b/lib/zita-convolver-4.0.0/zita-convolver.cpp
+@@ -1,6 +1,6 @@
+ // ----------------------------------------------------------------------------
+ //
+-//  Copyright (C) 2006-2011 Fons Adriaensen <fons at linuxaudio.org>
++//  Copyright (C) 2006-2018 Fons Adriaensen <fons at 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
+@@ -42,11 +42,27 @@ float Convproc::_mac_cost = 1.0f;
+ float Convproc::_fft_cost = 5.0f;
+ 
+ 
++static float *calloc_real (uint32_t k)
++{
++    float *p = fftwf_alloc_real (k);
++    if (!p) throw (Converror (Converror::MEM_ALLOC));
++    memset (p, 0, k * sizeof (float));
++    return p;
++}
++
++static fftwf_complex *calloc_complex (uint32_t k)
++{
++    fftwf_complex *p = fftwf_alloc_complex (k);
++    if (!p) throw (Converror (Converror::MEM_ALLOC));
++    memset (p, 0, k * sizeof (fftwf_complex));
++    return p;
++}
++
++
+ Convproc::Convproc (void) :
+     _state (ST_IDLE),
+     _options (0),
+     _skipcnt (0),
+-    _density (0),
+     _ninp (0),
+     _nout (0),
+     _quantum (0),
+@@ -63,41 +79,39 @@ Convproc::Convproc (void) :
+ 
+ Convproc::~Convproc (void)
+ {
++    stop_process ();
+     cleanup ();
+ }
+ 
+ 
+-void Convproc::set_options (unsigned int options)
++void Convproc::set_options (uint32_t options)
+ {
+     _options = options;
+ }
+ 
+ 
+-void Convproc::set_density (float density)
+-{
+-    _density = density;
+-}
+-
+-
+-void Convproc::set_skipcnt (unsigned int skipcnt)
++void Convproc::set_skipcnt (uint32_t skipcnt)
+ {
+     if ((_quantum == _minpart) && (_quantum == _maxpart)) _skipcnt = skipcnt;
+ }
+ 
+ 
+-int Convproc::configure (unsigned int ninp,
+-                         unsigned int nout,
+-                         unsigned int maxsize,
+-                         unsigned int quantum,
+-                         unsigned int minpart,
+-			 unsigned int maxpart)
++int Convproc::configure (uint32_t  ninp,
++                         uint32_t  nout,
++                         uint32_t  maxsize,
++                         uint32_t  quantum,
++                         uint32_t  minpart,
++			 uint32_t  maxpart,
++                         float     density)
+ {
+-    unsigned int  offs, npar, size, pind, nmin, nmax, step, i;
+-    int           prio, d, r, s;
+-    float         cfft, cmac, t;
++    uint32_t  offs, npar, size, pind, nmin, i;
++    int       prio, step, d, r, s;
++    float     cfft, cmac;
+     
+     if (_state != ST_IDLE) return Converror::BAD_STATE;
+-    if (   (quantum & (quantum - 1))
++    if (   (ninp < 1) || (ninp > MAXINP)
++        || (nout < 1) || (nout > MAXOUT)
++	|| (quantum & (quantum - 1))
+         || (quantum < MINQUANT)
+         || (quantum > MAXQUANT)
+         || (minpart & (minpart - 1))
+@@ -108,21 +122,12 @@ int Convproc::configure (unsigned int ninp,
+ 	|| (maxpart > MAXPART)
+ 	|| (maxpart < minpart)) return Converror::BAD_PARAM;
+ 
+-    if (ninp < nout) { nmin = ninp; nmax = nout; }
+-    else             { nmin = nout; nmax = ninp; }
+-
+-    if (_density <= 0) _density = 1.0 / nmin;
+-    else
+-    {
+-        t = 1.0f / nmax;
+-        if (_density < t) _density = t;
+-        if (_density > 1) _density = 1;
+-    }
+-
++    nmin = (ninp < nout) ? ninp : nout;
++    if (density <= 0.0f) density = 1.0f / nmin;
++    if (density >  1.0f) density = 1.0f;
+     cfft = _fft_cost * (ninp + nout);
+-    cmac = _mac_cost * ninp * nout * _density;
++    cmac = _mac_cost * ninp * nout * density;
+     step = (cfft < 4 * cmac) ? 1 : 2;
+-
+     if (step == 2)
+     {
+         r = maxpart / minpart;
+@@ -131,7 +136,6 @@ int Convproc::configure (unsigned int ninp,
+     else s = 1;
+     nmin = (s == 1) ? 2 : 6;
+     if (minpart == quantum) nmin++;
+-
+     prio = 0;
+     size = quantum;
+     while (size < minpart)
+@@ -154,7 +158,6 @@ int Convproc::configure (unsigned int ninp,
+ 	    }
+ 	    _convlev [pind] = new Convlevel ();
+ 	    _convlev [pind]->configure (prio, offs, npar, size, _options);
+-
+ 	    offs += size * npar;
+ 	    if (offs < maxsize)
+ 	    {
+@@ -188,21 +191,22 @@ int Convproc::configure (unsigned int ninp,
+ }
+ 
+ 
+-int Convproc::impdata_create (unsigned int inp,
+-                              unsigned int out,
+-                              unsigned int step,
+-                              float       *data,
+-                              int          ind0,
+-                              int          ind1)
++int Convproc::impdata_create (uint32_t  inp,
++                              uint32_t  out,
++                              int32_t   step,
++                              float     *data,
++                              int32_t   ind0,
++                              int32_t   ind1)
+ {
+-    unsigned int j;
++    uint32_t j;
+ 
+     if (_state != ST_STOP) return Converror::BAD_STATE;
++    if ((inp >= _ninp) || (out >= _nout)) return Converror::BAD_PARAM;
+     try
+     {
+         for (j = 0; j < _nlevels; j++)
+ 	{
+-            _convlev [j]->impdata_create (inp, out, step, data, ind0, ind1);
++            _convlev [j]->impdata_write (inp, out, step, data, ind0, ind1, true);
+ 	}
+     }
+     catch (...)
+@@ -214,37 +218,51 @@ int Convproc::impdata_create (unsigned int inp,
+ }
+ 
+ 
+-int Convproc::impdata_update (unsigned int inp,
+-                              unsigned int out,
+-                              unsigned int step,
+-                              float       *data, 
+-                              int          ind0,
+-                              int          ind1)
++int Convproc::impdata_clear (uint32_t inp, uint32_t out)
+ {
+-    unsigned int j;
++    uint32_t k;
+ 
+     if (_state < ST_STOP) return Converror::BAD_STATE;
++    for (k = 0; k < _nlevels; k++) _convlev [k]->impdata_clear (inp, out);
++    return 0;
++}
++
++
++int Convproc::impdata_update (uint32_t  inp,
++                              uint32_t  out,
++                              int32_t   step,
++                              float     *data, 
++                              int32_t   ind0,
++                              int32_t   ind1)
++{
++    uint32_t j;
++
++    if (_state < ST_STOP) return Converror::BAD_STATE;
++    if ((inp >= _ninp) || (out >= _nout)) return Converror::BAD_PARAM;
+     for (j = 0; j < _nlevels; j++)
+     {
+-        _convlev [j]->impdata_update (inp, out, step, data, ind0, ind1);
++        _convlev [j]->impdata_write (inp, out, step, data, ind0, ind1, false);
+     }
+     return 0;
+ }
+ 
+ 
+-int Convproc::impdata_copy (unsigned int inp1,
+-                            unsigned int out1,
+-                            unsigned int inp2,
+-                            unsigned int out2) 
++int Convproc::impdata_link (uint32_t inp1,
++                            uint32_t out1,
++                            uint32_t inp2,
++                            uint32_t out2) 
+ {
+-    unsigned int j;
+-
++    uint32_t j;
++    
++    if ((inp1 >= _ninp) || (out1 >= _nout)) return Converror::BAD_PARAM;
++    if ((inp2 >= _ninp) || (out2 >= _nout)) return Converror::BAD_PARAM;
++    if ((inp1 == inp2) && (out1 == out2)) return Converror::BAD_PARAM;
+     if (_state != ST_STOP) return Converror::BAD_STATE;
+     try
+     {
+         for (j = 0; j < _nlevels; j++)
+ 	{
+-            _convlev [j]->impdata_copy (inp1, out1, inp2, out2);
++            _convlev [j]->impdata_link (inp1, out1, inp2, out2);
+ 	}
+     }
+     catch (...)
+@@ -258,7 +276,7 @@ int Convproc::impdata_copy (unsigned int inp1,
+ 
+ int Convproc::reset (void)
+ {
+-    unsigned int k;
++    uint32_t k;
+ 
+     if (_state == ST_IDLE) return Converror::BAD_STATE;
+     for (k = 0; k < _ninp; k++) memset (_inpbuff [k], 0, _inpsize * sizeof (float));
+@@ -270,17 +288,17 @@ int Convproc::reset (void)
+ 
+ int Convproc::start_process (int abspri, int policy)
+ {
+-    unsigned int k;
++    uint32_t k;
+ 
+     if (_state != ST_STOP) return Converror::BAD_STATE;
+-
+     _latecnt = 0;
+     _inpoffs = 0;
+     _outoffs = 0;
+     reset ();
++
+     for (k = (_minpart == _quantum) ? 1 : 0; k < _nlevels; k++)
+     {
+-         _convlev [k]->start (abspri, policy);
++        _convlev [k]->start (abspri, policy);
+     }
+     _state = ST_PROC;
+     return 0;
+@@ -289,14 +307,12 @@ int Convproc::start_process (int abspri, int policy)
+ 
+ int Convproc::process (bool sync)
+ {
+-    unsigned int k;
+-    int f = 0;
++    uint32_t  k;
++    int       f = 0;
+ 
+     if (_state != ST_PROC) return 0;
+-    
+     _inpoffs += _quantum;
+     if (_inpoffs == _inpsize) _inpoffs = 0;
+-
+     _outoffs += _quantum;
+     if (_outoffs == _minpart)
+     {
+@@ -309,7 +325,7 @@ int Convproc::process (bool sync)
+ 	{
+             if (++_latecnt >= 5)
+             {
+-	        stop_process ();
++	        if (~_options & OPT_LATE_CONTIN) stop_process ();
+ 	        f |= FL_LOAD;
+ 	    }
+ 	}
+@@ -321,7 +337,7 @@ int Convproc::process (bool sync)
+ 
+ int Convproc::stop_process (void)
+ {
+-    unsigned int k;
++    uint32_t k;
+ 
+     if (_state != ST_PROC) return Converror::BAD_STATE;
+     for (k = 0; k < _nlevels; k++) _convlev [k]->stop ();
+@@ -332,17 +348,12 @@ int Convproc::stop_process (void)
+ 
+ int Convproc::cleanup (void)
+ {
+-    unsigned int k;
++    uint32_t k;
+ 
+     while (! check_stop ())
+     {
+         usleep (100000);
+     }
+-    if (_state != ST_STOP)
+-    {
+-        return Converror::BAD_STATE;
+-    }
+-
+     for (k = 0; k < _ninp; k++)
+     {
+         delete[] _inpbuff [k];
+@@ -362,7 +373,6 @@ int Convproc::cleanup (void)
+     _state = ST_IDLE;
+     _options = 0;
+     _skipcnt = 0;
+-    _density = 0;
+     _ninp = 0;
+     _nout = 0;
+     _quantum = 0;
+@@ -376,7 +386,7 @@ int Convproc::cleanup (void)
+ 
+ bool Convproc::check_stop (void)
+ {
+-    unsigned int k;
++    uint32_t k;
+ 
+     for (k = 0; (k < _nlevels) && (_convlev [k]->_stat == Convlevel::ST_IDLE); k++);
+     if (k == _nlevels)
+@@ -390,7 +400,7 @@ bool Convproc::check_stop (void)
+ 
+ void Convproc::print (FILE *F)
+ {
+-    unsigned int k;
++    uint32_t k;
+ 
+     for (k = 0; k < _nlevels; k++) _convlev [k]->print (F);
+ }
+@@ -424,21 +434,11 @@ Convlevel::~Convlevel (void)
+ }
+ 
+ 
+-void *Convlevel::alloc_aligned (size_t size)
+-{
+-    void *p;
+-
+-    if (posix_memalign (&p, 16, size)) throw (Converror (Converror::MEM_ALLOC));
+-    memset (p, 0, size);
+-    return p;
+-}
+-
+-
+-void Convlevel::configure (int prio,
+-                           unsigned int offs,
+-                           unsigned int npar,
+-                           unsigned int parsize,
+-			   unsigned int options)
++void Convlevel::configure (int       prio,
++                           uint32_t  offs,
++                           uint32_t  npar,
++                           uint32_t  parsize,
++			   uint32_t  options)
+ {
+     int fftwopt = (options & OPT_FFTW_MEASURE) ? FFTW_MEASURE : FFTW_ESTIMATE;
+ 
+@@ -448,9 +448,9 @@ void Convlevel::configure (int prio,
+     _parsize = parsize;
+     _options = options;
+     
+-    _time_data = (float *)(alloc_aligned (2 * _parsize * sizeof (float)));
+-    _prep_data = (float *)(alloc_aligned (2 * _parsize * sizeof (float)));
+-    _freq_data = (fftwf_complex *)(alloc_aligned ((_parsize + 1) * sizeof (fftwf_complex)));
++    _time_data = calloc_real (2 * _parsize);
++    _prep_data = calloc_real (2 * _parsize);
++    _freq_data = calloc_complex (_parsize + 1);
+     _plan_r2c = fftwf_plan_dft_r2c_1d (2 * _parsize, _time_data, _freq_data, fftwopt);
+     _plan_c2r = fftwf_plan_dft_c2r_1d (2 * _parsize, _freq_data, _time_data, fftwopt);
+     if (_plan_r2c && _plan_c2r) return;
+@@ -458,42 +458,49 @@ void Convlevel::configure (int prio,
+ }
+ 
+ 
+-void Convlevel::impdata_create (unsigned int inp,
+-                                unsigned int out,
+-                                unsigned int step,
+-                                float *data,
+-                                int i0,
+-                                int i1)
++void Convlevel::impdata_write (uint32_t  inp,
++                               uint32_t  out,
++                               int32_t   step,
++                               float     *data,
++                               int32_t   i0,
++                               int32_t   i1,
++                               bool      create)
+ {
+-    unsigned int   k;
+-    int            j, j0, j1, n;
+-    float          norm;
+-    fftwf_complex  *fftb;
+-    Macnode        *M;
++    uint32_t        k;
++    int32_t         j, j0, j1, n;
++    float           norm;
++    fftwf_complex   *fftb;
++    Macnode         *M;
+ 
+     n = i1 - i0;
+     i0 = _offs - i0;
+     i1 = i0 + _npar * _parsize;
+     if ((i0 >= n) || (i1 <= 0)) return;
+ 
+-    M = findmacnode (inp, out, true);
+-    if (! (M->_fftb))
++    if (create)
+     {
+-	M->_fftb = new fftwf_complex * [_npar];
+-	memset (M->_fftb, 0, _npar * sizeof (fftwf_complex *));
++        M = findmacnode (inp, out, true);
++	if (M == 0 || M->_link) return;
++	if (M->_fftb == 0) M->alloc_fftb (_npar);
+     }
+-
++    else
++    {
++        M = findmacnode (inp, out, false);
++	if (M == 0 || M->_link || M->_fftb == 0) return;
++    }
++    
+     norm = 0.5f / _parsize;
+     for (k = 0; k < _npar; k++)
+     {
+ 	i1 = i0 + _parsize;
+ 	if ((i0 < n) && (i1 > 0))
+ 	{
+-	    if (! (M->_fftb [k]))
+-	    {
+-		M->_fftb [k] = (fftwf_complex *)(alloc_aligned ((_parsize + 1) * sizeof (fftwf_complex)));
++	    fftb = M->_fftb [k];
++            if (fftb == 0 && create)
++            {
++		M->_fftb [k] = fftb = calloc_complex (_parsize + 1);
+ 	    }
+-	    if (data)
++	    if (fftb && data)
+ 	    {
+ 	        memset (_prep_data, 0, 2 * _parsize * sizeof (float));
+ 	        j0 = (i0 < 0) ? 0 : i0;
+@@ -503,7 +510,6 @@ void Convlevel::impdata_create (unsigned int inp,
+ #ifdef ENABLE_VECTOR_MODE
+ 	        if (_options & OPT_VECTOR_MODE) fftswap (_freq_data);
+ #endif
+-  	        fftb = M->_fftb [k];
+ 	        for (j = 0; j <= (int)_parsize; j++)
+ 	        {
+ 	            fftb [j][0] += _freq_data [j][0];
+@@ -516,52 +522,27 @@ void Convlevel::impdata_create (unsigned int inp,
+ }
+ 
+ 
+-void Convlevel::impdata_update (unsigned int inp,
+-                                unsigned int out,
+-                                unsigned int step,
+-                                float *data,
+-                                int i0,
+-                                int i1)
++void Convlevel::impdata_clear (uint32_t inp, uint32_t out)
+ {
+-    unsigned int   k;
+-    int            j, j0, j1, n;
+-    float          norm;
+-    fftwf_complex  *fftb;
+-    Macnode        *M;
++    uint32_t  i;
++    Macnode   *M;
+ 
+     M = findmacnode (inp, out, false);
+-    if (! M) return;
+-
+-    n = i1 - i0;
+-    i0 = _offs - i0;
+-    i1 = i0 + _npar * _parsize;
+-    if ((i0 >= n) || (i1 <= 0)) return;
+-
+-    norm = 0.5f / _parsize;
+-    for (k = 0; k < _npar; k++)
++    if (M == 0 || M->_link || M->_fftb == 0) return;
++    for (i = 0; i < _npar; i++)
+     {
+-	i1 = i0 + _parsize;
+-	fftb = M->_fftb [k];
+-	if (fftb && (i0 < n) && (i1 > 0))
+-	{
+-	    memset (_prep_data, 0, 2 * _parsize * sizeof (float));
+-	    j0 = (i0 < 0) ? 0 : i0;
+-	    j1 = (i1 > n) ? n : i1;
+-	    for (j = j0; j < j1; j++) _prep_data [j - i0] = norm * data [j * step];
+-	    fftwf_execute_dft_r2c (_plan_r2c, _prep_data, fftb);
+-#ifdef ENABLE_VECTOR_MODE
+-	    if (_options & OPT_VECTOR_MODE) fftswap (fftb);
+-#endif
++        if (M->_fftb [i])
++        {
++  	    memset (M->_fftb [i], 0, (_parsize + 1) * sizeof (fftwf_complex));
+ 	}
+-	i0 = i1;
+     }
+ }
+ 
+ 
+-void Convlevel::impdata_copy (unsigned int inp1,
+-                              unsigned int out1,
+-                              unsigned int inp2,
+-                              unsigned int out2)
++void Convlevel::impdata_link (uint32_t inp1,
++                              uint32_t out1,
++                              uint32_t inp2,
++                              uint32_t out2)
+ {
+     Macnode  *M1;
+     Macnode  *M2;
+@@ -569,18 +550,17 @@ void Convlevel::impdata_copy (unsigned int inp1,
+     M1 = findmacnode (inp1, out1, false);
+     if (! M1) return;
+     M2 = findmacnode (inp2, out2, true);
+-    if (M2->_fftb) return;
+-    M2->_fftb = M1->_fftb;
+-    M2->_copy = true;
++    M2->free_fftb ();	
++    M2->_link = M1;
+ }
+ 
+ 
+-void Convlevel::reset (unsigned int  inpsize,
+-                       unsigned int  outsize,
++void Convlevel::reset (uint32_t  inpsize,
++                       uint32_t  outsize,
+ 		       float         **inpbuff,
+ 		       float         **outbuff)
+ {
+-    unsigned int  i;
++    uint32_t     i;
+     Inpnode      *X; 
+     Outnode      *Y; 
+ 
+@@ -658,7 +638,6 @@ void Convlevel::stop (void)
+ 
+ void Convlevel::cleanup (void)
+ {
+-    unsigned int  i;
+     Inpnode       *X, *X1;
+     Outnode       *Y, *Y1;
+     Macnode       *M, *M1;
+@@ -666,8 +645,6 @@ void Convlevel::cleanup (void)
+     X = _inp_list;
+     while (X)
+     {
+-        for (i = 0; i < _npar; i++) free (X->_ffta [i]);
+-	delete[] X->_ffta;
+ 	X1 = X->_next;
+ 	delete X;
+ 	X = X1;
+@@ -680,19 +657,10 @@ void Convlevel::cleanup (void)
+ 	M = Y->_list;
+ 	while (M)
+ 	{
+-	    if ((M->_fftb) && !(M->_copy))
+-	    {
+-	        for (i = 0; i < _npar; i++) 
+-		{
+-                    free (M->_fftb [i]);
+-		}
+-	        delete[] M->_fftb;
+-	    }
+ 	    M1 = M->_next;
+ 	    delete M;
+ 	    M = M1;
+ 	}
+-	for (i = 0; i < 3; i++) free (Y->_buff [i]);
+ 	Y1 = Y->_next;
+ 	delete Y;
+ 	Y = Y1;
+@@ -701,9 +669,9 @@ void Convlevel::cleanup (void)
+ 
+     fftwf_destroy_plan (_plan_r2c);
+     fftwf_destroy_plan (_plan_c2r);
+-    free (_time_data);
+-    free (_prep_data);
+-    free (_freq_data);
++    fftwf_free (_time_data);
++    fftwf_free (_prep_data);
++    fftwf_free (_freq_data);
+     _plan_r2c = 0;
+     _plan_c2r = 0;
+     _time_data = 0;
+@@ -739,9 +707,7 @@ void Convlevel::main (void)
+ 
+ void Convlevel::process (bool skip)
+ {
+-    unsigned int    i, j, k;
+-    unsigned int    i1, n1, n2, opi1, opi2;
+-
++    uint32_t        i, i1, j, k, n1, n2, opi1, opi2;
+     Inpnode         *X;
+     Macnode         *M;
+     Outnode         *Y;
+@@ -796,7 +762,7 @@ void Convlevel::process (bool skip)
+ 		for (j = 0; j < _npar; j++)
+ 		{
+ 		    ffta = X->_ffta [i];
+-		    fftb = M->_fftb [j];
++		    fftb = M->_link ? M->_link->_fftb [j] : M->_fftb [j];
+ 		    if (fftb)
+ 		    {
+ #ifdef ENABLE_VECTOR_MODE
+@@ -847,11 +813,11 @@ void Convlevel::process (bool skip)
+ }
+ 
+ 
+-int Convlevel::readout (bool sync, unsigned int skipcnt)
++int Convlevel::readout (bool sync, uint32_t skipcnt)
+ {
+-    unsigned int  i;
+-    float         *p, *q;	
+-    Outnode       *Y;
++    uint32_t   i;
++    float      *p, *q;	
++    Outnode    *Y;
+ 
+     _outoffs += _outsize;
+     if (_outoffs == _parsize)
+@@ -893,58 +859,38 @@ void Convlevel::print (FILE *F)
+ }
+ 
+ 
+-Macnode *Convlevel::findmacnode (unsigned int inp, unsigned int out, bool create)
++Macnode *Convlevel::findmacnode (uint32_t inp, uint32_t out, bool create)
+ {
+-    unsigned int  i;
+-    Inpnode       *X;
+-    Outnode       *Y;
+-    Macnode       *M;
++    Inpnode   *X;
++    Outnode   *Y;
++    Macnode   *M;
+ 
+     for (X = _inp_list; X && (X->_inp != inp); X = X->_next);
+     if (! X)
+     {
+ 	if (! create) return 0;
+-	X = new Inpnode;
++	X = new Inpnode (inp);
+ 	X->_next = _inp_list;
+ 	_inp_list = X;
+-	X->_inp = inp;
+-	X->_ffta = new fftwf_complex * [_npar];
+-	memset (X->_ffta, 0, _npar * sizeof (fftw_complex *));
+-        for (i = 0; i < _npar; i++)
+-	{
+-            X->_ffta [i] = (fftwf_complex *)(alloc_aligned ((_parsize + 1) * sizeof (fftwf_complex)));
+-	}
++	X->alloc_ffta (_npar, _parsize);
+     }
+ 
+     for (Y = _out_list; Y && (Y->_out != out); Y = Y->_next);
+     if (! Y)
+     {
+ 	if (! create) return 0;
+-	Y = new Outnode;
++	Y = new Outnode (out, _parsize);
+ 	Y->_next = _out_list;
+ 	_out_list = Y;
+-	Y->_out = out;
+-	Y->_list = 0;
+-        for (i = 0; i < 3; i++)
+-	{
+-	    Y->_buff [i] = 0;
+-	}
+-        for (i = 0; i < 3; i++)
+-	{
+-	    Y->_buff [i] = (float *)(alloc_aligned (_parsize * sizeof (float)));
+-	}
+     }
+ 
+     for (M = Y->_list; M && (M->_inpn != X); M = M->_next);
+     if (! M)
+     {
+ 	if (! create) return 0;
+-	M = new Macnode;
++	M = new Macnode (X);
+ 	M->_next = Y->_list;
+ 	Y->_list = M;
+-	M->_inpn = X;
+-	M->_fftb = 0;
+-	M->_copy = false;
+     }
+ 
+     return M;
+@@ -955,8 +901,8 @@ Macnode *Convlevel::findmacnode (unsigned int inp, unsigned int out, bool create
+ 
+ void Convlevel::fftswap (fftwf_complex *p)
+ {
+-    unsigned int  n = _parsize;
+-    float         a, b;
++    uint32_t  n = _parsize;
++    float     a, b;
+ 
+     while (n)
+     {
+@@ -974,3 +920,98 @@ void Convlevel::fftswap (fftwf_complex *p)
+ #endif
+ 
+ 
++Inpnode::Inpnode (uint16_t inp):
++    _next (0),
++    _ffta (0),	
++    _npar (0),
++    _inp (inp)
++{
++}
++    
++
++Inpnode::~Inpnode (void)
++{
++    free_ffta ();
++}
++    
++
++void Inpnode::alloc_ffta (uint16_t npar, int32_t size)
++{
++    _npar = npar;
++    _ffta = new fftwf_complex * [_npar];
++    for (int i = 0; i < _npar; i++)
++    {
++        _ffta [i] = calloc_complex (size + 1);
++    }
++}
++
++
++void Inpnode::free_ffta (void)
++{
++    if (!_ffta) return;
++    for (uint16_t i = 0; i < _npar; i++)
++    {
++        fftwf_free ( _ffta [i]);
++    }
++    delete[] _ffta;
++    _ffta = 0;
++    _npar = 0;
++}
++
++
++Macnode::Macnode (Inpnode *inpn):
++    _next (0),
++    _inpn (inpn),
++    _link (0),
++    _fftb (0),
++    _npar (0)
++{}
++
++
++Macnode::~Macnode (void)
++{
++    free_fftb ();
++}
++
++
++void Macnode::alloc_fftb (uint16_t npar)
++{
++    _npar = npar;
++    _fftb = new fftwf_complex * [_npar];
++    for (uint16_t i = 0; i < _npar; i++)
++    {
++        _fftb [i] = 0;
++    }
++}
++
++
++void Macnode::free_fftb (void)
++{
++    if (!_fftb) return;
++    for (uint16_t i = 0; i < _npar; i++)
++    {
++        fftwf_free ( _fftb [i]);
++    }
++    delete[] _fftb;
++    _fftb = 0;
++    _npar = 0;
++}
++
++
++Outnode::Outnode (uint16_t out, int32_t size):
++    _next (0),
++    _list (0),
++    _out (out)
++{
++    _buff [0] = calloc_real (size);
++    _buff [1] = calloc_real (size);
++    _buff [2] = calloc_real (size);
++}
++    
++
++Outnode::~Outnode (void)
++{
++    fftwf_free (_buff [0]);
++    fftwf_free (_buff [1]);
++    fftwf_free (_buff [2]);
++}
+diff --git a/lib/zita-convolver-4.0.0/zita-convolver.h b/lib/zita-convolver-4.0.0/zita-convolver.h
+new file mode 100644
+index 0000000..0236bc0
+--- /dev/null
++++ b/lib/zita-convolver-4.0.0/zita-convolver.h
+@@ -0,0 +1,475 @@
++// ----------------------------------------------------------------------------
++//
++//  Copyright (C) 2006-2018 Fons Adriaensen <fons at 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 _ZITA_CONVOLVER_H
++#define _ZITA_CONVOLVER_H
++
++
++#include <pthread.h>
++#include <stdint.h>
++#include <fftw3.h>
++
++
++#define ZITA_CONVOLVER_MAJOR_VERSION 4
++#define ZITA_CONVOLVER_MINOR_VERSION 0
++
++
++extern int zita_convolver_major_version (void);
++extern int zita_convolver_minor_version (void);
++
++
++// ----------------------------------------------------------------------------
++
++
++#ifdef ZCSEMA_IS_IMPLEMENTED
++#undef ZCSEMA_IS_IMPLEMENTED
++#endif
++
++//XXX DZ: Hack for windows/osx10.5
++#include "zcsema-osx-win-compat.h"
++
++#if defined(__linux__)  || defined(__GNU__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
++
++#include <semaphore.h>
++
++class ZCsema
++{
++public:
++
++    ZCsema (void) { init (0, 0); }
++    ~ZCsema (void) { sem_destroy (&_sema); }
++
++    ZCsema (const ZCsema&); // disabled
++    ZCsema& operator= (const ZCsema&); // disabled
++
++    int init (int s, int v) { return sem_init (&_sema, s, v); }
++    int post (void) { return sem_post (&_sema); }
++    int wait (void) { return sem_wait (&_sema); }
++    int trywait (void) { return sem_trywait (&_sema); }
++
++private:
++
++    sem_t  _sema;
++};
++
++#define ZCSEMA_IS_IMPLEMENTED
++#endif
++
++
++#ifdef __APPLE__
++
++// NOTE:  ***** I DO NOT REPEAT NOT PROVIDE SUPPORT FOR OSX *****
++// 
++// The following code partially emulates the POSIX sem_t for which
++// OSX has only a crippled implementation. It may or may not compile,
++// and if it compiles it may or may not work correctly. Blame APPLE
++// for not following POSIX standards.
++
++class ZCsema
++{
++public:
++
++    ZCsema (void) : _count (0)
++    {
++        init (0, 0);
++    }
++
++    ~ZCsema (void)
++    {
++        pthread_mutex_destroy (&_mutex);
++        pthread_cond_destroy (&_cond);
++    }
++
++    ZCsema (const ZCsema&); // disabled
++    ZCsema& operator= (const ZCsema&); // disabled
++
++    int init (int s, int v)
++    {
++	_count = v;
++        return pthread_mutex_init (&_mutex, 0) || pthread_cond_init (&_cond, 0);
++    }
++
++    int post (void)
++    {
++	pthread_mutex_lock (&_mutex);
++	_count++;
++	if (_count == 1) pthread_cond_signal (&_cond);
++	pthread_mutex_unlock (&_mutex);
++	return 0;
++    }
++
++    int wait (void)
++    {
++	pthread_mutex_lock (&_mutex);
++	while (_count < 1) pthread_cond_wait (&_cond, &_mutex);
++	_count--;
++	pthread_mutex_unlock (&_mutex);
++	return 0;
++    }
++
++    int trywait (void)
++    {
++	if (pthread_mutex_trylock (&_mutex)) return -1;
++	if (_count < 1)
++	{
++	    pthread_mutex_unlock (&_mutex);
++	    return -1;
++	}
++        _count--;
++        pthread_mutex_unlock (&_mutex);
++        return 0;
++    }
++
++private:
++
++    int              _count;
++    pthread_mutex_t  _mutex;
++    pthread_cond_t   _cond;
++};
++
++#define ZCSEMA_IS_IMPLEMENTED
++#endif
++
++
++#ifndef ZCSEMA_IS_IMPLEMENTED
++#error "The ZCsema class is not implemented."
++#endif
++
++
++// ----------------------------------------------------------------------------
++
++
++class Inpnode   
++{
++private:
++
++    friend class Convlevel;
++
++    Inpnode (uint16_t inp);
++    ~Inpnode (void);
++    void alloc_ffta (uint16_t npar, int32_t size);
++    void free_ffta (void);
++    
++    Inpnode        *_next;
++    fftwf_complex **_ffta;
++    uint16_t        _npar;
++    uint16_t        _inp;
++};
++
++
++class Macnode  
++{
++private:
++
++    friend class Convlevel;
++
++    Macnode (Inpnode *inpn);
++    ~Macnode (void);
++    void alloc_fftb (uint16_t npar);
++    void free_fftb (void);
++
++    Macnode        *_next;
++    Inpnode        *_inpn;
++    Macnode        *_link;
++    fftwf_complex **_fftb;
++    uint16_t        _npar;
++};
++
++
++class Outnode   
++{
++private:
++
++    friend class Convlevel;
++
++    Outnode (uint16_t out, int32_t size);
++    ~Outnode (void);
++    
++    Outnode        *_next;
++    Macnode        *_list;
++    float          *_buff [3];
++    uint16_t        _out;
++};
++
++
++class Converror
++{
++public:
++
++    enum
++    {
++	BAD_STATE = -1,
++	BAD_PARAM = -2,
++        MEM_ALLOC = -3
++    };
++
++    Converror (int error) : _error (error) {}
++
++private:
++
++    int _error;
++};
++
++
++class Convlevel
++{
++private:
++
++    friend class Convproc;
++
++    enum 
++    {
++        OPT_FFTW_MEASURE = 1,
++        OPT_VECTOR_MODE  = 2,
++        OPT_LATE_CONTIN  = 4
++    };
++
++    enum
++    {
++        ST_IDLE,
++        ST_TERM,
++        ST_PROC
++    };
++
++    Convlevel (void);
++    ~Convlevel (void);
++
++    void configure (int      prio,
++                    uint32_t offs,
++                    uint32_t npar,
++                    uint32_t parsize,
++		    uint32_t options);
++
++    void impdata_write (uint32_t  inp,
++                        uint32_t  out,
++                        int32_t   step,
++                        float     *data,
++                        int32_t   ind0,
++                        int32_t   ind1,
++                        bool      create);
++
++    void impdata_clear (uint32_t  inp,
++	                uint32_t  out);
++
++    void impdata_link (uint32_t  inp1,
++                       uint32_t  out1,
++                       uint32_t  inp2,
++                       uint32_t  out2);
++
++    void reset (uint32_t  inpsize,
++                uint32_t  outsize,
++	        float     **inpbuff,
++	        float     **outbuff);
++
++    void start (int absprio, int policy);
++
++    void process (bool sync);
++
++    int  readout (bool sync, uint32_t skipcnt);
++
++    void stop (void);
++
++    void cleanup (void);
++
++    void fftswap (fftwf_complex *p);
++
++    void print (FILE *F);
++
++    static void *static_main (void *arg);
++
++    void main (void);
++
++    Macnode *findmacnode (uint32_t inp, uint32_t out, bool create);
++
++
++    volatile uint32_t   _stat;           // current processing state
++    int                 _prio;           // relative priority
++    uint32_t            _offs;           // offset from start of impulse response
++    uint32_t            _npar;           // number of partitions
++    uint32_t            _parsize;        // partition and outbut buffer size
++    uint32_t            _outsize;        // step size for output buffer
++    uint32_t            _outoffs;        // offset into output buffer
++    uint32_t            _inpsize;        // size of shared input buffer 
++    uint32_t            _inpoffs;        // offset into input buffer
++    uint32_t            _options;        // various options
++    uint32_t            _ptind;          // rotating partition index
++    uint32_t            _opind;          // rotating output buffer index
++    int                 _bits;           // bit identifiying this level
++    int                 _wait;           // number of unfinished cycles
++    pthread_t           _pthr;           // posix thread executing this level
++    ZCsema              _trig;           // sema used to trigger a cycle
++    ZCsema              _done;           // sema used to wait for a cycle
++    Inpnode            *_inp_list;       // linked list of active inputs
++    Outnode            *_out_list;       // linked list of active outputs
++    fftwf_plan          _plan_r2c;       // FFTW plan, forward FFT
++    fftwf_plan          _plan_c2r;       // FFTW plan, inverse FFT
++    float              *_time_data;      // workspace
++    float              *_prep_data;      // workspace
++    fftwf_complex      *_freq_data;      // workspace
++    float             **_inpbuff;        // array of shared input buffers
++    float             **_outbuff;        // array of shared output buffers
++};
++
++
++// ----------------------------------------------------------------------------
++
++
++class Convproc
++{
++public:
++
++    Convproc (void);
++    ~Convproc (void);
++
++    enum
++    {
++        ST_IDLE,
++	ST_STOP,
++        ST_WAIT,
++        ST_PROC
++    };
++
++    enum
++    {
++        FL_LATE = 0x0000FFFF,
++	FL_LOAD = 0x01000000
++    };
++
++    enum 
++    {
++        OPT_FFTW_MEASURE = Convlevel::OPT_FFTW_MEASURE, 
++        OPT_VECTOR_MODE  = Convlevel::OPT_VECTOR_MODE,
++        OPT_LATE_CONTIN  = Convlevel::OPT_LATE_CONTIN
++    };
++
++    enum
++    {
++	MAXINP   = 64,
++	MAXOUT   = 64,
++	MAXLEV   = 8,
++	MINPART  = 64,
++	MAXPART  = 8192,
++	MAXDIVIS = 16,
++	MINQUANT = 16,
++	MAXQUANT = 8192
++    };
++
++    uint32_t state (void) const
++    {
++	return _state;
++    }
++
++    float *inpdata (uint32_t inp) const
++    {
++	return _inpbuff [inp] + _inpoffs;
++    }
++
++    float *outdata (uint32_t out) const
++    {
++	return _outbuff [out] + _outoffs;
++    }
++
++    int configure (uint32_t  ninp,
++                   uint32_t  nout,
++                   uint32_t  maxsize,
++                   uint32_t  quantum,
++                   uint32_t  minpart,
++                   uint32_t  maxpart,
++		   float     density);
++
++    int impdata_create (uint32_t  inp,
++                        uint32_t  out,
++                        int32_t   step,
++                        float     *data,
++                        int32_t   ind0,
++                        int32_t   ind1); 
++
++    int impdata_clear (uint32_t  inp,
++	               uint32_t  out);
++
++    int impdata_update (uint32_t  inp,
++                        uint32_t  out,
++                        int32_t   step,
++                        float     *data,
++                        int32_t   ind0,
++                        int32_t   ind1); 
++
++    int impdata_link (uint32_t  inp1,
++                      uint32_t  out1,
++                      uint32_t  inp2,
++                      uint32_t  out2);
++
++    // Deprecated, use impdata_link() instead.
++    int impdata_copy (uint32_t  inp1,
++                      uint32_t  out1,
++                      uint32_t  inp2,
++                      uint32_t  out2)
++    {
++	return impdata_link (inp1, out1, inp2, out2);
++    }
++    
++    void set_options (uint32_t options);
++
++    void set_skipcnt (uint32_t skipcnt);
++
++    int  reset (void);
++
++    int  start_process (int abspri, int policy);
++
++    int  process (bool sync = false);
++
++    int  stop_process (void);
++
++    bool check_stop (void);
++
++    int  cleanup (void);
++
++    void print (FILE *F = stdout);
++
++private:
++
++    uint32_t    _state;                   // current state
++    float      *_inpbuff [MAXINP];        // input buffers
++    float      *_outbuff [MAXOUT];        // output buffers
++    uint32_t    _inpoffs;                 // current offset in input buffers
++    uint32_t    _outoffs;                 // current offset in output buffers
++    uint32_t    _options;                 // option bits
++    uint32_t    _skipcnt;                 // number of frames to skip 
++    uint32_t    _ninp;                    // number of inputs
++    uint32_t    _nout;                    // number of outputs
++    uint32_t    _quantum;                 // processing block size
++    uint32_t    _minpart;                 // smallest partition size
++    uint32_t    _maxpart;                 // largest allowed partition size
++    uint32_t    _nlevels;                 // number of partition sizes
++    uint32_t    _inpsize;                 // size of input buffers
++    uint32_t    _latecnt;                 // count of cycles ending too late
++    Convlevel  *_convlev [MAXLEV];        // array of processors 
++    void       *_dummy [64];
++
++    static float  _mac_cost;
++    static float  _fft_cost;
++};
++
++
++// ----------------------------------------------------------------------------
++
++
++#endif
++
+diff --git a/plugins/ZamHeadX2/Makefile b/plugins/ZamHeadX2/Makefile
+index c838293..8500534 100644
+--- a/plugins/ZamHeadX2/Makefile
++++ b/plugins/ZamHeadX2/Makefile
+@@ -13,7 +13,7 @@ NAME = ZamHeadX2
+ # Files to build
+ 
+ OBJS_DSP = \
+-	../../lib/zita-convolver-3.1.0/zita-convolver.cpp.o \
++	../../lib/zita-convolver-4.0.0/zita-convolver.cpp.o \
+ 	convolution.cpp.o \
+ 	ZamHeadX2Plugin.cpp.o
+ 
+diff --git a/plugins/ZamHeadX2/convolution.cpp b/plugins/ZamHeadX2/convolution.cpp
+index 81847e0..0026ba2 100644
+--- a/plugins/ZamHeadX2/convolution.cpp
++++ b/plugins/ZamHeadX2/convolution.cpp
+@@ -42,12 +42,12 @@
+ #include <pthread.h>
+ #include <assert.h>
+ 
+-#include "../../lib/zita-convolver-3.1.0/zita-convolver.h"
++#include "../../lib/zita-convolver-4.0.0/zita-convolver.h"
+ #include <samplerate.h>
+ #include "convolution.hpp"
+ 
+-#if ZITA_CONVOLVER_MAJOR_VERSION != 3
+-# error "This programs requires zita-convolver 3.x.x"
++#if ZITA_CONVOLVER_MAJOR_VERSION != 4
++# error "This programs requires zita-convolver 4.x.x"
+ #endif
+ 
+ #ifndef SRC_QUALITY
+@@ -557,7 +557,6 @@ int LV2convolv::clv_initialize (
+ 
+ 	convproc = new Convproc();
+ 	convproc->set_options (options);
+-	convproc->set_density (density);
+ 
+ 	float fir_coeffs_lr[400] = { 0 };
+ 	for (int i = 0; i < 200; i++) {
+@@ -600,7 +599,8 @@ int LV2convolv::clv_initialize (
+ 			/*max-convolution length */ max_size,
+ 			/*quantum*/  buffersize,
+ 			/*min-part*/ buffersize,
+-			/*max-part*/ buffersize
++			/*max-part*/ buffersize,
++			density
+ 			)) {
+ 		fprintf (stderr, "convolution: Cannot initialize convolution engine.\n");
+ 		goto errout;
+diff --git a/plugins/ZamHeadX2/convolution.hpp b/plugins/ZamHeadX2/convolution.hpp
+index ddf3d08..80be8e6 100644
+--- a/plugins/ZamHeadX2/convolution.hpp
++++ b/plugins/ZamHeadX2/convolution.hpp
+@@ -19,7 +19,7 @@
+ #ifndef CONVOLUTION_H_
+ #define CONVOLUTION_H_
+ 
+-#include "../../lib/zita-convolver-3.1.0/zita-convolver.h"
++#include "../../lib/zita-convolver-4.0.0/zita-convolver.h"
+ 
+ #define MAX_CHANNEL_MAPS (4)
+ #define VERBOSE_printf(x, ...)
+diff --git a/plugins/ZamVerb/Makefile b/plugins/ZamVerb/Makefile
+index 82c3bab..eacc080 100644
+--- a/plugins/ZamVerb/Makefile
++++ b/plugins/ZamVerb/Makefile
+@@ -16,7 +16,7 @@ OBJS_DSP = \
+ 	ZamVerbPlugin.cpp.o \
+ 	ZamVerbImpulses.cpp.o \
+ 	convolution.cpp.o \
+-	../../lib/zita-convolver-3.1.0/zita-convolver.cpp.o
++	../../lib/zita-convolver-4.0.0/zita-convolver.cpp.o
+ 
+ OBJS_UI  = \
+ 	ZamVerbArtwork.cpp.o \
+diff --git a/plugins/ZamVerb/convolution.cpp b/plugins/ZamVerb/convolution.cpp
+index 517a3cb..27374e0 100644
+--- a/plugins/ZamVerb/convolution.cpp
++++ b/plugins/ZamVerb/convolution.cpp
+@@ -42,13 +42,13 @@
+ #include <pthread.h>
+ #include <assert.h>
+ 
+-#include "../../lib/zita-convolver-3.1.0/zita-convolver.h"
++#include "../../lib/zita-convolver-4.0.0/zita-convolver.h"
+ #include <samplerate.h>
+ #include "convolution.hpp"
+ #include "ZamVerbImpulses.hpp"
+ 
+-#if ZITA_CONVOLVER_MAJOR_VERSION != 3
+-# error "This programs requires zita-convolver 3.x.x"
++#if ZITA_CONVOLVER_MAJOR_VERSION != 4
++# error "This programs requires zita-convolver 4.x.x"
+ #endif
+ 
+ #ifndef SRC_QUALITY
+@@ -295,7 +295,6 @@ int LV2convolv::clv_initialize (
+ 
+ 	convproc = new Convproc();
+ 	convproc->set_options (options);
+-	convproc->set_density (density);
+ /*
+ 	if (audiofile_read (ir_fn, sample_rate, &p, &n_chan, &n_frames)) {
+ 		fprintf(stderr, "convolution: failed to read IR.\n");
+@@ -337,7 +336,8 @@ int LV2convolv::clv_initialize (
+ 			/*max-convolution length */ max_size,
+ 			/*quantum*/  buffersize,
+ 			/*min-part*/ buffersize,
+-			/*max-part*/ buffersize
++			/*max-part*/ buffersize,
++			density
+ 			)) {
+ 		fprintf (stderr, "convolution: Cannot initialize convolution engine.\n");
+ 		goto errout;
+diff --git a/plugins/ZamVerb/convolution.hpp b/plugins/ZamVerb/convolution.hpp
+index 4eeada5..1c89971 100644
+--- a/plugins/ZamVerb/convolution.hpp
++++ b/plugins/ZamVerb/convolution.hpp
+@@ -19,7 +19,7 @@
+ #ifndef CONVOLUTION_H_
+ #define CONVOLUTION_H_
+ 
+-#include "../../lib/zita-convolver-3.1.0/zita-convolver.h"
++#include "../../lib/zita-convolver-4.0.0/zita-convolver.h"
+ 
+ #define MAX_CHANNEL_MAPS (4)
+ #define VERBOSE_printf(x, ...)
+-- 
+2.18.0
+



More information about the arch-commits mailing list