SoDaRadio-5.0.3-master:8901fb5
OneFilterTest.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 
39 #include <boost/format.hpp>
40 
41 using namespace std;
42 #include <sys/time.h>
43 
44 
45 double curtime()
46 {
47  double ret;
48  struct timeval tp;
49  gettimeofday(&tp, NULL);
50  ret = ((double) tp.tv_sec) + 1e-6*((double)tp.tv_usec);
51 
52  return ret;
53 }
54 
55 
56 #include "SoDa_filter_tables.hxx"
57 
59 {
60  SoDa::OSFilter ** filter_map = new SoDa::OSFilter*[5];
61 
62  filter_map[0] = new SoDa::OSFilter(300.0, 400.0, 500.0, 600.0, 512, 1.0, 48000.0, inbuflen);
63  // filter_map[1] = new SoDa::OSFilter(filt_500Hz, filt_len_500Hz, filt_gain_500Hz, inbuflen);
64  filter_map[1] = new SoDa::OSFilter(300.0, 400.0, 900.0, 1000.0, 512, 1.0, 48000.0, inbuflen);
65  filter_map[2] = new SoDa::OSFilter(200.0, 300.0, 2300.0, 2400.0, 512, 1.0, 48000.0, inbuflen);
66  filter_map[3] = new SoDa::OSFilter(100.0, 200.0, 6200.0, 6300.0, 512, 1.0, 48000.0, inbuflen);
67  filter_map[4] = new SoDa::OSFilter(100.0, 200.0, 18000.0, 19000.0, 512, 1.0, 48000.0, inbuflen);
68  std::ofstream f100("filt100.dat");
69  std::ofstream f500("filt500.dat");
70  std::ofstream f2000("filt_fd2000.dat");
71  std::ofstream f6000("filt_fd6000.dat");
72  std::ofstream fspec("filt_pass.dat");
73 
74  filter_map[0]->dump(f100);
75  filter_map[1]->dump(f500);
76  filter_map[2]->dump(f2000);
77  filter_map[3]->dump(f6000);
78  filter_map[4]->dump(fspec);
79 
80  f100.close();
81  f500.close();
82  f2000.close();
83  f6000.close();
84  fspec.close();
85 
86  return filter_map;
87 }
88 
89 void add_sig(complex<float> * in, float freq, int len, float acc)
90 {
91  int i;
92  float phase_step = 2.0 * M_PI * freq / ((float) SAMPLE_RATE);
93  float ang = 0.0;
94  for(i = 0; i < len; i++) {
95  in[i] = acc * in[i] + complex<float>(cos(ang),sin(ang));
96  ang += phase_step;
97  if(ang > M_PI) ang = ang - (2.0 * M_PI);
98  }
99 }
100 
101 // the filters are all built for a 48KHz sample rate.
102 // now let's see what happens..
103 
104 int main(int argc, char * argv[])
105 {
106  (void) argc; (void) argv;
107 
108  int i, j;
109  const int samp_len = 65536;
110  int inbuflen = 2304;
111 
112  double sample_rate = 48000.0;
113 
114  SoDa::OSFilter SSBFilter(200.0, 300.0, 2300.0, 2400.0, 512, 1.0, sample_rate, inbuflen);
115  // SoDa::OSFilter CWFilter(300.0, 400.0, 500.0, 600.0, 512, 1.0, 48000.0, inbuflen);
116  SoDa::OSFilter CWFilter(300.0, 400.0, 900.0, 1000.0, 512, 1.0, 48000.0, inbuflen);
117 
118  complex<float> in[samp_len];
119  complex<float> ssb_out[samp_len];
120  complex<float> cw_out[samp_len];
121 
122 
123  // sweep the frequency from -22kHz to 22kHz
124  double freq;
125  for(freq = -22e3; freq < 22e3; freq += 5.0) {
126  double phase_step = 2.0 * M_PI * freq / ((double) sample_rate);
127  double ang = 0.0;
128  for(i = 0; i < samp_len; i++) {
129  in[i] = complex<float>(cos(ang), sin(ang));
130  ang += phase_step;
131  if(ang > M_PI) ang = ang - 2.0 * M_PI;
132  if(ang < -M_PI) ang = ang + 2.0 * M_PI;
133  }
134  for(i = 0; i < (samp_len - inbuflen); i += inbuflen) {
135  SSBFilter.apply(&(in[i]), &(ssb_out[i]));
136  CWFilter.apply(&(in[i]), &(cw_out[i]));
137  }
138 
139  // now measure the phase and amplitude
140  // do this somewhere near the middle...
141 
142  double ssb_gain, ssb_phase, cw_gain, cw_phase;
143  for(i = 4000, j = 0; j < 5; i += 1000, j++) {
144  ssb_gain = std::abs(ssb_out[i]) / std::abs(in[i]);
145  ssb_phase = std::arg(ssb_out[i]) - std::arg(in[i]);
146  cw_gain = std::abs(cw_out[i]) / std::abs(in[i]);
147  cw_phase = std::arg(cw_out[i]) - std::arg(in[i]);
148  if(ssb_phase > M_PI) ssb_phase -= 2.0*M_PI;
149  if(ssb_phase < -M_PI) ssb_phase += 2.0*M_PI;
150  if(cw_phase > M_PI) cw_phase -= 2.0*M_PI;
151  if(cw_phase < -M_PI) cw_phase += 2.0*M_PI;
152  std::cout << boost::format("%12.8f %6g %6g %6g %6g\n") % freq % ssb_gain % ssb_phase % cw_gain % cw_phase;
153  }
154 
155  }
156 
157 
158  return 0;
159 }
This is an overlap-and-save frequency domain implementation of a general FIR filter widget...
void add_sig(complex< float > *in, float freq, int len, float acc)
STL namespace.
void dump(std::ostream &os)
dump the filter FFT to the output stream
Definition: OSFilter.cxx:364
int main(int argc, char *argv[])
Overlap-and-save filter class.
Definition: OSFilter.hxx:50
double curtime()
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)
#define SAMPLE_RATE