r4065 - in trunk/bse: . tests



Author: timj
Date: 2006-11-04 14:14:35 -0500 (Sat, 04 Nov 2006)
New Revision: 4065

Modified:
   trunk/bse/ChangeLog
   trunk/bse/bsefilter-ellf.c
   trunk/bse/bsemath.h
   trunk/bse/tests/filtertest.cc
Log:
Sat Nov  4 20:09:33 2006  Tim Janik  <timj gtk org>

        * bsefilter-ellf.c: removed ellf-behavior special casing. switched
        to higher precision constants. substituted bsemath.h constants.

        * bsemath.h: provide ln(4), decibel10 and decibel20 factors.




Modified: trunk/bse/ChangeLog
===================================================================
--- trunk/bse/ChangeLog	2006-11-04 18:47:17 UTC (rev 4064)
+++ trunk/bse/ChangeLog	2006-11-04 19:14:35 UTC (rev 4065)
@@ -1,3 +1,10 @@
+Sat Nov  4 20:09:33 2006  Tim Janik  <timj gtk org>
+
+	* bsefilter-ellf.c: removed ellf-behavior special casing. switched
+	to higher precision constants. substituted bsemath.h constants.
+
+	* bsemath.h: provide ln(4), decibel10 and decibel20 factors.
+
 Sat Nov  4 19:46:01 2006  Tim Janik  <timj gtk org>
 
 	* bsefilter-ellf.c: replaced all ellf specific complex number 

Modified: trunk/bse/bsefilter-ellf.c
===================================================================
--- trunk/bse/bsefilter-ellf.c	2006-11-04 18:47:17 UTC (rev 4064)
+++ trunk/bse/bsefilter-ellf.c	2006-11-04 19:14:35 UTC (rev 4065)
@@ -23,62 +23,9 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
-
-
-#ifndef ELLF_BEHAVIOR
 #include "bsefilter.h"
 
-#else
-
-#include <stdbool.h> // FIXME
-#include <complex.h>
-// typedef unsigned int uint;
-typedef _Complex double Complex;
-
-typedef enum {
-  BSE_IIR_FILTER_BUTTERWORTH = 1,
-  BSE_IIR_FILTER_BESSEL      = 2,
-  BSE_IIR_FILTER_CHEBYSHEV1  = 3,
-  BSE_IIR_FILTER_CHEBYSHEV2  = 4,
-  BSE_IIR_FILTER_ELLIPTIC    = 5,
-} BseIIRFilterKind;
-
-typedef enum {
-  BSE_IIR_FILTER_LOW_PASS    = 1,
-  BSE_IIR_FILTER_BAND_PASS   = 2,
-  BSE_IIR_FILTER_HIGH_PASS   = 3,
-  BSE_IIR_FILTER_BAND_STOP   = 4,
-} BseIIRFilterType;
-
 typedef struct {
-  BseIIRFilterKind      kind;
-  BseIIRFilterType      type;
-  uint                  order;                  /*     >= 1 */
-  double                sampling_frequency;     /* Hz, > 0.0 && == 2 * nyquist_frequency */
-  double                passband_edge;          /* Hz, > 0.0 && < nyquist_frequency */
-  double                passband_ripple_db;     /* dB, > 0.0, not Butterworth */
-  double                passband_edge2;         /* Hz, > 0.0 && < nyquist_frequency, for BAND filters */
-  double                stopband_edge;          /* Hz, > 0.0, replaces stopband_db, elliptic only */
-  double                stopband_db;            /* dB, < 0.0, elliptic only */
-} BseIIRFilterRequest;
-
-#define BSE_IIR_MAX_ORDER               (64)
-#define BSE_IIR_CARRAY_SIZE             (4 * BSE_IIR_MAX_ORDER + 2) /* size of arrays used to store coefficients */
-
-typedef struct {
-  uint    order;
-  double  sampling_frequency;
-  /* z-plane poles and zeros */
-  double  gain;
-  Complex zp[BSE_IIR_CARRAY_SIZE / 2];  /* z-plane poles [order] */
-  Complex zz[BSE_IIR_CARRAY_SIZE / 2];  /* z-plane zeros [order] */
-  /* normalized z-plane transfer function */
-  double  zn[BSE_IIR_CARRAY_SIZE];      /* numerator coefficients [order+1] */
-  double  zd[BSE_IIR_CARRAY_SIZE];      /* denominator coefficients [order+1] */
-} BseIIRFilterDesign;
-#endif
-
-typedef struct {
   int    n_poles;
   int    n_zeros;
   int    z_counter;	/* incremented as z^N coefficients are found, indexes poles and zeros */
@@ -113,39 +60,10 @@
   double  zd[BSE_IIR_CARRAY_SIZE];              /* denominator coefficients [order+1] */
 } EllfDesignState;
 
