summaryrefslogtreecommitdiff
path: root/gr-channels/lib
diff options
context:
space:
mode:
Diffstat (limited to 'gr-channels/lib')
-rw-r--r--gr-channels/lib/CMakeLists.txt5
-rw-r--r--gr-channels/lib/fading_model_impl.cc16
-rw-r--r--gr-channels/lib/flat_fader_impl.cc73
-rw-r--r--gr-channels/lib/flat_fader_impl.h3
-rw-r--r--gr-channels/lib/selective_fading_model2_impl.cc204
-rw-r--r--gr-channels/lib/selective_fading_model2_impl.h87
-rw-r--r--gr-channels/lib/selective_fading_model_impl.cc10
7 files changed, 345 insertions, 53 deletions
diff --git a/gr-channels/lib/CMakeLists.txt b/gr-channels/lib/CMakeLists.txt
index 52b6222b62..d025889edb 100644
--- a/gr-channels/lib/CMakeLists.txt
+++ b/gr-channels/lib/CMakeLists.txt
@@ -46,6 +46,7 @@ list(APPEND channels_sources
dynamic_channel_model_impl.cc
fading_model_impl.cc
selective_fading_model_impl.cc
+ selective_fading_model2_impl.cc
flat_fader_impl.cc
cfo_model_impl.cc
sro_model_impl.cc
@@ -76,7 +77,7 @@ list(APPEND channels_libs
add_library(gnuradio-channels SHARED ${channels_sources})
target_link_libraries(gnuradio-channels ${channels_libs})
-GR_LIBRARY_FOO(gnuradio-channels RUNTIME_COMPONENT "channels_runtime" DEVEL_COMPONENT "channels_devel")
+GR_LIBRARY_FOO(gnuradio-channels)
add_dependencies(gnuradio-channels
channels_generated_includes channels_generated_swigs
gnuradio-runtime gnuradio-filter gnuradio-analog gnuradio-blocks)
@@ -108,6 +109,6 @@ if(ENABLE_STATIC_LIBS)
endif(NOT WIN32)
install(TARGETS gnuradio-channels_static
- ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT "channels_devel" # .lib file
+ ARCHIVE DESTINATION lib${LIB_SUFFIX} # .lib file
)
endif(ENABLE_STATIC_LIBS)
diff --git a/gr-channels/lib/fading_model_impl.cc b/gr-channels/lib/fading_model_impl.cc
index 7eb9d0612c..8e88efc200 100644
--- a/gr-channels/lib/fading_model_impl.cc
+++ b/gr-channels/lib/fading_model_impl.cc
@@ -22,17 +22,6 @@
#include "fading_model_impl.h"
#include <gnuradio/io_signature.h>
-#include <iostream>
-
-#include <boost/format.hpp>
-#include <boost/random.hpp>
-
-#include <gnuradio/fxpt.h>
-#include <sincostable.h>
-
-
-// FASTSINCOS: 0 = slow native, 1 = gr::fxpt impl, 2 = sincostable.h
-#define FASTSINCOS 2
namespace gr {
@@ -116,8 +105,11 @@ namespace gr {
{
const gr_complex* in = (const gr_complex*) input_items[0];
gr_complex* out = (gr_complex*) output_items[0];
+ std::vector<gr_complex> ftaps;
+ d_fader.next_samples(ftaps, noutput_items);
for(int i=0; i<noutput_items; i++){
- out[i] = in[i] * d_fader.next_sample();
+ out[i] = in[i] * ftaps[i];
+ //out[i] = in[i] * d_fader.next_sample();
}
return noutput_items;
}
diff --git a/gr-channels/lib/flat_fader_impl.cc b/gr-channels/lib/flat_fader_impl.cc
index 0b4cab2337..47834175f3 100644
--- a/gr-channels/lib/flat_fader_impl.cc
+++ b/gr-channels/lib/flat_fader_impl.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2013 Free Software Foundation, Inc.
+ * Copyright 2016 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -48,7 +48,7 @@ namespace gr {
d_table(8*1024),
- scale_sin(sqrtf(2.0/d_N)),
+ scale_sin(sqrtf(1.0/d_N)),
scale_los(sqrtf(d_K)/sqrtf(d_K+1)),
scale_nlos(1/sqrtf(d_K+1))
{
@@ -59,47 +59,47 @@ namespace gr {
}
}
-
- gr_complex flat_fader_impl::next_sample(){
- gr_complex H(0,0);
-
- for(int n=1; n<d_N; n++){
- float alpha_n = (2*M_PI*n - M_PI + d_theta)/(4*d_N);
#if FASTSINCOS == 1
- float s_i = scale_sin*gr::fxpt::cos(gr::fxpt::float_to_fixed(2*M_PI*d_fDTs*d_m*gr::fxpt::cos(gr::fxpt::float_to_fixed(alpha_n))+d_psi[n+1]));
- float s_q = scale_sin*gr::fxpt::cos(gr::fxpt::float_to_fixed(2*M_PI*d_fDTs*d_m*gr::fxpt::sin(gr::fxpt::float_to_fixed(alpha_n))+d_phi[n+1]));
+#define _GRFASTSIN(x) gr::fxpt::sin(gr::fxpt::float_to_fixed(x))
+#define _GRFASTCOS(x) gr::fxpt::cos(gr::fxpt::float_to_fixed(x))
#elif FASTSINCOS == 2
- float s_i = scale_sin*d_table.cos(2*M_PI*d_fDTs*d_m*d_table.cos(alpha_n)+d_psi[n+1]);
- float s_q = scale_sin*d_table.cos(2*M_PI*d_fDTs*d_m*d_table.sin(alpha_n)+d_phi[n+1]);
-
+#define _GRFASTSIN(x) d_table.sin(x)
+#define _GRFASTCOS(x) d_table.cos(x)
#else
- float s_i = scale_sin*cos(2*M_PI*d_fDTs*d_m*cos(alpha_n)+d_psi[n+1]);
- float s_q = scale_sin*cos(2*M_PI*d_fDTs*d_m*sin(alpha_n)+d_phi[n+1]);
+#define _GRFASTSIN(x) sin(x)
+#define _GRFASTCOS(x) cos(x)
#endif
- H += gr_complex(s_i, s_q);
+ void flat_fader_impl::next_samples(std::vector<gr_complex> &Hvec, int n_samples){
+ Hvec.resize(n_samples);
+ for(int i = 0; i < n_samples; i++){
+ gr_complex H(0,0);
+ for(int n=1; n<d_N+1; n++){
+ float alpha_n = (2*M_PI*n - M_PI + d_theta)/(4*d_N);
+ d_psi[n] = fmod(d_psi[n] + 2*M_PI*d_fDTs*_GRFASTCOS(alpha_n), 2*M_PI);
+ d_phi[n] = fmod(d_phi[n] + 2*M_PI*d_fDTs*_GRFASTCOS(alpha_n), 2*M_PI);
+ float s_i = scale_sin*_GRFASTCOS(d_psi[n]);
+ float s_q = scale_sin*_GRFASTSIN(d_phi[n]);
+ H += gr_complex(s_i, s_q);
+ }
+
+ if(d_LOS){
+ d_psi[0] = fmod(d_psi[0] + 2*M_PI*d_fDTs*_GRFASTCOS(d_theta_los), 2*M_PI);
+ float los_i = scale_los*_GRFASTCOS(d_psi[0]);
+ float los_q = scale_los*_GRFASTSIN(d_psi[0]);
+ H = H*scale_nlos + gr_complex(los_i,los_q);
+ }
+
+ update_theta();
+ Hvec[i] = H;
}
+
+ }
- if(d_LOS){
-#if FASTSINCOS == 1
- float los_i = gr::fxpt::cos(gr::fxpt::float_to_fixed(2*M_PI*d_fDTs*d_m*gr::fxpt::cos(gr::fxpt::float_to_fixed(d_theta_los)) + d_psi[0]));
- float los_q = gr::fxpt::sin(gr::fxpt::float_to_fixed(2*M_PI*d_fDTs*d_m*gr::fxpt::cos(gr::fxpt::float_to_fixed(d_theta_los)) + d_psi[0]));
-#elif FASTSINCOS == 2
- float los_i = d_table.cos(2*M_PI*d_fDTs*d_m*d_table.cos(d_theta_los) + d_psi[0]);
- float los_q = d_table.sin(2*M_PI*d_fDTs*d_m*d_table.cos(d_theta_los) + d_psi[0]);
-#else
- float los_i = cos(2*M_PI*d_fDTs*d_m*cos(d_theta_los) + d_psi[0]);
- float los_q = sin(2*M_PI*d_fDTs*d_m*cos(d_theta_los) + d_psi[0]);
-#endif
-
- H = H*scale_nlos + gr_complex(los_i,los_q)*scale_los;
- }
-
- //out[i] = in[i]*H;
- d_m++;
- update_theta();
- return H;
-
+ gr_complex flat_fader_impl::next_sample(){
+ std::vector<gr_complex> v(1);
+ next_samples(v,1);
+ return v[0];
}
void flat_fader_impl::update_theta()
@@ -114,4 +114,3 @@ namespace gr {
} /* namespace channels */
} /* namespace gr */
-
diff --git a/gr-channels/lib/flat_fader_impl.h b/gr-channels/lib/flat_fader_impl.h
index ae782ffc78..fae237278c 100644
--- a/gr-channels/lib/flat_fader_impl.h
+++ b/gr-channels/lib/flat_fader_impl.h
@@ -48,7 +48,7 @@ namespace gr {
// random walk variate
boost::mt19937 seed_2;
- boost::uniform_real<> dist_2; // U(-pi,pi)
+ boost::uniform_real<> dist_2; // U(0,1)
boost::variate_generator<boost::mt19937&, boost::uniform_real<> > rv_2;
public:
@@ -75,6 +75,7 @@ namespace gr {
flat_fader_impl(unsigned int N, float fDTs, bool LOS, float K, int seed);
gr_complex next_sample();
+ void next_samples(std::vector<gr_complex> &HVec, int n_samples);
}; /* class flat_fader_impl */
} /* namespace channels */
diff --git a/gr-channels/lib/selective_fading_model2_impl.cc b/gr-channels/lib/selective_fading_model2_impl.cc
new file mode 100644
index 0000000000..c9b9d62b1b
--- /dev/null
+++ b/gr-channels/lib/selective_fading_model2_impl.cc
@@ -0,0 +1,204 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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 "selective_fading_model2_impl.h"
+#include <gnuradio/io_signature.h>
+#include <iostream>
+
+#include <boost/format.hpp>
+#include <boost/random.hpp>
+
+#include <gnuradio/fxpt.h>
+#include <sincostable.h>
+
+
+// FASTSINCOS: 0 = slow native, 1 = gr::fxpt impl, 2 = sincostable.h
+#define FASTSINCOS 2
+
+
+namespace gr {
+ namespace channels {
+
+ selective_fading_model2::sptr
+ selective_fading_model2::make( unsigned int N, float fDTs, bool LOS, float K, int seed, std::vector<float> delays,
+ std::vector<float> delays_std, std::vector<float> delays_maxdev, std::vector<float> mags, int ntaps)
+ {
+ return gnuradio::get_initial_sptr
+ (new selective_fading_model2_impl( N, fDTs, LOS, K, seed, delays, delays_std, delays_maxdev, mags, ntaps));
+ }
+
+ // Block constructor
+ selective_fading_model2_impl::selective_fading_model2_impl( unsigned int N, float fDTs, bool LOS, float K, int seed, std::vector<float> delays,
+ std::vector<float> delays_std, std::vector<float> delays_maxdev, std::vector<float> mags, int ntaps )
+ : sync_block("selective_fading_model2",
+ io_signature::make(1, 1, sizeof(gr_complex)),
+ io_signature::make(1, 1, sizeof(gr_complex))),
+ d_delays(delays),
+ d_delays_orig(delays),
+ d_delays_std(delays_std),
+ d_delays_maxdev(delays_maxdev),
+ d_mags(mags),
+ d_sintable(1024),
+ seed_1(0),
+ dist_1(0,1),
+ rv_1(seed_1, dist_1)
+ {
+ if(mags.size() != delays.size())
+ throw std::runtime_error("magnitude and delay vectors must be the same length!");
+ if(mags.size() != delays_std.size())
+ throw std::runtime_error("delay std dev vector length must be the same length!");
+ if(mags.size() != delays_maxdev.size())
+ throw std::runtime_error("delay maxdev vector length must be the same length!");
+
+ for(size_t i=0; i<mags.size(); i++){
+ d_faders.push_back(new gr::channels::flat_fader_impl(N, fDTs, (i==0)&&(LOS), K, seed+i));
+ }
+
+ // set up tap history
+ if(ntaps < 1){ throw std::runtime_error("ntaps must be >= 1"); }
+ set_history(1+ntaps);
+ d_taps.resize(ntaps, gr_complex(0,0));
+
+ // set up message port
+ message_port_register_out(pmt::mp("taps"));
+ }
+
+ selective_fading_model2_impl::~selective_fading_model2_impl()
+ {
+ for(size_t i=0; i<d_faders.size(); i++){
+ delete d_faders[i];
+ }
+ }
+
+ int
+ selective_fading_model2_impl::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const gr_complex* in = (const gr_complex*) input_items[0];
+ gr_complex* out = (gr_complex*) output_items[0];
+
+ // pregenerate fading components
+ std::vector<std::vector<gr_complex> > fading_taps;
+ for(size_t j=0; j<d_faders.size(); j++){
+ fading_taps.push_back( std::vector<gr_complex>() );
+ d_faders[j]->next_samples(fading_taps[j], noutput_items);
+ }
+
+ // loop over each output sample
+ for(int i=0; i<noutput_items; i++){
+
+ // move the tap delays around (random walk + clipping)
+ for(size_t j=0; j<d_faders.size(); j++){
+ float tmp = d_delays[j] + rv_1()*d_delays_std[j];
+ d_delays[j] = std::max(std::min(tmp,d_delays_orig[j]+d_delays_maxdev[j]), d_delays_orig[j]-d_delays_maxdev[j]);
+ }
+
+ // clear the current values in each tap
+ for(size_t j=0; j<d_taps.size(); j++){
+ d_taps[j] = gr_complex(0,0);
+ }
+
+ // add each flat fading component to the taps
+ for(size_t j=0; j<d_faders.size(); j++){
+ gr_complex ff_H(fading_taps[j][i]);
+ //gr_complex ff_H(d_faders[j]->next_sample());
+ for(size_t k=0; k<d_taps.size(); k++){
+ float dist = k-d_delays[j];
+ float interpmag = d_sintable.sinc(2*M_PI*dist);
+ d_taps[k] += ff_H * interpmag * d_mags[j];
+ }
+ }
+
+ // apply the taps and generate output
+ gr_complex sum(0,0);
+ for(size_t j=0; j<d_taps.size(); j++){
+ sum += in[i+j] * d_taps[d_taps.size()-j-1];
+ }
+
+ // assign output
+ out[i] = sum;
+
+ }
+
+ if(pmt::length(message_subscribers(pmt::mp("taps"))) > 0){
+ pmt::pmt_t pdu( pmt::cons( pmt::PMT_NIL, pmt::init_c32vector(d_taps.size(), d_taps) ));
+ message_port_pub(pmt::mp("taps"), pdu);
+ }
+
+ // return all outputs
+ return noutput_items;
+ }
+
+ void
+ selective_fading_model2_impl::setup_rpc()
+ {
+#ifdef GR_CTRLPORT
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_get<selective_fading_model2, float >(
+ alias(), "fDTs",
+ &selective_fading_model2::fDTs,
+ pmt::mp(0), pmt::mp(1), pmt::mp(0.01),
+ "Hz*Sec", "normalized maximum doppler frequency (fD*Ts)",
+ RPC_PRIVLVL_MIN, DISPTIME | DISPOPTSTRIP)));
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_set<selective_fading_model2, float >(
+ alias(), "fDTs",
+ &selective_fading_model2::set_fDTs,
+ pmt::mp(0), pmt::mp(1), pmt::mp(0.01),
+ "Hz*Sec", "normalized maximum doppler frequency (fD*Ts)",
+ RPC_PRIVLVL_MIN, DISPTIME | DISPOPTSTRIP)));
+
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_get<selective_fading_model2, float >(
+ alias(), "K",
+ &selective_fading_model2::K,
+ pmt::mp(0), pmt::mp(8), pmt::mp(4),
+ "Ratio", "Rician factor (ratio of the specular power to the scattered power)",
+ RPC_PRIVLVL_MIN, DISPTIME | DISPOPTSTRIP)));
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_set<selective_fading_model2, float >(
+ alias(), "K",
+ &selective_fading_model2::set_K,
+ pmt::mp(0), pmt::mp(8), pmt::mp(4),
+ "Ratio", "Rician factor (ratio of the specular power to the scattered power)",
+ RPC_PRIVLVL_MIN, DISPTIME | DISPOPTSTRIP)));
+
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_get<selective_fading_model2, float >(
+ alias(), "step",
+ &selective_fading_model2::step,
+ pmt::mp(0), pmt::mp(8), pmt::mp(4),
+ "radians", "Maximum step size for random walk angle per sample",
+ RPC_PRIVLVL_MIN, DISPTIME | DISPOPTSTRIP)));
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_set<selective_fading_model2, float >(
+ alias(), "step",
+ &selective_fading_model2::set_step,
+ pmt::mp(0), pmt::mp(1), pmt::mp(0.00001),
+ "radians", "Maximum step size for random walk angle per sample",
+ RPC_PRIVLVL_MIN, DISPTIME | DISPOPTSTRIP)));
+#endif /* GR_CTRLPORT */
+ }
+
+ } /* namespace channels */
+} /* namespace gr */
diff --git a/gr-channels/lib/selective_fading_model2_impl.h b/gr-channels/lib/selective_fading_model2_impl.h
new file mode 100644
index 0000000000..eac6adb842
--- /dev/null
+++ b/gr-channels/lib/selective_fading_model2_impl.h
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 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_CHANNELS_SELECTIVE_FADING_MODEL2_IMPL_H
+#define INCLUDED_CHANNELS_SELECTIVE_FADING_MODEL2_IMPL_H
+
+#include <gnuradio/sync_block.h>
+#include <gnuradio/channels/selective_fading_model2.h>
+#include "flat_fader_impl.h"
+
+//#include <iostream>
+#include <boost/format.hpp>
+#include <boost/random.hpp>
+
+#include <gnuradio/fxpt.h>
+#include <sincostable.h>
+
+namespace gr {
+ namespace channels {
+
+ class CHANNELS_API selective_fading_model2_impl : public selective_fading_model2
+ {
+ private:
+ std::vector<gr::channels::flat_fader_impl*> d_faders;
+ std::vector<float> d_delays;
+ std::vector<float> d_delays_orig;
+ std::vector<float> d_delays_std;
+ std::vector<float> d_delays_maxdev;
+ std::vector<float> d_mags;
+ sincostable d_sintable;
+
+ boost::mt19937 seed_1;
+ boost::normal_distribution<> dist_1; // U(-pi,pi)
+ boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > rv_1;
+
+ public:
+ selective_fading_model2_impl(unsigned int N, float fDTs, bool LOS, float K, int seed, std::vector<float> delays, std::vector<float> delay_std,
+ std::vector<float> delay_maxdev, std::vector<float> mags, int ntaps);
+ ~selective_fading_model2_impl();
+ void setup_rpc();
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ std::vector<gr_complex> d_taps;
+
+ virtual float fDTs(){ return d_faders[0]->d_fDTs; }
+ virtual float K(){ return d_faders[0]->d_K; }
+ virtual float step(){ return d_faders[0]->d_step; }
+
+ virtual void set_fDTs(float fDTs){
+ BOOST_FOREACH( gr::channels::flat_fader_impl* fader, d_faders )
+ { fader->d_fDTs = fDTs; fader->d_step = powf(0.00125*fDTs, 1.1); }
+ }
+ virtual void set_K(float K){
+ BOOST_FOREACH( gr::channels::flat_fader_impl* fader, d_faders )
+ { fader->d_K = K; fader->scale_los = sqrtf(fader->d_K)/sqrtf(fader->d_K+1); fader->scale_nlos = (1/sqrtf(fader->d_K+1)); }
+ }
+ virtual void set_step(float step){
+ BOOST_FOREACH( gr::channels::flat_fader_impl* fader, d_faders )
+ { fader->d_step = step; }
+ }
+
+ };
+
+ } /* namespace channels */
+} /* namespace gr */
+
+#endif /* INCLUDED_CHANNELS_SELECTIVE_FADING_MODEL2_IMPL_H */
diff --git a/gr-channels/lib/selective_fading_model_impl.cc b/gr-channels/lib/selective_fading_model_impl.cc
index dfd7b74ca9..be9c0b1f3a 100644
--- a/gr-channels/lib/selective_fading_model_impl.cc
+++ b/gr-channels/lib/selective_fading_model_impl.cc
@@ -82,6 +82,13 @@ namespace gr {
const gr_complex* in = (const gr_complex*) input_items[0];
gr_complex* out = (gr_complex*) output_items[0];
+ // pregenerate fading components
+ std::vector<std::vector<gr_complex> > fading_taps;
+ for(size_t j=0; j<d_faders.size(); j++){
+ fading_taps.push_back( std::vector<gr_complex>() );
+ d_faders[j]->next_samples(fading_taps[j], noutput_items);
+ }
+
// loop over each output sample
for(int i=0; i<noutput_items; i++){
@@ -92,7 +99,8 @@ namespace gr {
// add each flat fading component to the taps
for(size_t j=0; j<d_faders.size(); j++){
- gr_complex ff_H(d_faders[j]->next_sample());
+ gr_complex ff_H(fading_taps[j][i]);
+ //gr_complex ff_H(d_faders[j]->next_sample());
for(size_t k=0; k<d_taps.size(); k++){
float dist = k-d_delays[j];
float interpmag = d_sintable.sinc(2*M_PI*dist);