shithub: dumb

Download patch

ref: a57194a330f1ed2b44bb681e3d2c63880628f214
parent: 6c8eeb8a7b0e72c3de865d517ec0ff4778389315
author: Chris Moeller <kode54@gmail.com>
date: Sat Jan 12 10:59:36 EST 2013

- Simplified low-pass filter
- Eliminated accidentally applied resonance from low-pass filter
- Silenced a C89 error by adding a static cast

--- a/dumb/src/helpers/fir_resampler.c
+++ b/dumb/src/helpers/fir_resampler.c
@@ -59,8 +59,8 @@
     int read_pos, read_filled;
     unsigned short phase;
     unsigned int phase_inc;
-    float a0, a1, a2, b0, b1, b2;
-    float xn1, xn2, yn1, yn2;
+    float a1, a2, b02, b1;
+    float yn1, yn2;
     short buffer_in[fir_buffer_size * 2];
     int buffer_out[fir_buffer_size];
 } fir_resampler;
@@ -76,9 +76,8 @@
     r->read_filled = 0;
     r->phase = 0;
     r->phase_inc = 0;
-    r->a0 = 0; r->a1 = 0; r->a2 = 0;
-    r->b0 = 0; r->b1 = 0; r->b2 = 0;
-    r->xn1 = 0; r->xn2 = 0;
+    r->a1 = 0; r->a2 = 0;
+    r->b02 = 0; r->b1 = 0;
     r->yn1 = 0; r->yn2 = 0;
     memset( r->buffer_in, 0, sizeof(r->buffer_in) );
     memset( r->buffer_out, 0, sizeof(r->buffer_out) );
@@ -103,14 +102,10 @@
     r_out->read_filled = r_in->read_filled;
     r_out->phase = r_in->phase;
     r_out->phase_inc = r_in->phase_inc;
-    r_out->a0 = r_in->a0;
     r_out->a1 = r_in->a1;
     r_out->a2 = r_in->a2;
-    r_out->b0 = r_in->b0;
+    r_out->b02 = r_in->b02;
     r_out->b1 = r_in->b1;
-    r_out->b2 = r_in->b2;
-    r_out->xn1 = r_in->xn1;
-    r_out->xn2 = r_in->xn2;
     r_out->yn1 = r_in->yn1;
     r_out->yn2 = r_in->yn2;
     memcpy( r_out->buffer_in, r_in->buffer_in, sizeof(r_in->buffer_in) );
@@ -139,8 +134,6 @@
     r->read_pos = 0;
     r->read_filled = 0;
     r->phase = 0;
-    r->xn1 = 0;
-    r->xn2 = 0;
     r->yn1 = 0;
     r->yn2 = 0;
     memset( r->buffer_in, 0, sizeof(r->buffer_in) );
@@ -155,14 +148,15 @@
         double omega = 2 * PI * 0.5 / new_factor;
         double cs = cos(omega);
         double sn = sin(omega);
-        double a1pha = sn / 20.0;
+        double alpha = sn / 2.0;
+        double a0_inv = 1.0 / (1.0 + alpha);
 
-        r->b0 =  (1.0 - cs) / 2.0 ;
-        r->b1 =   1.0 - cs ;
-        r->b2 =  (1.0 - cs) / 2.0 ;
-        r->a0 =   1.0 + a1pha ;
-        r->a1 =  -2.0 * cs ;
-        r->a2 =   1.0 - a1pha ;
+        double b1_temp = (1.0 - cs) * a0_inv;
+
+        r->b02 = b1_temp * 0.5;
+        r->b1 =  b1_temp;
+        r->a1 =  -2.0 * cs * a0_inv;
+        r->a2 =  (1.0 - alpha) * a0_inv;
     }
 }
 
@@ -174,14 +168,14 @@
 	{
         if ( r->phase_inc > 65536 )
         {
+            /* The filter is implemented in Direct-II form. */
             int s32;
-            float in, out;
+            float in, out, dsp_centernode;
             in = s;
-            out = (r->b0 * in + r->b1 * r->xn1 + r->b2 * r->xn2 - r->a1 * r->yn1 - r->a2 * r->yn2) / r->a0;
-            r->xn2 = r->xn1;
-            r->xn1 = in;
+            dsp_centernode = in - r->a1 * r->yn1 - r->a2 * r->yn2;
+            out = r->b02 * (dsp_centernode + r->yn2) + r->b1 * r->yn1;
             r->yn2 = r->yn1;
-            r->yn1 = out;
+            r->yn1 = dsp_centernode;
             s32 = out;
             if ( (unsigned)(s32 + 0x8000) >= 0x10000 ) s32 = (s32 >> 31) ^ 0x7FFF;
             s = (short) s32;
@@ -210,7 +204,7 @@
     double const filter = (ratio_ < 1.0) ? 1.0 : 1.0 / ratio_;
     double pos = 0.0;
     //int input_per_cycle = 0;
-    short* out = fir_impulses;
+    short* out = (short*) fir_impulses;
     int n;
     for ( n = res; --n >= 0; )
     {