-#if 0 // precision
-//#include "bseieee754.h"
-#define PI                            (3.141592653589793238462643383279502884197)    // pi
-#define BSE_PI_DIV_2                  (1.570796326794896619231321691639751442099)    // pi/2
-#define BSE_DOUBLE_EPSILON       (1.1102230246251565404236316680908203125e-16) /* 2^-53, round-off error at 1.0 */
-#define BSE_DOUBLE_MAX_NORMAL    (1.7976931348623157e+308) /* 7fefffff ffffffff, 2^1024 * (1 - BSE_DOUBLE_EPSILON) */
-
-
-
-
-#define DECIBELL_FACTOR         (4.3429448190325182765112891891661)     /* 10.0 / ln (10.0) */
 #define MACHEP                  (BSE_DOUBLE_EPSILON)                    /* the machine roundoff error */
-// #define PI                   /* PI is defined in bseieee754.h */
 #define PIO2                    (BSE_PI_DIV_2)                          /* pi/2 */
 #define MAXNUM                  (BSE_DOUBLE_MAX_NORMAL)                 /* 2**1024*(1-MACHEP) */
 
-#else
-
-static double DECIBELL_FACTOR = -1;
-static void
-init_constants (void)
-{
-  DECIBELL_FACTOR = 10.0 / log (10.0);
-}
-static const double MAXNUM =  1.79769313486231570815E308;    /* 2**1024*(1-MACHEP) */
-#undef PI
-static const double PI     =  3.14159265358979323846;       /* pi */
-static const double PIO2   =  1.57079632679489661923;       /* pi/2 */
-static const double MACHEP =  1.11022302462515654042E-16;   /* 2**-53 */
-#endif
-
-
-
 #if 0
 #define error_printf(...)       fprintf (stderr, __VA_ARGS__)
 #define ellf_debugf(...)        fprintf (stderr, __VA_ARGS__)
@@ -161,14 +79,10 @@
 static const char* ellf_filter_design (const BseIIRFilterRequest *ifr,
                                        EllfDesignState           *ds);
 
-
-#ifndef ELLF_BEHAVIOR
-
 bool
 _bse_filter_design_ellf (const BseIIRFilterRequest      *ifr,
                          BseIIRFilterDesign             *fid)
 {
-  init_constants();
   EllfDesignState ds = { 0, };
   const char *errmsg = ellf_filter_design (ifr, &ds);
   fflush (stdout);
@@ -207,66 +121,6 @@
   return true;
 }
 
