SoDaRadio-5.0.3-master:8901fb5
OSFilter_Test.cxx
Go to the documentation of this file.
1 /*
2 Copyright (c) 2012, Matthew H. Reilly (kb1vc)
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 
9  Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in
13  the documentation and/or other materials provided with the
14  distribution.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 #define SAMPLE_RATE 48000
29 #include <complex>
30 #include <iostream>
31 #include <fstream>
32 #include <stdlib.h>
33 #include "OSFilter.hxx"
34 #include <time.h>
35 #include <fftw3.h>
36 #include <math.h>
37 
38 #include <stdio.h>
39 #include <fcntl.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 
43 using namespace std;
44 #include <sys/time.h>
45 
46 
47 double curtime()
48 {
49  double ret;
50  struct timeval tp;
51  gettimeofday(&tp, NULL);
52  ret = ((double) tp.tv_sec) + 1e-6*((double)tp.tv_usec);
53 
54  return ret;
55 }
56 
57 
58 #include "SoDa_filter_tables.hxx"
59 
61 {
62 
63  SoDa::OSFilter ** filter_map = new SoDa::OSFilter*[5];
64 
65  filter_map[0] = new SoDa::OSFilter(300.0, 400.0, 500.0, 600.0, 512, 1.0, 48000.0, inbuflen);
66  // filter_map[1] = new SoDa::OSFilter(filt_500Hz, filt_len_500Hz, filt_gain_500Hz, inbuflen);
67  filter_map[1] = new SoDa::OSFilter(300.0, 400.0, 900.0, 1000.0, 512, 1.0, 48000.0, inbuflen);
68  filter_map[2] = new SoDa::OSFilter(200.0, 300.0, 2300.0, 2400.0, 512, 1.0, 48000.0, inbuflen);
69  filter_map[3] = new SoDa::OSFilter(100.0, 200.0, 6200.0, 6300.0, 512, 1.0, 48000.0, inbuflen);
70  filter_map[4] = new SoDa::OSFilter(100.0, 200.0, 18000.0, 19000.0, 512, 1.0, 48000.0, inbuflen);
71  std::ofstream f100("filt100.dat");
72  std::ofstream f500("filt500.dat");
73  std::ofstream f2000("filt_fd2000.dat");
74  std::ofstream f6000("filt_fd6000.dat");
75  std::ofstream fspec("filt_pass.dat");
76 
77  filter_map[0]->dump(f100);
78  filter_map[1]->dump(f500);
79  filter_map[2]->dump(f2000);
80  filter_map[3]->dump(f6000);
81  filter_map[4]->dump(fspec);
82 
83  f100.close();
84  f500.close();
85  f2000.close();
86  f6000.close();
87  fspec.close();
88 
89  return filter_map;
90 }
91 
92 void add_sig(complex<float> * in, float freq, int len, float acc)
93 {
94  int i;
95  float phase_step = 2.0 * M_PI * freq / ((float) SAMPLE_RATE);
96  float ang = 0.0;
97  for(i = 0; i < len; i++) {
98  in[i] = acc * in[i] + complex<float>(cos(ang),sin(ang));
99  ang += phase_step;
100  if(ang > M_PI) ang = ang - (2.0 * M_PI);
101  }
102 }
103 
104 // the filters are all built for a 48KHz sample rate.
105 // now let's see what happens..
106 
107 int main(int argc, char * argv[])
108 {
109  (void) argc;
110  (void) argv;
111  SoDa::OSFilter ** filter_map;
112  int i, j;
113  fprintf(stderr, "Hey there!\n");
114  // two
115 
116 
117  srandom(0x13255);
118 
119  const int samp_len = 65536;
120  int inbuflen = samp_len / 8;
121  float * specbuf[6];
122  for(int iii = 0; iii < 6; iii++) {
123  specbuf[iii] = (float*) malloc(sizeof(float) * samp_len);
124  }
125  filter_map = buildFilterMap(inbuflen);
126  // three
127  complex<float> in[samp_len];
128  complex<float> out[6][samp_len];
129 
130  FILE * trace_outf = fopen("OSFilter_Test_Trace.dat", "w");
131  FILE * spec_outf = fopen("OSFilter_Test_Spectrum.dat", "w");
132 
133  // four
134 
135  std::complex<float> sout[6][samp_len];
136  fftwf_plan sp = fftwf_plan_dft_1d(samp_len, (fftwf_complex *) out[0], (fftwf_complex *) sout[0],
137  FFTW_FORWARD, FFTW_ESTIMATE);
138 
139  // five
140  for(j = 0; j < 5; j++) {
141  for(i = 0; i < samp_len; i++) specbuf[j][i] = 0.0;
142  }
143  // one
144 
145  int k;
146  for(k = 0; k < 1000; k++) {
147  for(i = 0; i < samp_len; i++) {
148  long irand = random();
149  in[i] = ((float) (irand & 0xffff));
150  }
151 
152  // not this
153 
154  for(i = 0; i < samp_len; i++) {
155  out[0][i] = in[i];
156  }
157  // not this
158 
159  // now run the filter through its paces.
160  for(i = 0; i < 5; i++) {
161  int j;
162  for(j = 0; j < samp_len; j += inbuflen) {
163  filter_map[i]->apply(&(in[j]), &(out[i+1][j]));
164  }
165  }
166  // not in here
167 
168  // print the results.
169  if(k == 2) {
170  for(i = 0; i < samp_len; i++) {
171  fprintf(trace_outf, "%d ", i);
172  for(j = 0; j < 6; j++) {
173  fprintf(trace_outf, "%g %g ", out[j][i].real(), out[j][i].imag());
174  }
175  fprintf(trace_outf, "\n");
176  }
177  }
178 
179  for(j = 0; j < 6; j++) {
180  fftwf_execute_dft(sp, (fftwf_complex*) out[j], (fftwf_complex*)sout[j]);
181  }
182  for(i = 0; i < samp_len; i++) {
183  for(j = 0; j < 6; j++) {
184  float re, im;
185  re = sout[j][i].real();
186  im = sout[j][i].imag();
187  specbuf[j][i] += sqrt(re * re + im * im);
188  }
189  }
190  }
191 
192  fclose(trace_outf);
193  float norm = 1.0 / ((float) k);
194  for(i = 0; i < samp_len / 2; i++) {
195  float freq = ((float) i) * 48000.0 / 65536.0;
196  fprintf(spec_outf, "%d %f", i, freq);
197  for(j = 0; j < 6; j++) {
198  fprintf(spec_outf, " %f", norm * specbuf[j][i]);
199  }
200  fprintf(spec_outf, "\n");
201  }
202  fclose(spec_outf);
203  return 0;
204 }
This is an overlap-and-save frequency domain implementation of a general FIR filter widget...
int main(int argc, char *argv[])
STL namespace.
void add_sig(complex< float > *in, float freq, int len, float acc)
void dump(std::ostream &os)
dump the filter FFT to the output stream
Definition: OSFilter.cxx:364
#define SAMPLE_RATE
double curtime()
Overlap-and-save filter class.
Definition: OSFilter.hxx:50
unsigned int apply(std::complex< float > *inbuf, std::complex< float > *outbuf, float outgain=1.0)
run the filter on a complex input stream
Definition: OSFilter.cxx:334
SoDa::OSFilter ** buildFilterMap(int inbuflen)