resampler: better bessel function

Applied fix from RBJ to Bessel polynomial.
Benchmarked various implementations.
Chose HyperbolicCosineWindow because it is faster to compute and cleaner.
diff --git a/src/flowgraph/resampler/BesselFunctionRBJ.h b/src/flowgraph/resampler/BesselFunctionRBJ.h
index 8dc6aaa..de6200b 100644
--- a/src/flowgraph/resampler/BesselFunctionRBJ.h
+++ b/src/flowgraph/resampler/BesselFunctionRBJ.h
@@ -31,12 +31,12 @@
      * Higher K gives higher precision.
      * @param K number of terms in the polynomial expansion
      */
-    BesselFunctionRBJ(int K = 8)
+    BesselFunctionRBJ(int K = 20)
     : mK(K) {
         mCoefficients = std::make_unique<double[]>(K + 1);
         mCoefficients[0] = 1.0;
         for (int64_t k = 1; k <= K; k++) {
-            mCoefficients[k] = mCoefficients[k - 1] * -0.25 / (k * k);
+            mCoefficients[k] = mCoefficients[k - 1] * 0.25 / (k * k);
         }
     }
 
@@ -53,8 +53,8 @@
     }
 
     // Direct summation of the first K terms.
-    double direct(double x, int K) {
-        double z = x * x * -0.25;
+    double direct(double x, int K = 20) {
+        double z = x * x * 0.25;
         double sum = 0.0;
         for (int k = K; k >= 1; k--) {
             int n = k;
diff --git a/src/flowgraph/resampler/KaiserWindow.h b/src/flowgraph/resampler/KaiserWindow.h
index f45aced..9232917 100644
--- a/src/flowgraph/resampler/KaiserWindow.h
+++ b/src/flowgraph/resampler/KaiserWindow.h
@@ -17,11 +17,10 @@
 #ifndef RESAMPLER_KAISER_WINDOW_H
 #define RESAMPLER_KAISER_WINDOW_H
 
-#include "Math.h"
+#include <math.h>
 
 namespace resampler {
 
-
 /**
  * Calculate a Kaiser window centered at 0.
  */
@@ -62,6 +61,10 @@
         return bessel(w) * mInverseBesselBeta;
     }
 
+    // Approximation of a
+    // modified zero order Bessel function of the first kind.
+    // Based on:
+    // https://dsp.stackexchange.com/questions/37714/kaiser-window-approximation
     static double bessel(double x) {
         double y = cosh(0.970941817426052 * x);
         y += cosh(0.8854560256532099 * x);
diff --git a/src/flowgraph/resampler/MultiChannelResampler.cpp b/src/flowgraph/resampler/MultiChannelResampler.cpp
index 2eca588..c35cf04 100644
--- a/src/flowgraph/resampler/MultiChannelResampler.cpp
+++ b/src/flowgraph/resampler/MultiChannelResampler.cpp
@@ -112,12 +112,6 @@
     }
 }
 
-float MultiChannelResampler::hammingWindow(float radians, float spread) {
-    const float alpha = 0.54f;
-    const float windowPhase = radians / spread;
-    return (float) (alpha + ((1.0 - alpha) * cosf(windowPhase)));
-}
-
 float MultiChannelResampler::sinc(float radians) {
     if (abs(radians) < 1.0e-9) return 1.0f;   // avoid divide by zero
     return sinf(radians) / radians;   // Sinc function
@@ -139,14 +133,19 @@
              ? ((float)outputRate / inputRate)
              : ((float)inputRate / outputRate));
     const int numTapsHalf = getNumTaps() / 2; // numTaps must be even.
+    const float numTapsHalfInverse = 1.0f / numTapsHalf;
     for (int i = 0; i < numRows; i++) {
         float tapPhase = phase - numTapsHalf;
         float gain = 0.0; // sum of raw coefficients
         int gainCursor = coefficientIndex;
         for (int tap = 0; tap < getNumTaps(); tap++) {
             float radians = tapPhase * M_PI;
-            float window = mCoshWindow(tapPhase / numTapsHalf);
-            // float window = hammingWindow(radians, numTapsHalf);
+
+#if MCR_USE_KAISER
+            float window = mKaiserWindow(tapPhase * numTapsHalfInverse);
+#else
+            float window = mCoshWindow(tapPhase * numTapsHalfInverse);
+#endif
             float coefficient = sinc(radians * cutoffScaler) * window;
             mCoefficients.at(coefficientIndex++) = coefficient;
             gain += coefficient;
@@ -161,7 +160,6 @@
         float gainCorrection = 1.0 / gain; // normalize the gain
         for (int tap = 0; tap < getNumTaps(); tap++) {
             mCoefficients.at(gainCursor + tap) *= gainCorrection;
-//            printf("%d, %8.5f\n", tap, mCoefficients.at(gainCursor + tap));
         }
     }
 }
diff --git a/src/flowgraph/resampler/MultiChannelResampler.h b/src/flowgraph/resampler/MultiChannelResampler.h
index 932af41..31ff2c0 100644
--- a/src/flowgraph/resampler/MultiChannelResampler.h
+++ b/src/flowgraph/resampler/MultiChannelResampler.h
@@ -22,7 +22,15 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#ifndef MCR_USE_KAISER
+#define MCR_USE_KAISER 0
+#endif
+
+#if MCR_USE_KAISER
+#include "KaiserWindow.h"
+#else
 #include "HyperbolicCosineWindow.h"
+#endif
 
 namespace resampler {
 
@@ -191,12 +199,6 @@
     explicit MultiChannelResampler(const MultiChannelResampler::Builder &builder);
 
     /**
-     * @param phase between 0.0 and  2*spread // TODO use centered phase, maybe
-     * @return windowedSinc
-     */
-    // static float calculateWindowedSinc(float phase, int spread); // TODO remove
-
-    /**
      * Write a frame containing N samples.
      * Call advanceWrite() after calling this.
      * @param frame pointer to the first sample in a frame
@@ -251,7 +253,11 @@
 
 private:
 
+#if MCR_USE_KAISER
+    KaiserWindow           mKaiserWindow;
+#else
     HyperbolicCosineWindow mCoshWindow;
+#endif
 
     // max coefficients for polyphase filter
     static constexpr float kDefaultNormalizedCutoff = 0.70f;