-#else
-
-static double
-my_getnum (const char *text)
-{
-  ellf_inputf ("%s ? ", text);
-  char s[4096];
-  if (!fgets (s, sizeof (s), stdin))
-    exit (0);
-  double val = 0;
-  sscanf (s, "%lf", &val);
-  return val;
-}
-
-int
-main (int   argc,
-      char *argv[])
-{
-  init_constants();
-  BseIIRFilterRequest ifr = { 0 };
-  EllfDesignState ds = { .stopband_edge = 2400, };
-  switch ((int) my_getnum ("kind"))
-    {
-    case 1: ifr.kind = BSE_IIR_FILTER_BUTTERWORTH; break;
-    case 2: ifr.kind = BSE_IIR_FILTER_CHEBYSHEV1;  break;
-    case 3: ifr.kind = BSE_IIR_FILTER_ELLIPTIC;    break;
-    default: return 1;
-    }
-  ifr.type = my_getnum ("type");
-  ifr.order = my_getnum ("order");
-  if (ifr.kind != BSE_IIR_FILTER_BUTTERWORTH) /* not Butterworth */
-    ifr.passband_ripple_db = my_getnum ("passband_ripple_db");
-  ifr.sampling_frequency = my_getnum ("sampling_frequency");
-  ifr.passband_edge = my_getnum ("passband_edge");
-  if (ifr.type == BSE_IIR_FILTER_BAND_PASS ||
-      ifr.type == BSE_IIR_FILTER_BAND_STOP)
-    ifr.passband_edge2 = my_getnum ("passband_edge2");
-  if (ifr.kind == BSE_IIR_FILTER_ELLIPTIC)
-    ifr.stopband_db = ifr.stopband_edge = my_getnum ("stopband_edge or stopband_db");
-  ellf_inputf ("\n");
-  const char *errmsg = ellf_filter_design (&ifr, &ds);
-  fflush (stdout);
-  fflush (stderr);
-  // ellf_debugf ("DEBUG: %.20g %.20g %.20g %.20g %.20g\n", a, cos(a), cang, ds->cgam, 0.);
-  if (errmsg)
-    {
-      error_printf (stderr, "Invalid specification: %s\n", errmsg);
-      fflush (stderr);
-      return 1;
-    }
-  
-  return 0;
-}
-
-/* compile with: gcc -Wall -O2 -g -ffloat-store -DELLF_BEHAVIOR bsefilter-ellf.c -lm -o bsefilter-ellf
- * (using -ffloat-store for ellf.c compatibility)
- */
-
-#endif
-
 /* This code calculates design coefficients for
  * digital filters of the Butterworth, Chebyshev, or
  * elliptic varieties.
@@ -327,7 +181,6 @@
  */
 
 /* --- prototypes --- */
-static double polevl (double x, const double coef[], int N);
 static double ellik  (double phi, double m); // incomplete elliptic integral of the first kind
 static double ellpk  (double x); // complete elliptic integral of the first kind
 static int    ellpj  (double u, double m, double *sn, double *cn, double *dn, double *ph); // Jacobian Elliptic Functions
@@ -395,7 +248,7 @@
    * which is supposed to be the name of the
    * function in which the error occurred:
    */
-  error_printf ("\n%s ", name); // FIXME
+  error_printf ("\n%s ", name);
   
   /* Set global error message word */
   math_global_error = code;
@@ -644,6 +497,47 @@
   return 0;
 }
 
+/* polevl - Evaluate polynomial
+ *
+ * SYNOPSIS:
+ * int N;
+ * double x, y, coef[N+1], polevl[];
+ * y = polevl(x, coef, N);
+ *
+ * DESCRIPTION:
+ * Evaluates polynomial of degree N:
+ *                     2          N
+ * y  =  C  + C x + C x  +...+ C x
+ *        0    1     2          N
+ *
+ * Coefficients are stored in reverse order:
+ * coef[0] = C  , ..., coef[N] = C  .
+ *            N                   0
+ * SPEED:
+ * In the interest of speed, there are no checks for out
+ * of bounds arithmetic.  This routine is used by most of
+ * the functions in the library.  Depending on available
+ * equipment features, the user may wish to rewrite the
+ * program in microcode or assembly language.
+ */
+static inline double
+polevl (double x, const double coef[], int N)
+{
+  double ans;
+  int i;
+  const double *p;
+  
+  p = coef;
+  ans = *p++;
+  i = N;
+  
+  do
+    ans = ans * x  +  *p++;
+  while (--i);
+  
+  return ans;
+}
+
 /* ellpk - Complete elliptic integral of the first kind
  *
  * SYNOPSIS:
@@ -707,7 +601,6 @@
     1.24999999999870820058E-1,
     4.99999999999999999821E-1
   };
-  static const double C1_ellpk = 1.3862943611198906188E0; /* log(4) */
 
   if ((x < 0.0) || (x > 1.0))
     {
@@ -728,7 +621,8 @@
         }
       else
         {
-          return C1_ellpk - 0.5 * log (x);
+          /* C1 = ln(4) */
+          return BSE_LN4 - 0.5 * log (x); /* C1 - 0.5 * log (x) */
         }
     }
 }
