changeset 3495:cc1c879533ee

tweaked surround lowpass filter, included some new test code
author steve
date Fri, 14 Dec 2001 21:25:49 +0000
parents fb9de639ed30
children 5c8a533dfa09
files libao2/firfilter.c libao2/pl_surround.c
diffstat 2 files changed, 81 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/libao2/firfilter.c	Fri Dec 14 20:45:30 2001 +0000
+++ b/libao2/firfilter.c	Fri Dec 14 21:25:49 2001 +0000
@@ -1,6 +1,8 @@
+
+#include <math.h>
 
 static double desired_7kHz_lowpass[] = {1.0, 0.0};
-static double weights_7kHz_lowpass[] = {0.1, 0.1};
+static double weights_7kHz_lowpass[] = {0.2, 2.0};
 
 double *calc_coefficients_7kHz_lowpass(int rate)
 {
@@ -18,16 +20,20 @@
 
 #if 0
 
-int16_t firfilter(int16_t *buf, int pos, int len, int count, double *coefficients)
-{
-  double result = 0.0;
+static double desired_125Hz_lowpass[] = {1.0, 0.0};
+static double weights_125Hz_lowpass[] = {0.2, 2.0};
 
-  // Back 32 samples, maybe wrapping in buffer.
-  pos = (pos+len-count)%len;
-  // And do the multiply-accumulate
-  while (count--) {
-    result += buf[pos++] * *coefficients++;  pos %= len;
-  }
+double *calc_coefficients_125Hz_lowpass(int rate)
+{
+  double *result = (double *)malloc(256*sizeof(double));
+  double bands[4];
+
+  bands[0] = 0.0;  bands[1] = 125.0/rate;
+  bands[2] = 175.0/rate;  bands[3] = 0.5;
+
+  remez(result, 256, 2, bands,
+	desired_125Hz_lowpass, weights_125Hz_lowpass, BANDPASS);
+
   return result;
 }
 
@@ -57,3 +63,59 @@
   while (count2--)  result += *buf++ * *coefficients++;
   return result;
 }
+
+void dump_filter_coefficients(double *coefficients)
+{
+  int i;
+  fprintf(stderr, "pl_surround: Filter coefficients are: \n");
+  for (i=0; (i<32); i++) {
+    fprintf(stderr, "  [%2d]: %23.20f\n", i, coefficients[i]);
+  }
+}
+
+#ifdef TESTING
+
+#define PI 3.1415926536
+
+// For testing purposes, fill a buffer with some sine-wave tone
+void sinewave(int16_t *output, int samples, int incr, int freq, double phase, int samplerate)
+{
+  double radians_per_sample = 2*PI / ((0.0+samplerate) / freq), r;
+
+  //fprintf(stderr, "samples=%d tone freq=%d, samplerate=%d, radians/sample=%f\n",
+  //	  samples, freq, samplerate, radians_per_sample);
+  r = phase;
+  while (samples--) {
+    *output = sin(r)*10000;  output = &output[incr];
+    r += radians_per_sample;
+  }
+}
+
+// Pass various frequencies through a FIR filter and report amplitudes
+void testfilter(double *coefficients, int count, int samplerate)
+{
+  int16_t wavein[8192]; //, waveout[2048];
+  int sample, samples, maxsample, minsample, totsample;
+  int nyquist=samplerate/2;
+  int freq, i;
+
+  for (freq=25; freq<nyquist; freq+=25) {
+    // Make input tone
+    sinewave(wavein, 8192, 1, freq, 0.0, samplerate);
+    //for (i=0; i<32; i++)
+    //  fprintf(stderr, "%5d\n", wavein[i]);
+    // Filter through the filter, measure results
+    maxsample=0;  minsample=1000000;  totsample=0;  samples=0;
+    for (i=2048; i<8192; i++) {
+      //waveout[i] = wavein[i];
+      sample = abs(firfilter(wavein, i, 8192, count, coefficients));
+      if (sample > maxsample) maxsample=sample;
+      if (sample < minsample) minsample=sample;
+      totsample += sample;  samples++;
+    }
+    // Report results
+    fprintf(stderr, "%5d  %5d  %5d  %5d  %f\n", freq, totsample/samples, maxsample, minsample, 10*log((totsample/samples)/6500.0));
+  }
+}
+
+#endif
--- a/libao2/pl_surround.c	Fri Dec 14 20:45:30 2001 +0000
+++ b/libao2/pl_surround.c	Fri Dec 14 21:25:49 2001 +0000
@@ -115,7 +115,8 @@
   ao_plugin_data.sz_mult    /= 2;
 
   // Figure out buffer space (in int16_ts) needed for the 15msec delay
-  pl_surround.delaybuf_len = (pl_surround.rate * pl_surround.msecs / 1000);
+  // Extra 31 samples allow for lowpass filter delay (taps-1)
+  pl_surround.delaybuf_len = (pl_surround.rate * pl_surround.msecs / 1000) + 31;
   // Allocate delay buffers
   pl_surround.Ls_delaybuf=(void*)calloc(pl_surround.delaybuf_len,sizeof(int16_t));
   pl_surround.Rs_delaybuf=(void*)calloc(pl_surround.delaybuf_len,sizeof(int16_t));
@@ -124,7 +125,8 @@
   pl_surround.delaybuf_pos = 0;
   // Surround filer coefficients
   pl_surround.filter_coefs_surround = calc_coefficients_7kHz_lowpass(pl_surround.rate);
-
+  //dump_filter_coefficients(pl_surround.filter_coefs_surround);
+  //testfilter(pl_surround.filter_coefs_surround, 32, pl_surround.rate);
   return 1;
 }
 
@@ -164,8 +166,12 @@
   // fprintf(stderr, "pl_surround: play %d bytes, %d samples\n", ao_plugin_data.len, samples);
 
   samples  = ao_plugin_data.len / sizeof(int16_t) / pl_surround.input_channels;
+  out = pl_surround.databuf;  in = (int16_t *)ao_plugin_data.data;
 
-  out = pl_surround.databuf;  in = (int16_t *)ao_plugin_data.data;
+  // Testing - place a 1kHz tone in the front channels in anti-phase
+  //sinewave(in, samples, pl_surround.input_channels, 1000, 0.0, pl_surround.rate);
+  //sinewave(&in[1], samples, pl_surround.input_channels, 1000, PI, pl_surround.rate);
+
   for (i=0; i<samples; i++) {
 
     // About volume balancing...