diff options
author | Tom Rondeau <trondeau@vt.edu> | 2013-03-06 15:37:15 -0500 |
---|---|---|
committer | Tom Rondeau <trondeau@vt.edu> | 2013-03-06 15:46:00 -0500 |
commit | 9ac143a654bc581d9a74363fc02e1ad30be93138 (patch) | |
tree | 537c7d57f2dd2f676011099429383b000af752ab /gnuradio-core/src | |
parent | cf2c954ba4fc54909515f8550fd55741c9603a11 (diff) |
core: cleaning up remez and firdes in gnuradio-core; now in gr-filter.
Diffstat (limited to 'gnuradio-core/src')
-rw-r--r-- | gnuradio-core/src/lib/general/CMakeLists.txt | 3 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/general.i | 4 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_firdes.cc | 840 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_firdes.h | 373 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_firdes.i | 360 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_remez.cc | 1033 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_remez.h | 65 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_remez.i | 32 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/qa_general.cc | 2 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/qa_gr_firdes.cc | 618 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/qa_gr_firdes.h | 52 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/qa_block_tags.cc | 3 | ||||
-rw-r--r-- | gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py | 5 | ||||
-rwxr-xr-x | gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py | 11 |
14 files changed, 10 insertions, 3391 deletions
diff --git a/gnuradio-core/src/lib/general/CMakeLists.txt b/gnuradio-core/src/lib/general/CMakeLists.txt index bf9d43ec1a..55593aed40 100644 --- a/gnuradio-core/src/lib/general/CMakeLists.txt +++ b/gnuradio-core/src/lib/general/CMakeLists.txt @@ -86,7 +86,6 @@ list(APPEND gnuradio_core_sources list(APPEND test_gnuradio_core_sources ${CMAKE_CURRENT_SOURCE_DIR}/qa_general.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_circular_file.cc - ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_firdes.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fxpt.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fxpt_nco.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fxpt_vco.cc @@ -151,7 +150,6 @@ set(gr_core_general_triple_threats gr_endian_swap gr_fake_channel_coder_pp gr_feval - gr_firdes gr_head gr_iqcomp_cc gr_kludge_copy @@ -161,7 +159,6 @@ set(gr_core_general_triple_threats gr_null_source gr_pa_2x2_phase_combiner gr_prefs - gr_remez gr_skiphead gr_test gr_vco_f diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index 8be52295b9..b67530cc33 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -28,14 +28,12 @@ #include <gr_null_source.h> #include <gr_head.h> #include <gr_skiphead.h> -#include <gr_remez.h> #include <gr_check_counting_s.h> #include <gr_lfsr_32k_source_s.h> #include <gr_check_lfsr_32k_s.h> #include <gr_align_on_samplenumbers_ss.h> //#include <gr_endianness.h> #include <gr_endian_swap.h> -#include <gr_firdes.h> #include <gr_fake_channel_coder_pp.h> #include <gr_vco_f.h> #include <gr_pa_2x2_phase_combiner.h> @@ -62,14 +60,12 @@ %include "gr_null_source.i" %include "gr_head.i" %include "gr_skiphead.i" -%include "gr_remez.i" %include "gr_check_counting_s.i" %include "gr_lfsr_32k_source_s.i" %include "gr_check_lfsr_32k_s.i" %include "gr_align_on_samplenumbers_ss.i" //%include "gr_endianness.i" %include "gr_endian_swap.i" -%include "gr_firdes.i" %include "gr_fake_channel_coder_pp.i" %include "gr_vco_f.i" %include "gr_pa_2x2_phase_combiner.i" diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc deleted file mode 100644 index 4c72371410..0000000000 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ /dev/null @@ -1,840 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2002,2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gr_firdes.h> -#include <stdexcept> - - -using std::vector; - -#define IzeroEPSILON 1E-21 /* Max error acceptable in Izero */ - -static double Izero(double x) -{ - double sum, u, halfx, temp; - int n; - - sum = u = n = 1; - halfx = x/2.0; - do { - temp = halfx/(double)n; - n += 1; - temp *= temp; - u *= temp; - sum += u; - } while (u >= IzeroEPSILON*sum); - return(sum); -} - - -// -// === Low Pass === -// - -vector<float> -gr_firdes::low_pass_2(double gain, - double sampling_freq, // Hz - double cutoff_freq, // Hz BEGINNING of transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // attenuation dB - win_type window_type, - double beta) // used only with Kaiser -{ - sanity_check_1f (sampling_freq, cutoff_freq, transition_width); - - int ntaps = compute_ntaps_windes (sampling_freq, transition_width, - attenuation_dB); - - // construct the truncated ideal impulse response - // [sin(x)/x for the low pass case] - - vector<float> taps(ntaps); - vector<float> w = window (window_type, ntaps, beta); - - int M = (ntaps - 1) / 2; - double fwT0 = 2 * M_PI * cutoff_freq / sampling_freq; - for (int n = -M; n <= M; n++){ - if (n == 0) - taps[n + M] = fwT0 / M_PI * w[n + M]; - else { - // a little algebra gets this into the more familiar sin(x)/x form - taps[n + M] = sin (n * fwT0) / (n * M_PI) * w[n + M]; - } - } - - // find the factor to normalize the gain, fmax. - // For low-pass, gain @ zero freq = 1.0 - - double fmax = taps[0 + M]; - for (int n = 1; n <= M; n++) - fmax += 2 * taps[n + M]; - - gain /= fmax; // normalize - - for (int i = 0; i < ntaps; i++) - taps[i] *= gain; - - - return taps; -} - -vector<float> -gr_firdes::low_pass (double gain, - double sampling_freq, - double cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window_type, - double beta) // used only with Kaiser -{ - sanity_check_1f (sampling_freq, cutoff_freq, transition_width); - - int ntaps = compute_ntaps (sampling_freq, transition_width, - window_type, beta); - - // construct the truncated ideal impulse response - // [sin(x)/x for the low pass case] - - vector<float> taps(ntaps); - vector<float> w = window (window_type, ntaps, beta); - - int M = (ntaps - 1) / 2; - double fwT0 = 2 * M_PI * cutoff_freq / sampling_freq; - - for (int n = -M; n <= M; n++){ - if (n == 0) - taps[n + M] = fwT0 / M_PI * w[n + M]; - else { - // a little algebra gets this into the more familiar sin(x)/x form - taps[n + M] = sin (n * fwT0) / (n * M_PI) * w[n + M]; - } - } - - // find the factor to normalize the gain, fmax. - // For low-pass, gain @ zero freq = 1.0 - - double fmax = taps[0 + M]; - for (int n = 1; n <= M; n++) - fmax += 2 * taps[n + M]; - - gain /= fmax; // normalize - - for (int i = 0; i < ntaps; i++) - taps[i] *= gain; - - return taps; -} - - -// -// === High Pass === -// - -vector<float> -gr_firdes::high_pass_2 (double gain, - double sampling_freq, - double cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // attenuation dB - win_type window_type, - double beta) // used only with Kaiser -{ - sanity_check_1f (sampling_freq, cutoff_freq, transition_width); - - int ntaps = compute_ntaps_windes (sampling_freq, transition_width, - attenuation_dB); - - // construct the truncated ideal impulse response times the window function - - vector<float> taps(ntaps); - vector<float> w = window (window_type, ntaps, beta); - - int M = (ntaps - 1) / 2; - double fwT0 = 2 * M_PI * cutoff_freq / sampling_freq; - - for (int n = -M; n <= M; n++){ - if (n == 0) - taps[n + M] = (1 - (fwT0 / M_PI)) * w[n + M]; - else { - // a little algebra gets this into the more familiar sin(x)/x form - taps[n + M] = -sin (n * fwT0) / (n * M_PI) * w[n + M]; - } - } - - // find the factor to normalize the gain, fmax. - // For high-pass, gain @ fs/2 freq = 1.0 - - double fmax = taps[0 + M]; - for (int n = 1; n <= M; n++) - fmax += 2 * taps[n + M] * cos (n * M_PI); - - gain /= fmax; // normalize - - for (int i = 0; i < ntaps; i++) - taps[i] *= gain; - - - return taps; -} - - -vector<float> -gr_firdes::high_pass (double gain, - double sampling_freq, - double cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window_type, - double beta) // used only with Kaiser -{ - sanity_check_1f (sampling_freq, cutoff_freq, transition_width); - - int ntaps = compute_ntaps (sampling_freq, transition_width, - window_type, beta); - - // construct the truncated ideal impulse response times the window function - - vector<float> taps(ntaps); - vector<float> w = window (window_type, ntaps, beta); - - int M = (ntaps - 1) / 2; - double fwT0 = 2 * M_PI * cutoff_freq / sampling_freq; - - for (int n = -M; n <= M; n++){ - if (n == 0) - taps[n + M] = (1 - (fwT0 / M_PI)) * w[n + M]; - else { - // a little algebra gets this into the more familiar sin(x)/x form - taps[n + M] = -sin (n * fwT0) / (n * M_PI) * w[n + M]; - } - } - - // find the factor to normalize the gain, fmax. - // For high-pass, gain @ fs/2 freq = 1.0 - - double fmax = taps[0 + M]; - for (int n = 1; n <= M; n++) - fmax += 2 * taps[n + M] * cos (n * M_PI); - - gain /= fmax; // normalize - - for (int i = 0; i < ntaps; i++) - taps[i] *= gain; - - return taps; -} - -// -// === Band Pass === -// - -vector<float> -gr_firdes::band_pass_2 (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // attenuation dB - win_type window_type, - double beta) // used only with Kaiser -{ - sanity_check_2f (sampling_freq, - low_cutoff_freq, - high_cutoff_freq, transition_width); - - int ntaps = compute_ntaps_windes (sampling_freq, transition_width, - attenuation_dB); - - vector<float> taps(ntaps); - vector<float> w = window (window_type, ntaps, beta); - - int M = (ntaps - 1) / 2; - double fwT0 = 2 * M_PI * low_cutoff_freq / sampling_freq; - double fwT1 = 2 * M_PI * high_cutoff_freq / sampling_freq; - - for (int n = -M; n <= M; n++){ - if (n == 0) - taps[n + M] = (fwT1 - fwT0) / M_PI * w[n + M]; - else { - taps[n + M] = (sin (n * fwT1) - sin (n * fwT0)) / (n * M_PI) * w[n + M]; - } - } - - // find the factor to normalize the gain, fmax. - // For band-pass, gain @ center freq = 1.0 - - double fmax = taps[0 + M]; - for (int n = 1; n <= M; n++) - fmax += 2 * taps[n + M] * cos (n * (fwT0 + fwT1) * 0.5); - - gain /= fmax; // normalize - - for (int i = 0; i < ntaps; i++) - taps[i] *= gain; - - return taps; -} - - -vector<float> -gr_firdes::band_pass (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window_type, - double beta) // used only with Kaiser -{ - sanity_check_2f (sampling_freq, - low_cutoff_freq, - high_cutoff_freq, transition_width); - - int ntaps = compute_ntaps (sampling_freq, transition_width, - window_type, beta); - - // construct the truncated ideal impulse response times the window function - - vector<float> taps(ntaps); - vector<float> w = window (window_type, ntaps, beta); - - int M = (ntaps - 1) / 2; - double fwT0 = 2 * M_PI * low_cutoff_freq / sampling_freq; - double fwT1 = 2 * M_PI * high_cutoff_freq / sampling_freq; - - for (int n = -M; n <= M; n++){ - if (n == 0) - taps[n + M] = (fwT1 - fwT0) / M_PI * w[n + M]; - else { - taps[n + M] = (sin (n * fwT1) - sin (n * fwT0)) / (n * M_PI) * w[n + M]; - } - } - - // find the factor to normalize the gain, fmax. - // For band-pass, gain @ center freq = 1.0 - - double fmax = taps[0 + M]; - for (int n = 1; n <= M; n++) - fmax += 2 * taps[n + M] * cos (n * (fwT0 + fwT1) * 0.5); - - gain /= fmax; // normalize - - for (int i = 0; i < ntaps; i++) - taps[i] *= gain; - - return taps; -} - -// -// === Complex Band Pass === -// - -vector<gr_complex> -gr_firdes::complex_band_pass_2 (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // attenuation dB - win_type window_type, - double beta) // used only with Kaiser -{ - sanity_check_2f_c (sampling_freq, - low_cutoff_freq, - high_cutoff_freq, transition_width); - - int ntaps = compute_ntaps_windes (sampling_freq, transition_width, - attenuation_dB); - - - - vector<gr_complex> taps(ntaps); - vector<float> lptaps(ntaps); - vector<float> w = window (window_type, ntaps, beta); - - lptaps = low_pass_2(gain,sampling_freq,(high_cutoff_freq - low_cutoff_freq)/2,transition_width,attenuation_dB,window_type,beta); - - gr_complex *optr = &taps[0]; - float *iptr = &lptaps[0]; - float freq = M_PI * (high_cutoff_freq + low_cutoff_freq)/sampling_freq; - float phase=0; - if (lptaps.size() & 01) { - phase = - freq * ( lptaps.size() >> 1 ); - } else phase = - freq/2.0 * ((1 + 2*lptaps.size()) >> 1); - for(unsigned int i=0;i<lptaps.size();i++) { - *optr++ = gr_complex(*iptr * cos(phase),*iptr * sin(phase)); - iptr++, phase += freq; - } - - return taps; -} - - -vector<gr_complex> -gr_firdes::complex_band_pass (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window_type, - double beta) // used only with Kaiser -{ - sanity_check_2f_c (sampling_freq, - low_cutoff_freq, - high_cutoff_freq, transition_width); - - int ntaps = compute_ntaps (sampling_freq, transition_width, - window_type, beta); - - // construct the truncated ideal impulse response times the window function - - vector<gr_complex> taps(ntaps); - vector<float> lptaps(ntaps); - vector<float> w = window (window_type, ntaps, beta); - - lptaps = low_pass(gain,sampling_freq,(high_cutoff_freq - low_cutoff_freq)/2,transition_width,window_type,beta); - - gr_complex *optr = &taps[0]; - float *iptr = &lptaps[0]; - float freq = M_PI * (high_cutoff_freq + low_cutoff_freq)/sampling_freq; - float phase=0; - if (lptaps.size() & 01) { - phase = - freq * ( lptaps.size() >> 1 ); - } else phase = - freq/2.0 * ((1 + 2*lptaps.size()) >> 1); - for(unsigned int i=0;i<lptaps.size();i++) { - *optr++ = gr_complex(*iptr * cos(phase),*iptr * sin(phase)); - iptr++, phase += freq; - } - - return taps; -} - -// -// === Band Reject === -// - -vector<float> -gr_firdes::band_reject_2 (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // attenuation dB - win_type window_type, - double beta) // used only with Kaiser -{ - sanity_check_2f (sampling_freq, - low_cutoff_freq, - high_cutoff_freq, transition_width); - - int ntaps = compute_ntaps_windes (sampling_freq, transition_width, - attenuation_dB); - - // construct the truncated ideal impulse response times the window function - - vector<float> taps(ntaps); - vector<float> w = window (window_type, ntaps, beta); - - int M = (ntaps - 1) / 2; - double fwT0 = 2 * M_PI * low_cutoff_freq / sampling_freq; - double fwT1 = 2 * M_PI * high_cutoff_freq / sampling_freq; - - for (int n = -M; n <= M; n++){ - if (n == 0) - taps[n + M] = 1.0 + ((fwT0 - fwT1) / M_PI * w[n + M]); - else { - taps[n + M] = (sin (n * fwT0) - sin (n * fwT1)) / (n * M_PI) * w[n + M]; - } - } - - // find the factor to normalize the gain, fmax. - // For band-reject, gain @ zero freq = 1.0 - - double fmax = taps[0 + M]; - for (int n = 1; n <= M; n++) - fmax += 2 * taps[n + M]; - - gain /= fmax; // normalize - - for (int i = 0; i < ntaps; i++) - taps[i] *= gain; - - return taps; -} - -vector<float> -gr_firdes::band_reject (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window_type, - double beta) // used only with Kaiser -{ - sanity_check_2f (sampling_freq, - low_cutoff_freq, - high_cutoff_freq, transition_width); - - int ntaps = compute_ntaps (sampling_freq, transition_width, - window_type, beta); - - // construct the truncated ideal impulse response times the window function - - vector<float> taps(ntaps); - vector<float> w = window (window_type, ntaps, beta); - - int M = (ntaps - 1) / 2; - double fwT0 = 2 * M_PI * low_cutoff_freq / sampling_freq; - double fwT1 = 2 * M_PI * high_cutoff_freq / sampling_freq; - - for (int n = -M; n <= M; n++){ - if (n == 0) - taps[n + M] = 1.0 + ((fwT0 - fwT1) / M_PI * w[n + M]); - else { - taps[n + M] = (sin (n * fwT0) - sin (n * fwT1)) / (n * M_PI) * w[n + M]; - } - } - - // find the factor to normalize the gain, fmax. - // For band-reject, gain @ zero freq = 1.0 - - double fmax = taps[0 + M]; - for (int n = 1; n <= M; n++) - fmax += 2 * taps[n + M]; - - gain /= fmax; // normalize - - for (int i = 0; i < ntaps; i++) - taps[i] *= gain; - - return taps; -} - -// -// Hilbert Transform -// - -vector<float> -gr_firdes::hilbert (unsigned int ntaps, - win_type windowtype, - double beta) -{ - if(!(ntaps & 1)) - throw std::out_of_range("Hilbert: Must have odd number of taps"); - - vector<float> taps(ntaps); - vector<float> w = window (windowtype, ntaps, beta); - unsigned int h = (ntaps-1)/2; - float gain=0; - for (unsigned int i = 1; i <= h; i++) - { - if(i&1) - { - float x = 1/(float)i; - taps[h+i] = x * w[h+i]; - taps[h-i] = -x * w[h-i]; - gain = taps[h+i] - gain; - } - else - taps[h+i] = taps[h-i] = 0; - } - gain = 2 * fabs(gain); - for ( unsigned int i = 0; i < ntaps; i++) - taps[i] /= gain; - return taps; -} - -// -// Gaussian -// - -vector<float> -gr_firdes::gaussian (double gain, - double spb, - double bt, - int ntaps) -{ - - vector<float> taps(ntaps); - double scale = 0; - double dt = 1.0/spb; - double s = 1.0/(sqrt(log(2.0)) / (2*M_PI*bt)); - double t0 = -0.5 * ntaps; - double ts; - for(int i=0;i<ntaps;i++) - { - t0++; - ts = s*dt*t0; - taps[i] = exp(-0.5*ts*ts); - scale += taps[i]; - } - for(int i=0;i<ntaps;i++) - taps[i] = taps[i] / scale * gain; - return taps; -} - - -// -// Root Raised Cosine -// - -vector<float> -gr_firdes::root_raised_cosine (double gain, - double sampling_freq, - double symbol_rate, - double alpha, - int ntaps) -{ - ntaps |= 1; // ensure that ntaps is odd - - double spb = sampling_freq/symbol_rate; // samples per bit/symbol - vector<float> taps(ntaps); - double scale = 0; - for(int i=0;i<ntaps;i++) - { - double x1,x2,x3,num,den; - double xindx = i - ntaps/2; - x1 = M_PI * xindx/spb; - x2 = 4 * alpha * xindx / spb; - x3 = x2*x2 - 1; - if( fabs(x3) >= 0.000001 ) // Avoid Rounding errors... - { - if( i != ntaps/2 ) - num = cos((1+alpha)*x1) + sin((1-alpha)*x1)/(4*alpha*xindx/spb); - else - num = cos((1+alpha)*x1) + (1-alpha) * M_PI / (4*alpha); - den = x3 * M_PI; - } - else - { - if(alpha==1) - { - taps[i] = -1; - continue; - } - x3 = (1-alpha)*x1; - x2 = (1+alpha)*x1; - num = (sin(x2)*(1+alpha)*M_PI - - cos(x3)*((1-alpha)*M_PI*spb)/(4*alpha*xindx) - + sin(x3)*spb*spb/(4*alpha*xindx*xindx)); - den = -32 * M_PI * alpha * alpha * xindx/spb; - } - taps[i] = 4 * alpha * num / den; - scale += taps[i]; - } - - for(int i=0;i<ntaps;i++) - taps[i] = taps[i] * gain / scale; - - return taps; -} - -// -// === Utilities === -// - -// delta_f / width_factor gives number of taps required. -static const float width_factor[5] = { // indexed by win_type - 3.3, // WIN_HAMMING - 3.1, // WIN_HANN - 5.5, // WIN_BLACKMAN - 2.0, // WIN_RECTANGULAR - //5.0 // WIN_KAISER (guesstimate compromise) - //2.0 // WIN_KAISER (guesstimate compromise) - 10.0 // WIN_KAISER -}; - -int -gr_firdes::compute_ntaps_windes(double sampling_freq, - double transition_width, // this is frequency, not relative frequency - double attenuation_dB) -{ - // Based on formula from Multirate Signal Processing for - // Communications Systems, fredric j harris - int ntaps = (int)(attenuation_dB*sampling_freq/(22.0*transition_width)); - if ((ntaps & 1) == 0) // if even... - ntaps++; // ...make odd - return ntaps; -} - -int -gr_firdes::compute_ntaps (double sampling_freq, - double transition_width, - win_type window_type, - double beta) -{ - // normalized transition width - double delta_f = transition_width / sampling_freq; - - // compute number of taps required for given transition width - int ntaps = (int) (width_factor[window_type] / delta_f + 0.5); - if ((ntaps & 1) == 0) // if even... - ntaps++; // ...make odd - - return ntaps; -} - -double gr_firdes::bessi0(double x) -{ - double ax,ans; - double y; - - ax=fabs(x); - if (ax < 3.75) - { - y=x/3.75; - y*=y; - ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492 - +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2))))); - } - else - { - y=3.75/ax; - ans=(exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1 - +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2 - +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1 - +y*0.392377e-2)))))))); - } - return ans; -} -vector<float> -gr_firdes::window (win_type type, int ntaps, double beta) -{ - vector<float> taps(ntaps); - int M = ntaps - 1; // filter order - - switch (type){ - case WIN_RECTANGULAR: - for (int n = 0; n < ntaps; n++) - taps[n] = 1; - - case WIN_HAMMING: - for (int n = 0; n < ntaps; n++) - taps[n] = 0.54 - 0.46 * cos ((2 * M_PI * n) / M); - break; - - case WIN_HANN: - for (int n = 0; n < ntaps; n++) - taps[n] = 0.5 - 0.5 * cos ((2 * M_PI * n) / M); - break; - - case WIN_BLACKMAN: - for (int n = 0; n < ntaps; n++) - taps[n] = 0.42 - 0.50 * cos ((2*M_PI * n) / (M-1)) - 0.08 * cos ((4*M_PI * n) / (M-1)); - break; - - case WIN_BLACKMAN_hARRIS: - for (int n = -ntaps/2; n < ntaps/2; n++) - taps[n+ntaps/2] = 0.35875 + 0.48829*cos((2*M_PI * n) / (float)M) + - 0.14128*cos((4*M_PI * n) / (float)M) + 0.01168*cos((6*M_PI * n) / (float)M); - break; - -#if 0 - case WIN_KAISER: - for (int n = 0; n < ntaps; n++) - taps[n] = bessi0(beta*sqrt(1.0 - (4.0*n/(M*M))))/bessi0(beta); - break; -#else - - case WIN_KAISER: - { - double IBeta = 1.0/Izero(beta); - double inm1 = 1.0/((double)(ntaps)); - double temp; - //fprintf(stderr, "IBeta = %g; inm1 = %g\n", IBeta, inm1); - - for (int i=0; i<ntaps; i++) { - temp = i * inm1; - //fprintf(stderr, "temp = %g\n", temp); - taps[i] = Izero(beta*sqrt(1.0-temp*temp)) * IBeta; - //fprintf(stderr, "taps[%d] = %g\n", i, taps[i]); - } - } - break; - -#endif - default: - throw std::out_of_range ("gr_firdes:window: type out of range"); - } - - return taps; -} - -void -gr_firdes::sanity_check_1f (double sampling_freq, - double fa, // cutoff freq - double transition_width) -{ - if (sampling_freq <= 0.0) - throw std::out_of_range ("gr_firdes check failed: sampling_freq > 0"); - - if (fa <= 0.0 || fa > sampling_freq / 2) - throw std::out_of_range ("gr_firdes check failed: 0 < fa <= sampling_freq / 2"); - - if (transition_width <= 0) - throw std::out_of_range ("gr_dirdes check failed: transition_width > 0"); -} - -void -gr_firdes::sanity_check_2f (double sampling_freq, - double fa, // first cutoff freq - double fb, // second cutoff freq - double transition_width) -{ - if (sampling_freq <= 0.0) - throw std::out_of_range ("gr_firdes check failed: sampling_freq > 0"); - - if (fa <= 0.0 || fa > sampling_freq / 2) - throw std::out_of_range ("gr_firdes check failed: 0 < fa <= sampling_freq / 2"); - - if (fb <= 0.0 || fb > sampling_freq / 2) - throw std::out_of_range ("gr_firdes check failed: 0 < fb <= sampling_freq / 2"); - - if (fa > fb) - throw std::out_of_range ("gr_firdes check failed: fa <= fb"); - - if (transition_width <= 0) - throw std::out_of_range ("gr_firdes check failed: transition_width > 0"); -} - -void -gr_firdes::sanity_check_2f_c (double sampling_freq, - double fa, // first cutoff freq - double fb, // second cutoff freq - double transition_width) -{ - if (sampling_freq <= 0.0) - throw std::out_of_range ("gr_firdes check failed: sampling_freq > 0"); - - if (fa < -sampling_freq / 2 || fa > sampling_freq / 2) - throw std::out_of_range ("gr_firdes check failed: 0 < fa <= sampling_freq / 2"); - - if (fb < -sampling_freq / 2 || fb > sampling_freq / 2) - throw std::out_of_range ("gr_firdes check failed: 0 < fb <= sampling_freq / 2"); - - if (fa > fb) - throw std::out_of_range ("gr_firdes check failed: fa <= fb"); - - if (transition_width <= 0) - throw std::out_of_range ("gr_firdes check failed: transition_width > 0"); -} diff --git a/gnuradio-core/src/lib/general/gr_firdes.h b/gnuradio-core/src/lib/general/gr_firdes.h deleted file mode 100644 index 8d98ebe0a1..0000000000 --- a/gnuradio-core/src/lib/general/gr_firdes.h +++ /dev/null @@ -1,373 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2002,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _GR_FIRDES_H_ -#define _GR_FIRDES_H_ - -#include <gr_core_api.h> -#include <vector> -#include <cmath> -#include <gr_complex.h> - -/*! - * \brief Finite Impulse Response (FIR) filter design functions. - * \ingroup filter_design - */ - -class GR_CORE_API gr_firdes { - public: - - enum win_type { - WIN_HAMMING = 0, // max attenuation 53 dB - WIN_HANN = 1, // max attenuation 44 dB - WIN_BLACKMAN = 2, // max attenuation 74 dB - WIN_RECTANGULAR = 3, - WIN_KAISER = 4, // max attenuation a function of beta, google it - WIN_BLACKMAN_hARRIS = 5, - WIN_BLACKMAN_HARRIS = 5, // alias for capitalization consistency - }; - - - // ... class methods ... - - /*! - * \brief use "window method" to design a low-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * The normalized width of the transition - * band is what sets the number of taps - * required. Narrow --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - static std::vector<float> - low_pass (double gain, - double sampling_freq, - double cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*! - * \brief use "window method" to design a low-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * \p attenuation_dB required stopband attenuation - * The normalized width of the transition - * band and the required stop band - * attenuation is what sets the number of taps - * required. Narrow --> more taps - * More attenuatin --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - low_pass_2 (double gain, - double sampling_freq, - double cutoff_freq, // Hz beginning transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // out of band attenuation dB - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*! - * \brief use "window method" to design a high-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * The normalized width of the transition - * band is what sets the number of taps - * required. Narrow --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - high_pass (double gain, - double sampling_freq, - double cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*! - * \brief use "window method" to design a high-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * \p attenuation_dB out of band attenuation - * The normalized width of the transition - * band and the required stop band - * attenuation is what sets the number of taps - * required. Narrow --> more taps - * More attenuation --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - high_pass_2 (double gain, - double sampling_freq, - double cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // out of band attenuation dB - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*! - * \brief use "window method" to design a band-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * The normalized width of the transition - * band is what sets the number of taps - * required. Narrow --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - static std::vector<float> - band_pass (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*! - * \brief use "window method" to design a band-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * \p attenuation_dB out of band attenuation - * The normalized width of the transition - * band and the required stop band - * attenuation is what sets the number of taps - * required. Narrow --> more taps - * More attenuation --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - band_pass_2 (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz beginning transition band - double high_cutoff_freq, // Hz beginning transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // out of band attenuation dB - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*! - * \brief use "window method" to design a complex band-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * The normalized width of the transition - * band is what sets the number of taps - * required. Narrow --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<gr_complex> - complex_band_pass (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*! - * \brief use "window method" to design a complex band-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * \p attenuation_dB out of band attenuation - * The normalized width of the transition - * band and the required stop band - * attenuation is what sets the number of taps - * required. Narrow --> more taps - * More attenuation --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<gr_complex> - complex_band_pass_2 (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz beginning transition band - double high_cutoff_freq, // Hz beginning transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // out of band attenuation dB - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*! - * \brief use "window method" to design a band-reject FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * The normalized width of the transition - * band is what sets the number of taps - * required. Narrow --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - band_reject (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*! - * \brief use "window method" to design a band-reject FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * \p attenuation_dB out of band attenuation - * The normalized width of the transition - * band and the required stop band - * attenuation is what sets the number of taps - * required. Narrow --> more taps - * More attenuation --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - band_reject_2 (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz beginning transition band - double high_cutoff_freq, // Hz beginning transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // out of band attenuation dB - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*!\brief design a Hilbert Transform Filter - * - * \p ntaps: Number of taps, must be odd - * \p window_type: What kind of window to use - * \p beta: Only used for Kaiser - */ - static std::vector<float> - hilbert (unsigned int ntaps = 19, - win_type windowtype = WIN_RECTANGULAR, - double beta = 6.76); - - /*! - * \brief design a Root Cosine FIR Filter (do we need a window?) - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p symbol rate: symbol rate, must be a factor of sample rate - * \p alpha: excess bandwidth factor - * \p ntaps: number of taps - */ - static std::vector<float> - root_raised_cosine (double gain, - double sampling_freq, - double symbol_rate, // Symbol rate, NOT bitrate (unless BPSK) - double alpha, // Excess Bandwidth Factor - int ntaps); - - /*! - * \brief design a Gaussian filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p symbols per bit: symbol rate, must be a factor of sample rate - * \p ntaps: number of taps - */ - static std::vector<float> - gaussian (double gain, - double spb, - double bt, // Bandwidth to bitrate ratio - int ntaps); - - // window functions ... - static std::vector<float> window (win_type type, int ntaps, double beta); - -private: - static double bessi0(double x); - static void sanity_check_1f (double sampling_freq, double f1, - double transition_width); - static void sanity_check_2f (double sampling_freq, double f1, double f2, - double transition_width); - static void sanity_check_2f_c (double sampling_freq, double f1, double f2, - double transition_width); - - static int compute_ntaps (double sampling_freq, - double transition_width, - win_type window_type, double beta); - - static int compute_ntaps_windes (double sampling_freq, - double transition_width, - double attenuation_dB); -}; - -#endif diff --git a/gnuradio-core/src/lib/general/gr_firdes.i b/gnuradio-core/src/lib/general/gr_firdes.i deleted file mode 100644 index 0493db6174..0000000000 --- a/gnuradio-core/src/lib/general/gr_firdes.i +++ /dev/null @@ -1,360 +0,0 @@ -/* -*- C++ -*- */ -/* - * Copyright 2002,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/*! - * \brief Finite Impulse Response (FIR) filter design functions. - */ - -%rename(firdes) gr_firdes; - -class gr_firdes { - public: - - enum win_type { - WIN_HAMMING = 0, // max attenuation 53 dB - WIN_HANN = 1, // max attenuation 44 dB - WIN_BLACKMAN = 2, // max attenuation 74 dB - WIN_RECTANGULAR = 3, - WIN_KAISER = 4, // max attenuation variable with beta, google it - WIN_BLACKMAN_hARRIS = 5, - }; - - // ... class methods ... - - /*! - * \brief use "window method" to design a low-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * The normalized width of the transition - * band is what sets the number of taps - * required. Narrow --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - static std::vector<float> - low_pass (double gain, - double sampling_freq, - double cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window = WIN_HAMMING, - double beta = 6.76 // used only with Kaiser - ) throw(std::out_of_range); - - /*! - * \brief use "window method" to design a low-pass FIR filter - * using alternative design criteria - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * \p attenuation_dB out of band attenuation - * The normalized width of the transition - * band and the required stop band - * attenuation is what sets the number of taps - * required. Narrow --> more taps - * More attenuation --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - static std::vector<float> - low_pass_2 (double gain, - double sampling_freq, - double cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // out of band attenuation - win_type window = WIN_HAMMING, - double beta = 6.76 // used only with Kaiser - ) throw(std::out_of_range); - - /*! - * \brief use "window method" to design a high-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * The normalized width of the transition - * band is what sets the number of taps - * required. Narrow --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - high_pass (double gain, - double sampling_freq, - double cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window = WIN_HAMMING, - double beta = 6.76 // used only with Kaiser - ) throw(std::out_of_range); - - /*! - * \brief use "window method" to design a high-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * \p attenuation_dB out of band attenuation - * The normalized width of the transition - * band and the required stop band - * attenuation is what sets the number of taps - * required. Narrow --> more taps - * More attenuation --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - high_pass_2 (double gain, - double sampling_freq, - double cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // out of band attenuation dB - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - - /*! - * \brief use "window method" to design a band-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * The normalized width of the transition - * band is what sets the number of taps - * required. Narrow --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - band_pass (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window = WIN_HAMMING, - double beta = 6.76 // used only with Kaiser - ) throw(std::out_of_range); - - - /*! - * \brief use "window method" to design a band-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * \p attenuation_dB out of band attenuation - * The normalized width of the transition - * band and the required stop band - * attenuation is what sets the number of taps - * required. Narrow --> more taps - * More attenuation --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - band_pass_2 (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz beginning transition band - double high_cutoff_freq, // Hz beginning transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // out of band attenuation dB - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*! - * \brief use "window method" to design a band-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * The normalized width of the transition - * band is what sets the number of taps - * required. Narrow --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<gr_complex> - complex_band_pass (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window = WIN_HAMMING, // used only with Kaiser - double beta = 6.76 - ) throw(std::out_of_range); - - - /*! - * \brief use "window method" to design a complex band-pass FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * \p attenuation_dB out of band attenuation - * The normalized width of the transition - * band and the required stop band - * attenuation is what sets the number of taps - * required. Narrow --> more taps - * More attenuation --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<gr_complex> - complex_band_pass_2 (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz beginning transition band - double high_cutoff_freq, // Hz beginning transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // out of band attenuation dB - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*! - * \brief use "window method" to design a band-reject FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * The normalized width of the transition - * band is what sets the number of taps - * required. Narrow --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - band_reject (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz center of transition band - double high_cutoff_freq, // Hz center of transition band - double transition_width, // Hz width of transition band - win_type window = WIN_HAMMING, // used only with Kaiser - double beta = 6.76 - ) throw(std::out_of_range); - - - /*! - * \brief use "window method" to design a band-reject FIR filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p low_cutoff_freq: center of transition band (Hz) - * \p high_cutoff_freq: center of transition band (Hz) - * \p transition_width: width of transition band (Hz). - * \p attenuation_dB out of band attenuation - * The normalized width of the transition - * band and the required stop band - * attenuation is what sets the number of taps - * required. Narrow --> more taps - * More attenuation --> more taps - * \p window_type: What kind of window to use. Determines - * maximum attenuation and passband ripple. - * \p beta: parameter for Kaiser window - */ - - static std::vector<float> - band_reject_2 (double gain, - double sampling_freq, - double low_cutoff_freq, // Hz beginning transition band - double high_cutoff_freq, // Hz beginning transition band - double transition_width, // Hz width of transition band - double attenuation_dB, // out of band attenuation dB - win_type window = WIN_HAMMING, - double beta = 6.76); // used only with Kaiser - - /*!\brief design a Hilbert Transform Filter - * - * \p ntaps: Number of taps, must be odd - * \p window_type: What kind of window to use - * \p beta: Only used for Kaiser - */ - static std::vector<float> - hilbert (unsigned int ntaps = 19, - win_type windowtype = WIN_RECTANGULAR, - double beta = 6.76 - ) throw(std::out_of_range); - - /*! - * \brief design a Root Cosine FIR Filter (do we need a window?) - * - * \p gain: overall gain of filter (typically 1.0) - * \p sampling_freq: sampling freq (Hz) - * \p symbol rate: symbol rate, must be a factor of sample rate - * \p alpha: excess bandwidth factor - * \p ntaps: number of taps - */ - static std::vector<float> - root_raised_cosine (double gain, - double sampling_freq, - double symbol_rate, // Symbol rate, NOT bitrate (unless BPSK) - double alpha, // Excess Bandwidth Factor - int ntaps) throw(std::out_of_range); - - /*! - * \brief design a Gaussian filter - * - * \p gain: overall gain of filter (typically 1.0) - * \p symbols per bit: symbol rate, must be a factor of sample rate - * \p bt: BT bandwidth time product - * \p ntaps: number of taps - */ - static std::vector<float> - gaussian (double gain, - double spb, - double bt, // Bandwidth to bitrate ratio - int ntaps) throw(std::out_of_range); - - /*! - * Return window given type, ntaps and optional beta. - */ - static std::vector<float> gr_firdes::window (win_type type, int ntaps, double beta) - throw(std::runtime_error); -}; diff --git a/gnuradio-core/src/lib/general/gr_remez.cc b/gnuradio-core/src/lib/general/gr_remez.cc deleted file mode 100644 index db4789e439..0000000000 --- a/gnuradio-core/src/lib/general/gr_remez.cc +++ /dev/null @@ -1,1033 +0,0 @@ -/************************************************************************** - * Parks-McClellan algorithm for FIR filter design (C version) - *------------------------------------------------- - * Copyright (c) 1995,1998 Jake Janovetz (janovetz@uiuc.edu) - * Copyright (c) 2004 Free Software Foundation, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA - * - * - * Sep 1999 - Paul Kienzle (pkienzle@cs.indiana.edu) - * Modified for use in octave as a replacement for the matlab function - * remez.mex. In particular, magnitude responses are required for all - * band edges rather than one per band, griddensity is a parameter, - * and errors are returned rather than printed directly. - * Mar 2000 - Kai Habel (kahacjde@linux.zrz.tu-berlin.de) - * Change: ColumnVector x=arg(i).vector_value(); - * to: ColumnVector x(arg(i).vector_value()); - * There appear to be some problems with the routine Search. See comments - * therein [search for PAK:]. I haven't looked closely at the rest - * of the code---it may also have some problems. - *************************************************************************/ - -/* - * This code was extracted from octave.sf.net, and wrapped with - * GNU Radio glue. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include <gr_remez.h> -#include <cmath> -#include <assert.h> -#include <iostream> - - -#ifndef LOCAL_BUFFER -#include <vector> -#define LOCAL_BUFFER(T, buf, size) \ - std::vector<T> buf ## _vector (size); \ - T *buf = &(buf ## _vector[0]) -#endif - - -#define CONST const -#define BANDPASS 1 -#define DIFFERENTIATOR 2 -#define HILBERT 3 - -#define NEGATIVE 0 -#define POSITIVE 1 - -#define Pi 3.14159265358979323846 -#define Pi2 (2*Pi) - -#define GRIDDENSITY 16 -#define MAXITERATIONS 40 - -/******************* - * CreateDenseGrid - *================= - * Creates the dense grid of frequencies from the specified bands. - * Also creates the Desired Frequency Response function (D[]) and - * the Weight function (W[]) on that dense grid - * - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coefficients - * int numtaps - Number of taps in the resulting filter - * int numband - Number of bands in user specification - * double bands[] - User-specified band edges [2*numband] - * double des[] - Desired response per band [2*numband] - * double weight[] - Weight per band [numband] - * int symmetry - Symmetry of filter - used for grid check - * int griddensity - * - * OUTPUT: - * ------- - * int gridsize - Number of elements in the dense frequency grid - * double Grid[] - Frequencies (0 to 0.5) on the dense grid [gridsize] - * double D[] - Desired response on the dense grid [gridsize] - * double W[] - Weight function on the dense grid [gridsize] - *******************/ - -static void -CreateDenseGrid (int r, int numtaps, int numband, const double bands[], - const double des[], const double weight[], int gridsize, - double Grid[], double D[], double W[], - int symmetry, int griddensity) -{ - int i, j, k, band; - double delf, lowf, highf, grid0; - - delf = 0.5/(griddensity*r); - -/* - * For differentiator, hilbert, - * symmetry is odd and Grid[0] = max(delf, bands[0]) - */ - grid0 = (symmetry == NEGATIVE) && (delf > bands[0]) ? delf : bands[0]; - - j=0; - for (band=0; band < numband; band++) - { - lowf = (band==0 ? grid0 : bands[2*band]); - highf = bands[2*band + 1]; - k = (int)((highf - lowf)/delf + 0.5); /* .5 for rounding */ - for (i=0; i<k; i++) - { - D[j] = des[2*band] + i*(des[2*band+1]-des[2*band])/(k-1); - W[j] = weight[band]; - Grid[j] = lowf; - lowf += delf; - j++; - } - Grid[j-1] = highf; - } - -/* - * Similar to above, if odd symmetry, last grid point can't be .5 - * - but, if there are even taps, leave the last grid point at .5 - */ - if ((symmetry == NEGATIVE) && - (Grid[gridsize-1] > (0.5 - delf)) && - (numtaps % 2)) - { - Grid[gridsize-1] = 0.5-delf; - } -} - - -/******************** - * InitialGuess - *============== - * Places Extremal Frequencies evenly throughout the dense grid. - * - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coefficients - * int gridsize - Number of elements in the dense frequency grid - * - * OUTPUT: - * ------- - * int Ext[] - Extremal indexes to dense frequency grid [r+1] - ********************/ - -static void -InitialGuess (int r, int Ext[], int gridsize) -{ - int i; - - for (i=0; i<=r; i++) - Ext[i] = i * (gridsize-1) / r; -} - - -/*********************** - * CalcParms - *=========== - * - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coefficients - * int Ext[] - Extremal indexes to dense frequency grid [r+1] - * double Grid[] - Frequencies (0 to 0.5) on the dense grid [gridsize] - * double D[] - Desired response on the dense grid [gridsize] - * double W[] - Weight function on the dense grid [gridsize] - * - * OUTPUT: - * ------- - * double ad[] - 'b' in Oppenheim & Schafer [r+1] - * double x[] - [r+1] - * double y[] - 'C' in Oppenheim & Schafer [r+1] - ***********************/ - -static void -CalcParms (int r, int Ext[], double Grid[], double D[], double W[], - double ad[], double x[], double y[]) -{ - int i, j, k, ld; - double sign, xi, delta, denom, numer; - -/* - * Find x[] - */ - for (i=0; i<=r; i++) - x[i] = cos(Pi2 * Grid[Ext[i]]); - -/* - * Calculate ad[] - Oppenheim & Schafer eq 7.132 - */ - ld = (r-1)/15 + 1; /* Skips around to avoid round errors */ - for (i=0; i<=r; i++) - { - denom = 1.0; - xi = x[i]; - for (j=0; j<ld; j++) - { - for (k=j; k<=r; k+=ld) - if (k != i) - denom *= 2.0*(xi - x[k]); - } - if (fabs(denom)<0.00001) - denom = 0.00001; - ad[i] = 1.0/denom; - } - -/* - * Calculate delta - Oppenheim & Schafer eq 7.131 - */ - numer = denom = 0; - sign = 1; - for (i=0; i<=r; i++) - { - numer += ad[i] * D[Ext[i]]; - denom += sign * ad[i]/W[Ext[i]]; - sign = -sign; - } - delta = numer/denom; - sign = 1; - -/* - * Calculate y[] - Oppenheim & Schafer eq 7.133b - */ - for (i=0; i<=r; i++) - { - y[i] = D[Ext[i]] - sign * delta/W[Ext[i]]; - sign = -sign; - } -} - - -/********************* - * ComputeA - *========== - * Using values calculated in CalcParms, ComputeA calculates the - * actual filter response at a given frequency (freq). Uses - * eq 7.133a from Oppenheim & Schafer. - * - * - * INPUT: - * ------ - * double freq - Frequency (0 to 0.5) at which to calculate A - * int r - 1/2 the number of filter coefficients - * double ad[] - 'b' in Oppenheim & Schafer [r+1] - * double x[] - [r+1] - * double y[] - 'C' in Oppenheim & Schafer [r+1] - * - * OUTPUT: - * ------- - * Returns double value of A[freq] - *********************/ - -static double -ComputeA (double freq, int r, double ad[], double x[], double y[]) -{ - int i; - double xc, c, denom, numer; - - denom = numer = 0; - xc = cos(Pi2 * freq); - for (i=0; i<=r; i++) - { - c = xc - x[i]; - if (fabs(c) < 1.0e-7) - { - numer = y[i]; - denom = 1; - break; - } - c = ad[i]/c; - denom += c; - numer += c*y[i]; - } - return numer/denom; -} - - -/************************ - * CalcError - *=========== - * Calculates the Error function from the desired frequency response - * on the dense grid (D[]), the weight function on the dense grid (W[]), - * and the present response calculation (A[]) - * - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coefficients - * double ad[] - [r+1] - * double x[] - [r+1] - * double y[] - [r+1] - * int gridsize - Number of elements in the dense frequency grid - * double Grid[] - Frequencies on the dense grid [gridsize] - * double D[] - Desired response on the dense grid [gridsize] - * double W[] - Weight function on the desnse grid [gridsize] - * - * OUTPUT: - * ------- - * double E[] - Error function on dense grid [gridsize] - ************************/ - -static void -CalcError (int r, double ad[], double x[], double y[], - int gridsize, double Grid[], - double D[], double W[], double E[]) -{ - int i; - double A; - - for (i=0; i<gridsize; i++) - { - A = ComputeA(Grid[i], r, ad, x, y); - E[i] = W[i] * (D[i] - A); - } -} - -/************************ - * Search - *======== - * Searches for the maxima/minima of the error curve. If more than - * r+1 extrema are found, it uses the following heuristic (thanks - * Chris Hanson): - * 1) Adjacent non-alternating extrema deleted first. - * 2) If there are more than one excess extrema, delete the - * one with the smallest error. This will create a non-alternation - * condition that is fixed by 1). - * 3) If there is exactly one excess extremum, delete the smaller - * of the first/last extremum - * - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coefficients - * int Ext[] - Indexes to Grid[] of extremal frequencies [r+1] - * int gridsize - Number of elements in the dense frequency grid - * double E[] - Array of error values. [gridsize] - * OUTPUT: - * ------- - * int Ext[] - New indexes to extremal frequencies [r+1] - ************************/ -static int -Search (int r, int Ext[], - int gridsize, double E[]) -{ - int i, j, k, l, extra; /* Counters */ - int up, alt; - int *foundExt; /* Array of found extremals */ - -/* - * Allocate enough space for found extremals. - */ - foundExt = (int *)malloc((2*r) * sizeof(int)); - k = 0; - -/* - * Check for extremum at 0. - */ - if (((E[0]>0.0) && (E[0]>E[1])) || - ((E[0]<0.0) && (E[0]<E[1]))) - foundExt[k++] = 0; - -/* - * Check for extrema inside dense grid - */ - for (i=1; i<gridsize-1; i++) - { - if (((E[i]>=E[i-1]) && (E[i]>E[i+1]) && (E[i]>0.0)) || - ((E[i]<=E[i-1]) && (E[i]<E[i+1]) && (E[i]<0.0))) { - // PAK: we sometimes get too many extremal frequencies - if (k >= 2*r) return -3; - foundExt[k++] = i; - } - } - -/* - * Check for extremum at 0.5 - */ - j = gridsize-1; - if (((E[j]>0.0) && (E[j]>E[j-1])) || - ((E[j]<0.0) && (E[j]<E[j-1]))) { - if (k >= 2*r) return -3; - foundExt[k++] = j; - } - - // PAK: we sometimes get not enough extremal frequencies - if (k < r+1) return -2; - - -/* - * Remove extra extremals - */ - extra = k - (r+1); - assert(extra >= 0); - - while (extra > 0) - { - if (E[foundExt[0]] > 0.0) - up = 1; /* first one is a maxima */ - else - up = 0; /* first one is a minima */ - - l=0; - alt = 1; - for (j=1; j<k; j++) - { - if (fabs(E[foundExt[j]]) < fabs(E[foundExt[l]])) - l = j; /* new smallest error. */ - if ((up) && (E[foundExt[j]] < 0.0)) - up = 0; /* switch to a minima */ - else if ((!up) && (E[foundExt[j]] > 0.0)) - up = 1; /* switch to a maxima */ - else - { - alt = 0; - // PAK: break now and you will delete the smallest overall - // extremal. If you want to delete the smallest of the - // pair of non-alternating extremals, then you must do: - // - // if (fabs(E[foundExt[j]]) < fabs(E[foundExt[j-1]])) l=j; - // else l=j-1; - break; /* Ooops, found two non-alternating */ - } /* extrema. Delete smallest of them */ - } /* if the loop finishes, all extrema are alternating */ - -/* - * If there's only one extremal and all are alternating, - * delete the smallest of the first/last extremals. - */ - if ((alt) && (extra == 1)) - { - if (fabs(E[foundExt[k-1]]) < fabs(E[foundExt[0]])) - /* Delete last extremal */ - l = k-1; - // PAK: changed from l = foundExt[k-1]; - else - /* Delete first extremal */ - l = 0; - // PAK: changed from l = foundExt[0]; - } - - for (j=l; j<k-1; j++) /* Loop that does the deletion */ - { - foundExt[j] = foundExt[j+1]; - assert(foundExt[j]<gridsize); - } - k--; - extra--; - } - - for (i=0; i<=r; i++) - { - assert(foundExt[i]<gridsize); - Ext[i] = foundExt[i]; /* Copy found extremals to Ext[] */ - } - - free(foundExt); - return 0; -} - - -/********************* - * FreqSample - *============ - * Simple frequency sampling algorithm to determine the impulse - * response h[] from A's found in ComputeA - * - * - * INPUT: - * ------ - * int N - Number of filter coefficients - * double A[] - Sample points of desired response [N/2] - * int symmetry - Symmetry of desired filter - * - * OUTPUT: - * ------- - * double h[] - Impulse Response of final filter [N] - *********************/ -static void -FreqSample (int N, double A[], double h[], int symm) -{ - int n, k; - double x, val, M; - - M = (N-1.0)/2.0; - if (symm == POSITIVE) - { - if (N%2) - { - for (n=0; n<N; n++) - { - val = A[0]; - x = Pi2 * (n - M)/N; - for (k=1; k<=M; k++) - val += 2.0 * A[k] * cos(x*k); - h[n] = val/N; - } - } - else - { - for (n=0; n<N; n++) - { - val = A[0]; - x = Pi2 * (n - M)/N; - for (k=1; k<=(N/2-1); k++) - val += 2.0 * A[k] * cos(x*k); - h[n] = val/N; - } - } - } - else - { - if (N%2) - { - for (n=0; n<N; n++) - { - val = 0; - x = Pi2 * (n - M)/N; - for (k=1; k<=M; k++) - val += 2.0 * A[k] * sin(x*k); - h[n] = val/N; - } - } - else - { - for (n=0; n<N; n++) - { - val = A[N/2] * sin(Pi * (n - M)); - x = Pi2 * (n - M)/N; - for (k=1; k<=(N/2-1); k++) - val += 2.0 * A[k] * sin(x*k); - h[n] = val/N; - } - } - } -} - -/******************* - * isDone - *======== - * Checks to see if the error function is small enough to consider - * the result to have converged. - * - * INPUT: - * ------ - * int r - 1/2 the number of filter coeffiecients - * int Ext[] - Indexes to extremal frequencies [r+1] - * double E[] - Error function on the dense grid [gridsize] - * - * OUTPUT: - * ------- - * Returns 1 if the result converged - * Returns 0 if the result has not converged - ********************/ - -static bool -isDone (int r, int Ext[], double E[]) -{ - int i; - double min, max, current; - - min = max = fabs(E[Ext[0]]); - for (i=1; i<=r; i++) - { - current = fabs(E[Ext[i]]); - if (current < min) - min = current; - if (current > max) - max = current; - } - return (((max-min)/max) < 0.0001); -} - -/******************** - * remez - *======= - * Calculates the optimal (in the Chebyshev/minimax sense) - * FIR filter impulse response given a set of band edges, - * the desired reponse on those bands, and the weight given to - * the error in those bands. - * - * INPUT: - * ------ - * int numtaps - Number of filter coefficients - * int numband - Number of bands in filter specification - * double bands[] - User-specified band edges [2 * numband] - * double des[] - User-specified band responses [2 * numband] - * double weight[] - User-specified error weights [numband] - * int type - Type of filter - * - * OUTPUT: - * ------- - * double h[] - Impulse response of final filter [numtaps] - * returns - true on success, false on failure to converge - ********************/ - -static int -remez (double h[], int numtaps, - int numband, const double bands[], - const double des[], const double weight[], - int type, int griddensity) -{ - double *Grid, *W, *D, *E; - int i, iter, gridsize, r, *Ext; - double *taps, c; - double *x, *y, *ad; - int symmetry; - - if (type == BANDPASS) - symmetry = POSITIVE; - else - symmetry = NEGATIVE; - - r = numtaps/2; /* number of extrema */ - if ((numtaps%2) && (symmetry == POSITIVE)) - r++; - -/* - * Predict dense grid size in advance for memory allocation - * .5 is so we round up, not truncate - */ - gridsize = 0; - for (i=0; i<numband; i++) - { - gridsize += (int)(2*r*griddensity*(bands[2*i+1] - bands[2*i]) + .5); - } - if (symmetry == NEGATIVE) - { - gridsize--; - } - -/* - * Dynamically allocate memory for arrays with proper sizes - */ - Grid = (double *)malloc(gridsize * sizeof(double)); - D = (double *)malloc(gridsize * sizeof(double)); - W = (double *)malloc(gridsize * sizeof(double)); - E = (double *)malloc(gridsize * sizeof(double)); - Ext = (int *)malloc((r+1) * sizeof(int)); - taps = (double *)malloc((r+1) * sizeof(double)); - x = (double *)malloc((r+1) * sizeof(double)); - y = (double *)malloc((r+1) * sizeof(double)); - ad = (double *)malloc((r+1) * sizeof(double)); - -/* - * Create dense frequency grid - */ - CreateDenseGrid(r, numtaps, numband, bands, des, weight, - gridsize, Grid, D, W, symmetry, griddensity); - InitialGuess(r, Ext, gridsize); - -/* - * For Differentiator: (fix grid) - */ - if (type == DIFFERENTIATOR) - { - for (i=0; i<gridsize; i++) - { -/* D[i] = D[i]*Grid[i]; */ - if (D[i] > 0.0001) - W[i] = W[i]/Grid[i]; - } - } - -/* - * For odd or Negative symmetry filters, alter the - * D[] and W[] according to Parks McClellan - */ - if (symmetry == POSITIVE) - { - if (numtaps % 2 == 0) - { - for (i=0; i<gridsize; i++) - { - c = cos(Pi * Grid[i]); - D[i] /= c; - W[i] *= c; - } - } - } - else - { - if (numtaps % 2) - { - for (i=0; i<gridsize; i++) - { - c = sin(Pi2 * Grid[i]); - D[i] /= c; - W[i] *= c; - } - } - else - { - for (i=0; i<gridsize; i++) - { - c = sin(Pi * Grid[i]); - D[i] /= c; - W[i] *= c; - } - } - } - -/* - * Perform the Remez Exchange algorithm - */ - for (iter=0; iter<MAXITERATIONS; iter++) - { - CalcParms(r, Ext, Grid, D, W, ad, x, y); - CalcError(r, ad, x, y, gridsize, Grid, D, W, E); - int err = Search(r, Ext, gridsize, E); - if (err) return err; - for(int i=0; i <= r; i++) assert(Ext[i]<gridsize); - if (isDone(r, Ext, E)) - break; - } - - CalcParms(r, Ext, Grid, D, W, ad, x, y); - -/* - * Find the 'taps' of the filter for use with Frequency - * Sampling. If odd or Negative symmetry, fix the taps - * according to Parks McClellan - */ - for (i=0; i<=numtaps/2; i++) - { - if (symmetry == POSITIVE) - { - if (numtaps%2) - c = 1; - else - c = cos(Pi * (double)i/numtaps); - } - else - { - if (numtaps%2) - c = sin(Pi2 * (double)i/numtaps); - else - c = sin(Pi * (double)i/numtaps); - } - taps[i] = ComputeA((double)i/numtaps, r, ad, x, y)*c; - } - -/* - * Frequency sampling design with calculated taps - */ - FreqSample(numtaps, taps, h, symmetry); - -/* - * Delete allocated memory - */ - free(Grid); - free(W); - free(D); - free(E); - free(Ext); - free(x); - free(y); - free(ad); - return iter<MAXITERATIONS?0:-1; -} - -////////////////////////////////////////////////////////////////////////////// -// -// GNU Radio interface -// -////////////////////////////////////////////////////////////////////////////// - - -static void -punt (const std::string msg) -{ - std::cerr << msg << '\n'; - throw std::runtime_error (msg); -} - -std::vector<double> -gr_remez (int order, - const std::vector<double> &arg_bands, - const std::vector<double> &arg_response, - const std::vector<double> &arg_weight, - const std::string filter_type, - int grid_density - ) throw (std::runtime_error) -{ - int numtaps = order + 1; - if (numtaps < 4) - punt ("gr_remez: number of taps must be >= 3"); - - int numbands = arg_bands.size () / 2; - LOCAL_BUFFER (double, bands, numbands * 2); - if (numbands < 1 || arg_bands.size () % 2 == 1) - punt ("gr_remez: must have an even number of band edges"); - - for (unsigned int i = 1; i < arg_bands.size (); i++){ - if (arg_bands[i] < arg_bands[i-1]) - punt ("gr_remez: band edges must be nondecreasing"); - } - - if (arg_bands[0] < 0 || arg_bands[arg_bands.size () - 1] > 1) - punt ("gr_remez: band edges must be in the range [0,1]"); - - // Divide by 2 to fit with the implementation that uses a - // sample rate of [0, 0.5] instead of [0, 1.0] - for (int i = 0; i < 2 * numbands; i++) - bands[i] = arg_bands[i] / 2; - - LOCAL_BUFFER (double, response, numbands * 2); - if (arg_response.size () != arg_bands.size ()) - punt ("gr_remez: must have one response magnitude for each band edge"); - - for (int i = 0; i < 2 * numbands; i++) - response[i] = arg_response[i]; - - LOCAL_BUFFER (double, weight, numbands); - for (int i = 0; i < numbands; i++) - weight[i] = 1.0; - - if (arg_weight.size () != 0){ - if ((int) arg_weight.size () != numbands) - punt ("gr_remez: need one weight for each band [=length(band)/2]"); - for (int i = 0; i < numbands; i++) - weight[i] = arg_weight [i]; - } - - int itype = 0; - if (filter_type == "bandpass") - itype = BANDPASS; - else if (filter_type == "differentiator") - itype = DIFFERENTIATOR; - else if (filter_type == "hilbert") - itype = HILBERT; - else - punt ("gr_remez: unknown ftype '" + filter_type + "'"); - - if (grid_density < 16) - punt ("gr_remez: grid_density is too low; must be >= 16"); - - LOCAL_BUFFER (double, coeff, numtaps + 5); // FIXME why + 5? - int err = remez (coeff, numtaps, numbands, - bands, response, weight, itype, grid_density); - - if (err == -1) - punt ("gr_remez: failed to converge"); - - if (err == -2) - punt ("gr_remez: insufficient extremals -- cannot continue"); - - if (err == -3) - punt ("gr_remez: too many extremals -- cannot continue"); - - return std::vector<double> (&coeff[0], &coeff[numtaps]); -} - - - -#if 0 -/* == Octave interface starts here ====================================== */ - -DEFUN_DLD (remez, args, , - "b = remez(n, f, a [, w] [, ftype] [, griddensity])\n\ -Parks-McClellan optimal FIR filter design.\n\ -n gives the number of taps in the returned filter\n\ -f gives frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...]\n\ -a gives amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...]\n\ -w gives weighting applied to each band\n\ -ftype is 'bandpass', 'hilbert' or 'differentiator'\n\ -griddensity determines how accurately the filter will be\n\ - constructed. The minimum value is 16, but higher numbers are\n\ - slower to compute.\n\ -\n\ -Frequency is in the range (0, 1), with 1 being the nyquist frequency") -{ - octave_value_list retval; - int i; - - int nargin = args.length(); - if (nargin < 3 || nargin > 6) { - print_usage("remez"); - return retval; - } - - int numtaps = NINT (args(0).double_value()) + 1; // #coeff = filter order+1 - if (numtaps < 4) { - error("remez: number of taps must be an integer greater than 3"); - return retval; - } - - ColumnVector o_bands(args(1).vector_value()); - int numbands = o_bands.length()/2; - OCTAVE_LOCAL_BUFFER(double, bands, numbands*2); - if (numbands < 1 || o_bands.length()%2 == 1) { - error("remez: must have an even number of band edges"); - return retval; - } - for (i=1; i < o_bands.length(); i++) { - if (o_bands(i)<o_bands(i-1)) { - error("band edges must be nondecreasing"); - return retval; - } - } - if (o_bands(0) < 0 || o_bands(1) > 1) { - error("band edges must be in the range [0,1]"); - return retval; - } - for(i=0; i < 2*numbands; i++) bands[i] = o_bands(i)/2.0; - - ColumnVector o_response(args(2).vector_value()); - OCTAVE_LOCAL_BUFFER (double, response, numbands*2); - if (o_response.length() != o_bands.length()) { - error("remez: must have one response magnitude for each band edge"); - return retval; - } - for(i=0; i < 2*numbands; i++) response[i] = o_response(i); - - std::string stype = std::string("bandpass"); - int density = 16; - OCTAVE_LOCAL_BUFFER (double, weight, numbands); - for (i=0; i < numbands; i++) weight[i] = 1.0; - if (nargin > 3) { - if (args(3).is_real_matrix()) { - ColumnVector o_weight(args(3).vector_value()); - if (o_weight.length() != numbands) { - error("remez: need one weight for each band [=length(band)/2]"); - return retval; - } - for (i=0; i < numbands; i++) weight[i] = o_weight(i); - } - else if (args(3).is_string()) - stype = args(3).string_value(); - else if (args(3).is_real_scalar()) - density = NINT(args(3).double_value()); - else { - error("remez: incorrect argument list"); - return retval; - } - } - if (nargin > 4) { - if (args(4).is_string() && !args(3).is_string()) - stype = args(4).string_value(); - else if (args(4).is_real_scalar() && !args(3).is_real_scalar()) - density = NINT(args(4).double_value()); - else { - error("remez: incorrect argument list"); - return retval; - } - } - if (nargin > 5) { - if (args(5).is_real_scalar() - && !args(4).is_real_scalar() - && !args(3).is_real_scalar()) - density = NINT(args(4).double_value()); - else { - error("remez: incorrect argument list"); - return retval; - } - } - - int itype; - if (stype == "bandpass") - itype = BANDPASS; - else if (stype == "differentiator") - itype = DIFFERENTIATOR; - else if (stype == "hilbert") - itype = HILBERT; - else { - error("remez: unknown ftype '%s'", stype.data()); - return retval; - } - - if (density < 16) { - error("remez: griddensity is too low; must be greater than 16"); - return retval; - } - - OCTAVE_LOCAL_BUFFER (double, coeff, numtaps+5); - int err = remez(coeff,numtaps,numbands,bands,response,weight,itype,density); - - if (err == -1) - warning("remez: -- failed to converge -- returned filter may be bad."); - else if (err == -2) { - error("remez: insufficient extremals--cannot continue"); - return retval; - } - else if (err == -3) { - error("remez: too many extremals--cannot continue"); - return retval; - } - - ColumnVector h(numtaps); - while(numtaps--) h(numtaps) = coeff[numtaps]; - - return octave_value(h); -} - -/* -%!test -%! b = [ -%! 0.0415131831103279 -%! 0.0581639884202646 -%! -0.0281579212691008 -%! -0.0535575358002337 -%! -0.0617245915143180 -%! 0.0507753178978075 -%! 0.2079018331396460 -%! 0.3327160895375440 -%! 0.3327160895375440 -%! 0.2079018331396460 -%! 0.0507753178978075 -%! -0.0617245915143180 -%! -0.0535575358002337 -%! -0.0281579212691008 -%! 0.0581639884202646 -%! 0.0415131831103279]; -%! assert(remez(15,[0,0.3,0.4,1],[1,1,0,0]),b,1e-14); - - */ - -#endif diff --git a/gnuradio-core/src/lib/general/gr_remez.h b/gnuradio-core/src/lib/general/gr_remez.h deleted file mode 100644 index d875b88229..0000000000 --- a/gnuradio-core/src/lib/general/gr_remez.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_GR_REMEZ_H -#define INCLUDED_GR_REMEZ_H - -#include <gr_core_api.h> -#include <gr_types.h> -#include <string> -#include <stdexcept> - -/*! - * \brief Parks-McClellan FIR filter design. - * - * \ingroup filter_design - * - * Calculates the optimal (in the Chebyshev/minimax sense) FIR filter - * inpulse reponse given a set of band edges, the desired reponse on - * those bands, and the weight given to the error in those bands. - * - * \param order filter order (number of taps in the returned filter - 1) - * \param bands frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...] - * \param ampl desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...] - * \param error_weight weighting applied to each band (usually 1) - * \param filter_type one of "bandpass", "hilbert" or "differentiator" - * \param grid_density determines how accurately the filter will be constructed. \ - * The minimum value is 16; higher values are slower to compute. - * - * Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2) - * - * \returns vector of computed taps - * - * \throws std::runtime_error if args are invalid or calculation fails to converge. - */ - -GR_CORE_API std::vector<double> -gr_remez (int order, - const std::vector<double> &bands, - const std::vector<double> &l, - const std::vector<double> &error_weight, - const std::string filter_type = "bandpass", - int grid_density = 16 - ) throw (std::runtime_error); - - -#endif /* INCLUDED_GR_REMEZ_H */ diff --git a/gnuradio-core/src/lib/general/gr_remez.i b/gnuradio-core/src/lib/general/gr_remez.i deleted file mode 100644 index fe3eea20da..0000000000 --- a/gnuradio-core/src/lib/general/gr_remez.i +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -%rename(remez) gr_remez; - -std::vector<double> -gr_remez (int order, - const std::vector<double> &bands, - const std::vector<double> &l, - const std::vector<double> &error_weight, - const std::string filter_type = "bandpass", - int grid_density = 16 - ) throw (std::runtime_error); diff --git a/gnuradio-core/src/lib/general/qa_general.cc b/gnuradio-core/src/lib/general/qa_general.cc index 75d59434d4..7f30c11e01 100644 --- a/gnuradio-core/src/lib/general/qa_general.cc +++ b/gnuradio-core/src/lib/general/qa_general.cc @@ -26,7 +26,6 @@ */ #include <qa_general.h> -#include <qa_gr_firdes.h> #include <qa_gr_circular_file.h> #include <qa_gr_fxpt.h> #include <qa_gr_fxpt_nco.h> @@ -38,7 +37,6 @@ qa_general::suite () { CppUnit::TestSuite *s = new CppUnit::TestSuite ("general"); - s->addTest (qa_gr_firdes::suite ()); s->addTest (qa_gr_circular_file::suite ()); s->addTest (qa_gr_fxpt::suite ()); s->addTest (qa_gr_fxpt_nco::suite ()); diff --git a/gnuradio-core/src/lib/general/qa_gr_firdes.cc b/gnuradio-core/src/lib/general/qa_gr_firdes.cc deleted file mode 100644 index 877b4bd561..0000000000 --- a/gnuradio-core/src/lib/general/qa_gr_firdes.cc +++ /dev/null @@ -1,618 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2002 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#include <qa_gr_firdes.h> -#include <gr_firdes.h> -#include <cppunit/TestAssert.h> -#include <gr_complex.h> -#include <string.h> -#include <iostream> -#include <iomanip> -#include <stdio.h> - -#define NELEM(x) (sizeof (x) / sizeof (x[0])) - -using std::vector; - -#if 0 -static void -print_taps (std::ostream &s, vector<float> &v) -{ - - for (unsigned int i = 0; i < v.size (); i++){ - printf ("tap[%2d] = %16.7e\n", i, v[i]); - } -} -#endif - -static void -check_symmetry (vector<float> &v) -{ - int n = v.size (); - int m = n / 2; - - for (int i = 0; i < m; i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL (v[i], v[n - i - 1], 1e-9); -} - -const static float t1_exp[53] = { - -9.0525491e-04, - 2.0713841e-04, - 1.2388536e-03, - 2.9683491e-04, - -1.7744775e-03, - -1.3599906e-03, - 2.2031884e-03, - 3.2744040e-03, - -1.8868084e-03, - -5.9935520e-03, - 6.4301129e-18, - 8.9516686e-03, - 4.2178580e-03, - -1.0998557e-02, - -1.1173409e-02, - 1.0455756e-02, - 2.0686293e-02, - -5.2032238e-03, - -3.1896964e-02, - -7.4998410e-03, - 4.3362070e-02, - 3.2502845e-02, - -5.3328082e-02, - -8.5621715e-02, - 6.0117975e-02, - 3.1128189e-01, - 4.3769023e-01, - 3.1128189e-01, - 6.0117975e-02, - -8.5621715e-02, - -5.3328082e-02, - 3.2502845e-02, - 4.3362070e-02, - -7.4998410e-03, - -3.1896964e-02, - -5.2032238e-03, - 2.0686293e-02, - 1.0455756e-02, - -1.1173409e-02, - -1.0998557e-02, - 4.2178580e-03, - 8.9516686e-03, - 6.4301129e-18, - -5.9935520e-03, - -1.8868084e-03, - 3.2744040e-03, - 2.2031884e-03, - -1.3599906e-03, - -1.7744775e-03, - 2.9683491e-04, - 1.2388536e-03, - 2.0713841e-04, - -9.0525491e-04 -}; - -const static float t2_exp[53] = { - 9.0380036e-04, - -2.0680559e-04, - -1.2368630e-03, - -2.9635796e-04, - 1.7716263e-03, - 1.3578053e-03, - -2.1996482e-03, - -3.2691427e-03, - 1.8837767e-03, - 5.9839217e-03, - -6.4197810e-18, - -8.9372853e-03, - -4.2110807e-03, - 1.0980885e-02, - 1.1155456e-02, - -1.0438956e-02, - -2.0653054e-02, - 5.1948633e-03, - 3.1845711e-02, - 7.4877902e-03, - -4.3292396e-02, - -3.2450620e-02, - 5.3242393e-02, - 8.5484132e-02, - -6.0021374e-02, - -3.1078172e-01, - 5.6184036e-01, - -3.1078172e-01, - -6.0021374e-02, - 8.5484132e-02, - 5.3242393e-02, - -3.2450620e-02, - -4.3292396e-02, - 7.4877902e-03, - 3.1845711e-02, - 5.1948633e-03, - -2.0653054e-02, - -1.0438956e-02, - 1.1155456e-02, - 1.0980885e-02, - -4.2110807e-03, - -8.9372853e-03, - -6.4197810e-18, - 5.9839217e-03, - 1.8837767e-03, - -3.2691427e-03, - -2.1996482e-03, - 1.3578053e-03, - 1.7716263e-03, - -2.9635796e-04, - -1.2368630e-03, - -2.0680559e-04, - 9.0380036e-04 -}; - -const static float t3_exp[107] = { - -1.8970841e-06, - -7.1057165e-04, - 5.4005696e-04, - 4.6233178e-04, - 2.0572044e-04, - 3.5209916e-04, - -1.4098573e-03, - 1.1279077e-04, - -6.2994129e-04, - 1.1450432e-03, - 1.3637283e-03, - -6.4360141e-04, - 3.6509900e-04, - -3.2864159e-03, - 7.0192874e-04, - 3.7524730e-04, - 2.0256115e-03, - 3.0641893e-03, - -3.6618244e-03, - 7.5592739e-05, - -5.5586505e-03, - 2.3849572e-03, - 4.0114378e-03, - 1.6636450e-03, - 4.7835698e-03, - -1.0191196e-02, - -3.8158931e-04, - -5.5551580e-03, - 5.3901658e-03, - 1.1366769e-02, - -3.0000482e-03, - 4.9341680e-03, - -2.0093076e-02, - 5.5752542e-17, - 1.2093617e-03, - 8.6089745e-03, - 2.2382140e-02, - -1.6854567e-02, - 1.6913920e-03, - -3.1222520e-02, - 3.2711059e-03, - 2.2604836e-02, - 8.1451107e-03, - 3.7583180e-02, - -5.2293688e-02, - -8.0551542e-03, - -4.0092729e-02, - 1.5582236e-02, - 9.7452506e-02, - -1.6183170e-02, - 8.3281815e-02, - -2.8196752e-01, - -1.0965768e-01, - 5.2867508e-01, - -1.0965768e-01, - -2.8196752e-01, - 8.3281815e-02, - -1.6183170e-02, - 9.7452506e-02, - 1.5582236e-02, - -4.0092729e-02, - -8.0551542e-03, - -5.2293688e-02, - 3.7583180e-02, - 8.1451107e-03, - 2.2604836e-02, - 3.2711059e-03, - -3.1222520e-02, - 1.6913920e-03, - -1.6854567e-02, - 2.2382140e-02, - 8.6089745e-03, - 1.2093617e-03, - 5.5752542e-17, - -2.0093076e-02, - 4.9341680e-03, - -3.0000482e-03, - 1.1366769e-02, - 5.3901658e-03, - -5.5551580e-03, - -3.8158931e-04, - -1.0191196e-02, - 4.7835698e-03, - 1.6636450e-03, - 4.0114378e-03, - 2.3849572e-03, - -5.5586505e-03, - 7.5592739e-05, - -3.6618244e-03, - 3.0641893e-03, - 2.0256115e-03, - 3.7524730e-04, - 7.0192874e-04, - -3.2864159e-03, - 3.6509900e-04, - -6.4360141e-04, - 1.3637283e-03, - 1.1450432e-03, - -6.2994129e-04, - 1.1279077e-04, - -1.4098573e-03, - 3.5209916e-04, - 2.0572044e-04, - 4.6233178e-04, - 5.4005696e-04, - -7.1057165e-04, - -1.8970841e-06 -}; - - -const static float t4_exp[] = { // low pass - 0.001059958362, -0.0002263929928, --0.001277606934, --0.0009675776237, - 0.001592264394, - 0.00243603508, --0.001451682881, --0.004769335967, -5.281541594e-18, - 0.007567512803, - 0.003658855334, --0.009761494584, - -0.01011830103, - 0.009636915289, - 0.0193619132, --0.004935568199, - -0.03060629964, --0.007267376408, - 0.04236677289, - 0.03197422624, - -0.05274848267, - -0.0850463286, - 0.05989059806, - 0.31065014, - 0.4370569289, - 0.31065014, - 0.05989059806, - -0.0850463286, - -0.05274848267, - 0.03197422624, - 0.04236677289, --0.007267376408, - -0.03060629964, --0.004935568199, - 0.0193619132, - 0.009636915289, - -0.01011830103, --0.009761494584, - 0.003658855334, - 0.007567512803, -5.281541594e-18, --0.004769335967, --0.001451682881, - 0.00243603508, - 0.001592264394, --0.0009675776237, --0.001277606934, -0.0002263929928, - 0.001059958362, -}; - - -const static float t5_exp[] = { //high pass --0.001062123571, --0.0002268554381, - 0.001280216733, - 0.000969554123, --0.001595516922, --0.002441011136, - 0.001454648213, - 0.004779078532, --5.292330097e-18, --0.007582970895, - -0.00366632943, - 0.009781434201, - 0.01013896987, --0.009656600654, - -0.01940146461, - 0.004945650231, - 0.03066881932, - 0.00728222169, - -0.04245331511, - -0.03203954175, - 0.05285623297, - 0.08522006124, - -0.06001294032, - -0.3112847209, - 0.5630782247, - -0.3112847209, - -0.06001294032, - 0.08522006124, - 0.05285623297, - -0.03203954175, - -0.04245331511, - 0.00728222169, - 0.03066881932, - 0.004945650231, - -0.01940146461, --0.009656600654, - 0.01013896987, - 0.009781434201, - -0.00366632943, --0.007582970895, --5.292330097e-18, - 0.004779078532, - 0.001454648213, --0.002441011136, --0.001595516922, - 0.000969554123, - 0.001280216733, --0.0002268554381, --0.001062123571, -}; - -const static float t6_exp[] = { // bandpass -0.0002809273137, --0.001047327649, -7.936541806e-05, --0.0004270860809, -0.0007595835486, -0.0008966081077, --0.0004236323002, -0.0002423936094, --0.002212299034, -0.0004807534278, -0.0002620361629, - 0.001443728455, - 0.002229931997, --0.002720607212, -5.731141573e-05, --0.004297634587, - 0.001878833398, - 0.003217151389, - 0.001357055153, - 0.003965090029, --0.008576190099, --0.0003257228818, --0.004805727862, - 0.004721920472, - 0.01007549558, --0.002688719891, - 0.004467967432, - -0.01837076992, -5.119658377e-17, - 0.001125075156, - 0.008071650751, - 0.02113764361, - -0.01602453552, - 0.001618095324, - -0.03004053794, - 0.003163811285, - 0.0219683405, - 0.007950295694, - 0.03682873398, - -0.05142467469, - -0.00794606097, - -0.03965795785, - 0.01544955093, - 0.09681399167, - -0.01610304788, - 0.08297294378, - -0.2811714709, - -0.1094062924, - 0.5275565982, - -0.1094062924, - -0.2811714709, - 0.08297294378, - -0.01610304788, - 0.09681399167, - 0.01544955093, - -0.03965795785, - -0.00794606097, - -0.05142467469, - 0.03682873398, - 0.007950295694, - 0.0219683405, - 0.003163811285, - -0.03004053794, - 0.001618095324, - -0.01602453552, - 0.02113764361, - 0.008071650751, - 0.001125075156, -5.119658377e-17, - -0.01837076992, - 0.004467967432, --0.002688719891, - 0.01007549558, - 0.004721920472, --0.004805727862, --0.0003257228818, --0.008576190099, - 0.003965090029, - 0.001357055153, - 0.003217151389, - 0.001878833398, --0.004297634587, -5.731141573e-05, --0.002720607212, - 0.002229931997, - 0.001443728455, -0.0002620361629, -0.0004807534278, --0.002212299034, -0.0002423936094, --0.0004236323002, -0.0008966081077, -0.0007595835486, --0.0004270860809, -7.936541806e-05, --0.001047327649, -0.0002809273137, -}; - -void -qa_gr_firdes::t1 () -{ - vector<float> taps = - gr_firdes::low_pass ( 1.0, - 8000, - 1750, - 500, - gr_firdes::WIN_HAMMING); - - // cout << "ntaps: " << taps.size () << endl; - // print_taps (cout, taps); - - CPPUNIT_ASSERT_EQUAL (NELEM (t1_exp), taps.size ()); - for (unsigned int i = 0; i < taps.size (); i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL (t1_exp[i], taps[i], 1e-9); - - check_symmetry (taps); -} - -void -qa_gr_firdes::t2 () -{ - vector<float> taps = - gr_firdes::high_pass ( 1.0, - 8000, - 1750, - 500, - gr_firdes::WIN_HAMMING); - - // cout << "ntaps: " << taps.size () << endl; - // print_taps (cout, taps); - - CPPUNIT_ASSERT_EQUAL (NELEM (t2_exp), taps.size ()); - - for (unsigned int i = 0; i < taps.size (); i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL (t2_exp[i], taps[i], 1e-9); - - check_symmetry (taps); -} - -void -qa_gr_firdes::t3 () -{ - vector<float> taps = - gr_firdes::band_pass ( 1.0, - 20e6, - 5.75e6 - (5.28e6/2), - 5.75e6 + (5.28e6/2), - 0.62e6, - gr_firdes::WIN_HAMMING); - - // cout << "ntaps: " << taps.size () << endl; - // print_taps (cout, taps); - - CPPUNIT_ASSERT_EQUAL (NELEM (t3_exp), taps.size ()); - - for (unsigned int i = 0; i < taps.size (); i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL (t3_exp[i], taps[i], 1e-7); - - check_symmetry (taps); -} - -void -qa_gr_firdes::t4 () -{ - vector<float> taps = - gr_firdes::low_pass_2 ( 1.0, - 8000, - 1750, - 500, - 66, - gr_firdes::WIN_HAMMING); - - // std::cout << "ntaps: " << taps.size () << std::endl; - // print_taps (std::cout, taps); - - CPPUNIT_ASSERT_EQUAL (NELEM (t4_exp), taps.size ()); - for (unsigned int i = 0; i < taps.size (); i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL (t4_exp[i], taps[i], 1e-9); - - - check_symmetry (taps); -} - -void -qa_gr_firdes::t5 () -{ - vector<float> taps = - gr_firdes::high_pass_2 ( 1.0, - 8000, - 1750, - 500, - 66, - gr_firdes::WIN_HAMMING); - - // std::cout << "ntaps: " << taps.size () << std::endl; - // print_taps (std::cout, taps); - - CPPUNIT_ASSERT_EQUAL (NELEM (t5_exp), taps.size ()); - - for (unsigned int i = 0; i < taps.size (); i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL (t5_exp[i], taps[i], 1e-9); - - check_symmetry (taps); -} - -void -qa_gr_firdes::t6 () -{ - vector<float> taps = - gr_firdes::band_pass_2 ( 1.0, - 20e6, - 5.75e6 - (5.28e6/2), - 5.75e6 + (5.28e6/2), - 0.62e6, - 66, - gr_firdes::WIN_HAMMING); - - // std::cout << "ntaps: " << taps.size () << std::endl; - // print_taps (std::cout, taps); - - CPPUNIT_ASSERT_EQUAL (NELEM (t6_exp), taps.size ()); - - for (unsigned int i = 0; i < taps.size (); i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL (t6_exp[i], taps[i], 1e-7); - - check_symmetry (taps); -} - -void -qa_gr_firdes::t7 () -{ -} diff --git a/gnuradio-core/src/lib/general/qa_gr_firdes.h b/gnuradio-core/src/lib/general/qa_gr_firdes.h deleted file mode 100644 index 98cee99b97..0000000000 --- a/gnuradio-core/src/lib/general/qa_gr_firdes.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2002 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -#ifndef _QA_GR_FIRDES_H_ -#define _QA_GR_FIRDES_H_ - -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCase.h> - -class qa_gr_firdes : public CppUnit::TestCase { - - CPPUNIT_TEST_SUITE (qa_gr_firdes); - CPPUNIT_TEST (t1); - CPPUNIT_TEST (t2); - CPPUNIT_TEST (t3); - CPPUNIT_TEST (t4); - CPPUNIT_TEST (t5); - CPPUNIT_TEST (t6); - CPPUNIT_TEST (t7); - CPPUNIT_TEST_SUITE_END (); - - private: - void t1 (); - void t2 (); - void t3 (); - void t4 (); - void t5 (); - void t6 (); - void t7 (); - -}; - - -#endif /* _QA_GR_FIRDES_H_ */ diff --git a/gnuradio-core/src/lib/runtime/qa_block_tags.cc b/gnuradio-core/src/lib/runtime/qa_block_tags.cc index d3ae476027..c3c18cac01 100644 --- a/gnuradio-core/src/lib/runtime/qa_block_tags.cc +++ b/gnuradio-core/src/lib/runtime/qa_block_tags.cc @@ -23,6 +23,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif + #include <qa_block_tags.h> #include <gr_block.h> #include <gr_top_block.h> @@ -31,8 +32,6 @@ #include <gr_head.h> #include <gr_annotator_alltoall.h> #include <gr_annotator_1to1.h> -//#include <gr_keep_one_in_n.h> -#include <gr_firdes.h> #include <gr_tags.h> diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py b/gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py index f797271970..dfa67feffe 100644 --- a/gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py +++ b/gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py @@ -22,6 +22,7 @@ from gnuradio import gr from gnuradio import blocks +from gnuradio import filter import sys, time try: @@ -289,7 +290,7 @@ class GrDataPlotterPsdC(GrDataPlotParent): self._iscomplex = True self._npts = 2048 - self._wintype = gr.firdes.WIN_BLACKMAN_hARRIS + self._wintype = filter.firdes.WIN_BLACKMAN_hARRIS self._fc = 0 self._setup(1) @@ -322,7 +323,7 @@ class GrDataPlotterPsdF(GrDataPlotParent): self._iscomplex = False self._npts = 2048 - self._wintype = gr.firdes.WIN_BLACKMAN_hARRIS + self._wintype = filter.firdes.WIN_BLACKMAN_hARRIS self._fc = 0 self._setup(1) diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py b/gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py index defc47b59f..162bae5633 100755 --- a/gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py +++ b/gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py @@ -28,6 +28,7 @@ import math import numpy from gnuradio import gr +from gnuradio import filter from gnuradio.gruimpl.freqz import freqz @@ -69,11 +70,11 @@ def gnuplot_freqz (hw, Fs=None, logfreq=False): def test_plot (): sample_rate = 2.0e6 - taps = gr.firdes.low_pass (1.0, # gain - sample_rate, # sampling rate - 200e3, # low pass cutoff freq - 100e3, # width of trans. band - gr.firdes.WIN_HAMMING) + taps = filter.firdes.low_pass (1.0, # gain + sample_rate, # sampling rate + 200e3, # low pass cutoff freq + 100e3, # width of trans. band + filter.firdes.WIN_HAMMING) # print len (taps) return gnuplot_freqz (freqz (taps, 1), sample_rate) |