From 5d69a524f81f234b3fbc41d49ba18d6f6886baba Mon Sep 17 00:00:00 2001 From: jcorgan Date: Thu, 3 Aug 2006 04:51:51 +0000 Subject: Houston, we have a trunk. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@3122 221aa14e-8319-0410-a670-987f0aec2ac5 --- gnuradio-core/src/lib/general/gr_firdes.cc | 584 +++++++++++++++++++++++++++++ 1 file changed, 584 insertions(+) create mode 100644 gnuradio-core/src/lib/general/gr_firdes.cc (limited to 'gnuradio-core/src/lib/general/gr_firdes.cc') diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc new file mode 100644 index 000000000..d09d68d61 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -0,0 +1,584 @@ +/* -*- 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 2, 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + + +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 +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 taps(ntaps); + vector 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 +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 taps(ntaps); + vector 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 +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 taps(ntaps); + vector 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_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 taps(ntaps); + vector lptaps(ntaps); + vector 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 +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 taps(ntaps); + vector 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 +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 taps(ntaps); + vector 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 +gr_firdes::gaussian (double gain, + double spb, + double bt, + int ntaps) +{ + + vector taps(ntaps); + double scale = 0; + double dt = 1.0/spb; + double s = 1.0/(sqrt(log(2)) / (2*M_PI*bt)); + double t0 = -0.5 * ntaps; + double ts; + for(int i=0;i +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 taps(ntaps); + double scale = 0; + for(int i=0;i= 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 +gr_firdes::window (win_type type, int ntaps, double beta) +{ + vector 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; + +#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 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"); +} -- cgit From 86f5c92427b3f4bb30536d76cf63c3fca388fb2f Mon Sep 17 00:00:00 2001 From: eb Date: Wed, 13 Sep 2006 21:30:04 +0000 Subject: Updated FSF address in all files. Fixes ticket:51 git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@3534 221aa14e-8319-0410-a670-987f0aec2ac5 --- gnuradio-core/src/lib/general/gr_firdes.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gnuradio-core/src/lib/general/gr_firdes.cc') diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc index d09d68d61..994424edf 100644 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -16,8 +16,8 @@ * * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. */ #include -- cgit From 5f11df3a837bfe56013b9483e5d8dd931b1aaf4e Mon Sep 17 00:00:00 2001 From: eb Date: Mon, 4 Dec 2006 23:39:26 +0000 Subject: fix for ticket:113 gr_firdes::band_reject git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@4055 221aa14e-8319-0410-a670-987f0aec2ac5 --- gnuradio-core/src/lib/general/gr_firdes.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnuradio-core/src/lib/general/gr_firdes.cc') diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc index 994424edf..87724fcdf 100644 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -272,7 +272,7 @@ gr_firdes::band_reject (double gain, for (int n = -M; n <= M; n++){ if (n == 0) - taps[n + M] = (1.0 + (fwT0 - fwT1)) / M_PI * w[n + M]; + 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]; } -- cgit From 937b719d2e57d0497293d603da10cac2532346f6 Mon Sep 17 00:00:00 2001 From: eb Date: Sat, 21 Jul 2007 03:44:38 +0000 Subject: Updated license from GPL version 2 or later to GPL version 3 or later. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@6044 221aa14e-8319-0410-a670-987f0aec2ac5 --- gnuradio-core/src/lib/general/gr_firdes.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnuradio-core/src/lib/general/gr_firdes.cc') diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc index 87724fcdf..7b449af95 100644 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -6,7 +6,7 @@ * * 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 2, or (at your option) + * 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, -- cgit From 415910cb8d48e33edf3289e2ba7b4a7b7f352cdd Mon Sep 17 00:00:00 2001 From: eb Date: Fri, 31 Aug 2007 01:59:32 +0000 Subject: Attempt to simplify conditions for ticket:181. Didn't fix problem, but didn't harm anything either. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@6236 221aa14e-8319-0410-a670-987f0aec2ac5 --- gnuradio-core/src/lib/general/gr_firdes.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gnuradio-core/src/lib/general/gr_firdes.cc') diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc index 7b449af95..06730b7f8 100644 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002 Free Software Foundation, Inc. + * Copyright 2002,2007 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -518,7 +518,7 @@ gr_firdes::window (win_type type, int ntaps, double beta) #endif default: - throw std::runtime_error ("not_implemented"); + throw std::out_of_range ("gr_firdes:window: type out of range"); } return taps; -- cgit From a3c5490e99dc21f24432c984cbdf0763e585a391 Mon Sep 17 00:00:00 2001 From: n4hy Date: Mon, 18 Aug 2008 22:36:19 +0000 Subject: New taps computation based on requested transition bandwidth and stopband attenuation. qa code testing each added git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@9316 221aa14e-8319-0410-a670-987f0aec2ac5 --- gnuradio-core/src/lib/general/gr_firdes.cc | 270 +++++++++++++++++++++++++++-- 1 file changed, 258 insertions(+), 12 deletions(-) (limited to 'gnuradio-core/src/lib/general/gr_firdes.cc') diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc index 06730b7f8..17c40d78a 100644 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -50,6 +50,53 @@ static double Izero(double x) // === Low Pass === // +vector +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 taps(ntaps); + vector 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 gr_firdes::low_pass (double gain, double sampling_freq, @@ -74,7 +121,7 @@ gr_firdes::low_pass (double gain, for (int n = -M; n <= M; n++){ if (n == 0) - taps[n + M] = fwT0 / M_PI * w[n + M]; + 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]; @@ -96,22 +143,71 @@ gr_firdes::low_pass (double gain, return taps; } + // // === High Pass === // +vector +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 taps(ntaps); + vector 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 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 + 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); + window_type, beta); // construct the truncated ideal impulse response times the window function @@ -129,15 +225,15 @@ gr_firdes::high_pass (double gain, 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 + gain /= fmax; // normalize for (int i = 0; i < ntaps; i++) taps[i] *= gain; @@ -146,9 +242,57 @@ gr_firdes::high_pass (double gain, } // -// === Band Pass === +// === Band Pass === // +vector +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 taps(ntaps); + vector 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 gr_firdes::band_pass (double gain, double sampling_freq, @@ -201,6 +345,47 @@ gr_firdes::band_pass (double gain, // === Complex Band Pass === // +vector +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 taps(ntaps); + vector lptaps(ntaps); + vector 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 gr_firdes::complex_band_pass (double gain, double sampling_freq, @@ -240,11 +425,59 @@ gr_firdes::complex_band_pass (double gain, return taps; } - // // === Band Reject === // +vector +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 taps(ntaps); + vector 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 gr_firdes::band_reject (double gain, double sampling_freq, @@ -427,6 +660,19 @@ static const float width_factor[5] = { // indexed by win_type 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, -- cgit From af6842f337a6d7c640827a2bdcba89a8fecd63b2 Mon Sep 17 00:00:00 2001 From: n4hy Date: Sat, 4 Oct 2008 19:08:56 +0000 Subject: fixing copyleft in gr_firdes.cc and .h git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@9714 221aa14e-8319-0410-a670-987f0aec2ac5 --- gnuradio-core/src/lib/general/gr_firdes.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnuradio-core/src/lib/general/gr_firdes.cc') diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc index 17c40d78a..3eaa9c8d9 100644 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002,2007 Free Software Foundation, Inc. + * Copyright 2002,2007,2008 Free Software Foundation, Inc. * * This file is part of GNU Radio * -- cgit From 144fa44ed2e0378e2ec585c3991108926d9449be Mon Sep 17 00:00:00 2001 From: trondeau Date: Sat, 25 Oct 2008 23:29:43 +0000 Subject: Merging qtgui branch-r9068:9837: this ads a qtgui_sink_c and qtgui_sink_f that displays the time, PSD, and spectrogram plots of a signal put into it. It requires qt4, qwt, and qwtplot3d and has not been tested on OSX. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@9853 221aa14e-8319-0410-a670-987f0aec2ac5 --- gnuradio-core/src/lib/general/gr_firdes.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gnuradio-core/src/lib/general/gr_firdes.cc') diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc index 3eaa9c8d9..8efeb3438 100644 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -739,6 +739,12 @@ gr_firdes::window (win_type type, int ntaps, double beta) 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++) -- cgit From e4d3b484edb2e852932d9da3d328273d4d35f475 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 17 Jan 2011 16:45:33 -0800 Subject: math explicit type overloads: Use explicit data type casts in math functions where the overloaded function could not be determined. affects msvc --- gnuradio-core/src/lib/general/gr_firdes.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnuradio-core/src/lib/general/gr_firdes.cc') diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc index 8efeb3438..5d192d67e 100644 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -574,7 +574,7 @@ gr_firdes::gaussian (double gain, vector taps(ntaps); double scale = 0; double dt = 1.0/spb; - double s = 1.0/(sqrt(log(2)) / (2*M_PI*bt)); + double s = 1.0/(sqrt(log(2.0)) / (2*M_PI*bt)); double t0 = -0.5 * ntaps; double ts; for(int i=0;i +#endif + #include #include -- cgit From f919f9dcbb54a08e6e26d6c229ce92fb784fa1b2 Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Fri, 13 Apr 2012 18:36:53 -0400 Subject: Removed whitespace and added dtools/bin/remove-whitespace as a tool to do this in the future. The sed script was provided by Moritz Fischer. --- gnuradio-core/src/lib/general/gr_firdes.cc | 54 +++++++++++++++--------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'gnuradio-core/src/lib/general/gr_firdes.cc') diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc index 13110d57d..4c7237141 100644 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -1,19 +1,19 @@ /* -*- 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, @@ -84,10 +84,10 @@ gr_firdes::low_pass_2(double gain, 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]; @@ -131,10 +131,10 @@ gr_firdes::low_pass (double gain, 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]; @@ -280,10 +280,10 @@ gr_firdes::band_pass_2 (double gain, 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); @@ -329,10 +329,10 @@ gr_firdes::band_pass (double gain, 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); @@ -385,7 +385,7 @@ gr_firdes::complex_band_pass_2 (double gain, *optr++ = gr_complex(*iptr * cos(phase),*iptr * sin(phase)); iptr++, phase += freq; } - + return taps; } @@ -425,7 +425,7 @@ gr_firdes::complex_band_pass (double gain, *optr++ = gr_complex(*iptr * cos(phase),*iptr * sin(phase)); iptr++, phase += freq; } - + return taps; } @@ -466,10 +466,10 @@ gr_firdes::band_reject_2 (double gain, 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]; @@ -514,10 +514,10 @@ gr_firdes::band_reject (double gain, 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]; @@ -536,7 +536,7 @@ gr_firdes::band_reject (double gain, vector gr_firdes::hilbert (unsigned int ntaps, - win_type windowtype, + win_type windowtype, double beta) { if(!(ntaps & 1)) @@ -745,7 +745,7 @@ gr_firdes::window (win_type type, int ntaps, double beta) 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) + + 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; @@ -790,7 +790,7 @@ gr_firdes::sanity_check_1f (double sampling_freq, 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"); } @@ -806,13 +806,13 @@ gr_firdes::sanity_check_2f (double sampling_freq, 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"); } @@ -828,13 +828,13 @@ gr_firdes::sanity_check_2f_c (double sampling_freq, 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"); } -- cgit