@@ -777,66 +671,7 @@
   return a;
 }
 
-/* --- misc utilities --- */
-/* polevl - Evaluate polynomial
- *
- * SYNOPSIS:
- * int N;
- * double x, y, coef[N+1], polevl[];
- * y = polevl(x, coef, N);
- *
- * DESCRIPTION:
- * Evaluates polynomial of degree N:
- *                     2          N
- * y  =  C  + C x + C x  +...+ C x
- *        0    1     2          N
- *
- * Coefficients are stored in reverse order:
- * coef[0] = C  , ..., coef[N] = C  .
- *            N                   0
- * SPEED:
- * In the interest of speed, there are no checks for out
- * of bounds arithmetic.  This routine is used by most of
- * the functions in the library.  Depending on available
- * equipment features, the user may wish to rewrite the
- * program in microcode or assembly language.
- */
-static double
-polevl (double x, const double coef[], int N)
-{
-  double ans;
-  int i;
-  const double *p;
-  
-  p = coef;
-  ans = *p++;
-  i = N;
-  
-  do
-    ans = ans * x  +  *p++;
-  while (--i);
-  
-  return ans;
-}
-
 /* --- filter design functions --- */
-static void
-print_z_fraction_before_zplnc (const BseIIRFilterRequest *ifr,
-                               EllfDesignState           *ds) /* must be called *before* zplnc() */
-{
-  double zgain;
-  if ((ifr->kind == BSE_IIR_FILTER_BUTTERWORTH || ifr->kind == BSE_IIR_FILTER_CHEBYSHEV1) && ds->numerator_accu == 0)
-    zgain = 1.0;
-  else
-    zgain = ds->denominator_accu / (ds->numerator_accu * ds->gain_scale);
-  ellf_outputf ("# constant mygain factor %23.13E\n", zgain); // BSE info
-  ellf_outputf ("# z plane Denominator      Numerator\n"); // BSE info
-  int j;
-  for (j = 0; j <= ds->n_solved_poles; j++)
-    ellf_outputf ("# %2d %17.9E %17.9E\n", j, ds->zd[j], ds->zn[j] * zgain); // BSE info
-}
-
-
 static int
 find_elliptic_locations_in_lambda_plane (const BseIIRFilterRequest *ifr,
                                          EllfDesignState           *ds)
@@ -1501,7 +1336,7 @@
       if (r <= 0.0)
         r = -999.99;
       else
-        r = 2.0 * DECIBELL_FACTOR * log (r);
+        r = BSE_DECIBEL20_FACTOR * log (r);
       ellf_debugf ("%10.1f  %10.2f\n", f, r);
       // f = f + 0.05 * ds->nyquist_frequency;
     }
@@ -1534,7 +1369,7 @@
       if (ifr->kind == BSE_IIR_FILTER_CHEBYSHEV1)
         {
           /* For Chebyshev filter, ripples go from 1.0 to 1/sqrt(1+ds->ripple_epsilon^2) */
-          ds->chebyshev_phi = exp (0.5 * ifr->passband_ripple_db / DECIBELL_FACTOR);
+          ds->chebyshev_phi = exp (ifr->passband_ripple_db / BSE_DECIBEL20_FACTOR);
 
           if ((ifr->order & 1) == 0)
             ds->gain_scale = ds->chebyshev_phi;
@@ -1543,7 +1378,7 @@
         }
       else
         { /* elliptic */
-          ds->ripple_epsilon = exp (ifr->passband_ripple_db / DECIBELL_FACTOR);
+          ds->ripple_epsilon = exp (ifr->passband_ripple_db / BSE_DECIBEL10_FACTOR);
           ds->gain_scale = 1.0;
           if ((ifr->order & 1) == 0)
             ds->gain_scale = sqrt (ds->ripple_epsilon);
@@ -1614,7 +1449,7 @@
         return "need stopband_db or stopband_edge";
       else /* stopband_db < 0.0 */
         { /* calculate band edge from db down */
-          double a = exp (-ifr->stopband_db / DECIBELL_FACTOR);
+          double a = exp (-ifr->stopband_db / BSE_DECIBEL10_FACTOR);
           double m1 = ds->ripple_epsilon / sqrt (a - 1.0);
           m1 *= m1;
           double m1p = 1.0 - m1;
@@ -1763,7 +1598,6 @@
   // volatile_sink ("x");
   z_plane_zeros_poles_to_numerator_denomerator (ifr, ds);
   ellf_debugf ("an=%.20g pn=%.20g scale=%.20g\n", ds->denominator_accu, ds->numerator_accu, ds->gain_scale); // BSE info
-  print_z_fraction_before_zplnc (ifr, ds);
   gainscale_and_print_deno_nume_zeros2_poles2 (ifr, ds);
   print_filter_table (ifr, ds); /* tabulate transfer function */
   return NULL;

Modified: trunk/bse/bsemath.h
===================================================================
--- trunk/bse/bsemath.h	2006-11-04 18:47:17 UTC (rev 4064)
+++ trunk/bse/bsemath.h	2006-11-04 19:14:35 UTC (rev 4065)
@@ -39,6 +39,7 @@
 #define BSE_LN2                       (0.6931471805599453094172321214581765680755)   // ln(2)
 #define BSE_SQRT2                     (1.41421356237309504880168872420969807857)     // sqrt(2)
 #define BSE_1_DIV_SQRT2               (0.7071067811865475244008443621048490392848)   // 1/sqrt(2)
+#define BSE_LN4                       (1.386294361119890618834464242916353136151)    // ln(4)
 #define BSE_LN10                      (2.302585092994045684017991454684364207601)    // ln(10)
 #define BSE_LOG2_10                   (3.321928094887362347870319429489390175865)    // log_2(10)
 #define BSE_LOG2POW20_10              (0.1660964047443681173935159714744695087932)   // log_2(10)/20
@@ -47,6 +48,8 @@
 #define BSE_LN_2_POW_1_DIV_1200_d     (5.776226504666210911810267678818138067296e-4) // ln(2^(1/1200))
 #define BSE_2_POW_1_DIV_72            (1.009673533228510862192521401118605073603)    // 2^(1/72)
 #define BSE_LN_2_POW_1_DIV_72         (9.62704417444368485301711279803023011216e-3)  // ln(2^(1/72))
+#define BSE_DECIBEL20_FACTOR          (8.68588963806503655302257837833210164588794)  // 20.0 / ln (10.0)
+#define BSE_DECIBEL10_FACTOR          (4.34294481903251827651128918916605082294397)  // 10.0 / ln (10.0)
 #define BSE_COMPLEX_ONE               (bse_complex (1, 0))
 
 /* --- structures --- */

Modified: trunk/bse/tests/filtertest.cc
===================================================================
--- trunk/bse/tests/filtertest.cc	2006-11-04 18:47:17 UTC (rev 4064)
+++ trunk/bse/tests/filtertest.cc	2006-11-04 19:14:35 UTC (rev 4065)
@@ -85,8 +85,7 @@
 static double
 to_db (double response)
 {
-  const double decibel20 = 8.6858896380650365530225783783321; /* 20.0 / ln (10.0) */
-  return response <= 0.0 ? -999.99 : max (decibel20 * log (response), -999.99);
+  return response <= 0.0 ? -999.99 : max (BSE_DECIBEL20_FACTOR * log (response), -999.99);
 }
 
 static double




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]