diff options
-rw-r--r-- | utils/gmr_multi_rx/.gitignore | 2 | ||||
-rw-r--r-- | utils/gmr_multi_rx/Makefile | 35 | ||||
-rw-r--r-- | utils/gmr_multi_rx/filter_helpers.hpp | 138 | ||||
-rw-r--r-- | utils/gmr_multi_rx/gmr_channels.hpp | 68 | ||||
-rw-r--r-- | utils/gmr_multi_rx/gmr_multi_rx.cpp | 540 |
5 files changed, 0 insertions, 783 deletions
diff --git a/utils/gmr_multi_rx/.gitignore b/utils/gmr_multi_rx/.gitignore deleted file mode 100644 index 6c429dd..0000000 --- a/utils/gmr_multi_rx/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -!Makefile -gmr_multi_rx diff --git a/utils/gmr_multi_rx/Makefile b/utils/gmr_multi_rx/Makefile deleted file mode 100644 index d9167a7..0000000 --- a/utils/gmr_multi_rx/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -CFLAGS = -Wall -Wextra -Wno-unused -O2 - -TARGET ?= usrp - -ifeq ($(TARGET),fcd) -PKGLIBS += gnuradio-fcd -CFLAGS += -DHAVE_FCD -endif -ifeq ($(TARGET),uhd) -PKGLIBS += gnuradio-uhd uhd -CFLAGS += -DHAVE_UHD -endif -ifeq ($(TARGET),usrp) -PKGLIBS += gnuradio-usrp -endif - -CFLAGS += $(shell pkg-config --cflags $(PKGLIBS)) -LDLIBS = $(shell pkg-config --libs $(PKGLIBS)) \ - -lboost_program_options \ - -lboost_system \ - -lboost_thread -lpthread \ - -all: gmr_multi_rx - -gmr_multi_rx: gmr_multi_rx.o - $(CXX) -o $@ $< $(LDFLAGS) $(LDLIBS) - -.cc.o: - $(CXX) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< - -.cpp.o: - $(CXX) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< - -clean: - $(RM) gmr_multi_rx *.o diff --git a/utils/gmr_multi_rx/filter_helpers.hpp b/utils/gmr_multi_rx/filter_helpers.hpp deleted file mode 100644 index e0d613c..0000000 --- a/utils/gmr_multi_rx/filter_helpers.hpp +++ /dev/null @@ -1,138 +0,0 @@ -/* Conversion of Python routines from Sylvain Munaut <tnt@246tNt.com> - * (C) 2011 by Dimitri Stolnikov <horiz0n@gmx.net> - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef FILTER_HELPERS_HPP -#define FILTER_HELPERS_HPP - -#include <boost/math/common_factor.hpp> // gcd -#include <cmath> // ceil, floor - -int gcd( int n, int d ) -{ - return boost::math::gcd( n, d ); -} - -void reduce_fract( int & n_out, int & d_out, int n_in, int d_in ) -{ - int g = gcd( n_in, d_in ); - - n_out = n_in / g; - d_out = d_in / g; -} - -bool find_decim( int & hw_decim, int & sw_decim, int & ai, int d, int max_decim ) -{ - int x = max_decim; - - while ( x >= 4 ) - { - if ( d % x == 0 ) - { - // If it's odd, the usrp can't do it. But maybe we can decimate twice - // as much and then interpolate more in sw - if ( x % 2 == 1 ) - { - if ( x * 2 > max_decim ) - { - x--; - continue; - } - - hw_decim = 2 * x; - sw_decim = d / x; - ai = 2; - return true; - } - else - { - hw_decim = x; - sw_decim = d / x; - ai = 1; - return true; - } - } - - x--; - } - - hw_decim = 0; - sw_decim = 0; - ai = 1; - - return false; -} - -void find_split( int & first_decim, int & second_decim, int decim, int inter) -{ - int mx = decim / (inter * 2); - first_decim = 1; - - for ( int x = 2; x < mx + 1; x++ ) - { - if (decim % x == 0) - first_decim = x; - } - - second_decim = decim / first_decim; -} - -void compute_filter_params( int & hw_decim, - int & s1_decim, - int & s2_decim, - int & s2_inter, - int req_bw, - int fpga_freq, - int symbol_rate, - int osr ) -{ - // Required samplerate - int req_symrate = int(std::ceil(req_bw / symbol_rate)) * symbol_rate; - if ( req_symrate < osr * symbol_rate ) - req_symrate = osr * symbol_rate; - - // Find the total decim / inter ratio for 1 channel - int tot_inter, tot_decim; - reduce_fract( tot_inter, tot_decim, osr * symbol_rate, fpga_freq); - - // Need to split the decimation between USRP and SW - // (but we need _at_ least req_symrate out of the USRP) - int max_decim = int(std::floor(fpga_freq / req_symrate)); - if ( max_decim > 256 ) - max_decim = 256; - - int sw_decim, ai; - find_decim( hw_decim, sw_decim, ai, tot_decim, max_decim ); - - if ( hw_decim == 0 ) - { - // No good solution found ... so settle for a bad one - hw_decim = max_decim; - reduce_fract( tot_inter, sw_decim, tot_inter * hw_decim, tot_decim ); - } - else - { - tot_inter *= ai; - } - - s2_inter = tot_inter; - - // Split the sw decim in 2 stage - find_split( s1_decim, s2_decim, sw_decim, tot_inter ); -} - -#endif // FILTER_HELPERS_HPP diff --git a/utils/gmr_multi_rx/gmr_channels.hpp b/utils/gmr_multi_rx/gmr_channels.hpp deleted file mode 100644 index f767d80..0000000 --- a/utils/gmr_multi_rx/gmr_channels.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* (C) 2011 by Dimitri Stolnikov <horiz0n@gmx.net> - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef GMR_CHANNELS_HPP -#define GMR_CHANNELS_HPP - -//////////////////////////////////////////////////////////////////////////////// -class channel_base -{ -public: - channel_base( const std::string & name, unsigned int number ) : - _name(name), _number(number) {} - virtual ~channel_base() {} - - virtual double frequency() /* as per GMR-1 05.005, p4.2 */ - { return _base_freq + _bandwidth * _number; } - - std::string _name; - double _symbol_rate; - double _bandwidth; - double _base_freq; - unsigned int _max_channels; - unsigned int _number; -}; - -//////////////////////////////////////////////////////////////////////////////// -class gmr1_dl_channel : public channel_base -{ -public: - gmr1_dl_channel( unsigned int number ) : - channel_base( "gmr1-dl", number ) - { - _symbol_rate = 23400; /* from GMR-1 05.004, p4.2 */ - _bandwidth = 31250; - _base_freq = 1525e6; - _max_channels = 1087; - } -}; - -//////////////////////////////////////////////////////////////////////////////// -class gmr1_ul_channel : public channel_base -{ -public: - gmr1_ul_channel( unsigned int number ) : - channel_base( "gmr1-ul", number ) - { - _symbol_rate = 23400; /* from GMR-1 05.004, p4.2 */ - _bandwidth = 31250; - _base_freq = 1525e6 + 101.5e6; - _max_channels = 1087; - } -}; - -#endif // GMR_CHANNELS_HPP diff --git a/utils/gmr_multi_rx/gmr_multi_rx.cpp b/utils/gmr_multi_rx/gmr_multi_rx.cpp deleted file mode 100644 index c389592..0000000 --- a/utils/gmr_multi_rx/gmr_multi_rx.cpp +++ /dev/null @@ -1,540 +0,0 @@ -/* (C) 2011 by Dimitri Stolnikov <horiz0n@gmx.net> - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - - build: - - "make" for USRP, requires libgnuradio-usrp - "make TARGET=fcd" for FCD, requires libgnuradio-fcd - "make TARGET=uhd" for UHD, requires libgnuradio-uhd - - usage: - - for FunCube Dongle call: - - ./gmr_multi_rx --gain 30 --gmr1-dl 941 942 943 - - - when receiving 3 consecutive channels, the center channel will be - distorted by the center peak caused by dc offset / iq imbalance, - - - when receiving 2 channels, each channel will have a small contribution - of the center peak on the right or left side. - - - best results may be achieved when receiving only one channel. - - for default USRP clock, call: - - - only 75% of the master output rate will be used on the usrp, because of - insufficient attenuation of the fpga channelizer at filter edges. - - ./gmr_multi_rx --gain 45 --gmr1-dl 941 942 943 - - for modified clocks, use --mcr to tell custom fpga frequency in Hz - - ./gmr_multi_rx --gain 45 --gmr1-dl 941 942 943 --mcr 52e6 - - mcr of 59.904e6 Hz is gmr1-friendly, thus alowing to save on interpolation - - ./gmr_multi_rx --gain 45 --gmr1-dl 941 942 943 --mcr 59.904e6 - - */ - -#include <cstring> -#include <csignal> - -#include <map> -#include <iostream> -#include <algorithm> -#include <iterator> - -#include <boost/bind.hpp> -#include <boost/thread.hpp> -#include <boost/program_options.hpp> -#include <boost/format.hpp> -#include <boost/algorithm/string.hpp> -#include <boost/lexical_cast.hpp> -#include <boost/foreach.hpp> - -#include <gr_top_block.h> - -#ifdef HAVE_FCD -#include <fcd/fcd_source_c.h> -#elif defined(HAVE_UHD) -#include <gr_uhd_usrp_source.h> -#else -#include <usrp_source_c.h> -#endif - -#include <gr_firdes.h> -#include <gr_freq_xlating_fir_filter_ccf.h> -#include <gr_rational_resampler_base_ccf.h> - -#include <gr_file_sink.h> -#include <gr_udp_sink.h> - -#include "gmr_channels.hpp" -#include "filter_helpers.hpp" - -namespace po = boost::program_options; - -//////////////////////////////////////////////////////////////////////////////// -int main(int argc, char** argv) -{ - /* variables to be set by po */ - std::string prefix, udp, ant, side; -#ifdef HAVE_FCD - std::string device; - double correct; -#else -#ifdef HAVE_UHD - std::string addr, subdev; -#endif -#endif - double gain, mcr; - unsigned int time, osr; - - /* setup the program options */ - po::options_description opt_desc("Allowed options"); - opt_desc.add_options() - ("help,h", "print the command line help") - ("prefix,P", po::value<std::string>(&prefix)->default_value("/tmp/"), "prefix of file to write channel samples to") - ("time,T", po::value<unsigned int>(&time)->default_value(0), "recording time in seconds, 0 means infinite") - ("udp,u", po::value<std::string>(&udp), "UDP destination (host:port) to send radio samples to") - ("gain,g", po::value<double>(&gain)->default_value(10), "gain for the RF chain") - ("osr,s", po::value<unsigned int>(&osr)->default_value(4), "oversampling rate, samples per symbol") -#ifdef HAVE_FCD - ("device", po::value<std::string>(&device)->default_value("hw:1"), "FCD audio device name") - ("correct", po::value<double>(&correct)->default_value(-21), "FCD frequency correction (ppm)") -#else -#ifdef HAVE_UHD - ("addr", po::value<std::string>(&addr)->default_value("type=usrp1"), "UHD device address") - ("subdev,S", po::value<std::string>(&subdev), "UHD sub-device spec, A:0 or B:0") -#else - ("side,S", po::value<std::string>(&side), "USRP daughterboard side, A or B") -#endif - ("ant,a", po::value<std::string>(&ant), "daughterboard antenna selection") - ("mcr", po::value<double>(&mcr), "USRP fpga master clock rate in Hz") -#endif - ; - - po::options_description chan_desc("Supported channels"); - chan_desc.add_options() - ("gmr1-dl", po::value< std::vector<unsigned int> >()->multitoken(), "GMR-1 L-band downlink channel [1...1087]") - ("gmr1-ul", po::value< std::vector<unsigned int> >()->multitoken(), "GMR-1 L-band uplink channel [1...1087]") - ; - - po::options_description visible("visible"); - visible.add(opt_desc).add(chan_desc); - - po::variables_map vm; - po::store(po::command_line_parser(argc, argv).options(visible).run(), vm); - po::notify(vm); - - /* print the help message */ - if (vm.count("help")) { - std::cout << boost::format("\nGMR-1 Acquisition tool\n") << std::endl; - std::cout << boost::format("%s") % opt_desc << std::endl; - std::cout << boost::format("%s") % chan_desc << std::endl; - return ~0; - } - - if (not vm.count("gmr1-dl") and not vm.count("gmr1-ul")) { - std::cerr << boost::format("No channel number(s) given.") << std::endl; - return ~0; - } - - std::string type = ""; - std::vector< unsigned int > arfcns; - - if (vm.count("gmr1-dl")) { - type = "gmr1-dl"; - arfcns = vm[type].as< std::vector<unsigned int> >(); - } else if (vm.count("gmr1-ul")) { - type = "gmr1-ul"; - arfcns = vm[type].as< std::vector<unsigned int> >(); - } - - /* remove duplicate ARFCNs */ - sort( arfcns.begin(), arfcns.begin() + arfcns.size() ); - arfcns.resize( std::unique( arfcns.begin(), arfcns.end() ) - arfcns.begin() ); - - std::vector< channel_base > channels; - - std::cout << "Given " << type << " ARFCNs:" << std::endl; - BOOST_FOREACH(unsigned int arfcn, arfcns) - { - channel_base channel("", 0); - - if ( "gmr1-dl" == type ) - channel = gmr1_dl_channel( arfcn ); - else if ( "gmr1-ul" == type ) - channel = gmr1_ul_channel( arfcn ); - - if ( arfcn < 1 || arfcn > channel._max_channels ) { - std::cerr << boost::format("Please specify the channel number in range [1...%d]") - % channel._max_channels << std::endl; - return ~0; - } - - std::cout << boost::format(" %i = %f MHz") - % arfcn - % (channel.frequency()/1e6) - << std::endl; - - channels.push_back( channel ); - } - - double required_bandwidth = \ - channels.back().frequency() \ - - channels.front().frequency() \ - + channels.back()._bandwidth / 2.0 \ - + channels.front()._bandwidth / 2.0; - - std::cout << boost::format("Required bandwidth is: %f kHz") - % (required_bandwidth / 1e3) - << std::endl; - - double sample_rate = 0; -#ifndef HAVE_FCD - /* use only 75% of BW due to USRP filter shape */ - const double useful_bw_factor = 0.75; -#else - const double useful_bw_factor = 1.0; -#endif - channel_base last_channel = channels.back(); - int channel_rate = last_channel._symbol_rate * osr; - int hw_decim, first_decim, second_decim, interpolation; - - std::cout << std::endl; - -#ifdef HAVE_FCD - std::cout << boost::format("Creating the FCD device...") << std::endl; - fcd_source_c_sptr radio = fcd_make_source_c( device ); - radio->set_freq_corr( correct ); - sample_rate = 96000; /* fixed by design */ - hw_decim = 1; - first_decim = 1; - int gcd = boost::math::gcd( int(sample_rate), channel_rate ); - second_decim = sample_rate / gcd; - interpolation = channel_rate / gcd; -#elif defined(HAVE_UHD) - std::cout << boost::format("Creating the UHD device...") << std::endl; - boost::shared_ptr<uhd_usrp_source> radio = \ - uhd_make_usrp_source( addr, - uhd::io_type_t::COMPLEX_FLOAT32, - 1 ); - - if (vm.count("mcr")) radio->set_clock_rate(mcr); - mcr = radio->get_clock_rate(); - - if (vm.count("subdev")) radio->set_subdev_spec(subdev, 0); - - std::cout << boost::format("Using %s") - % radio->get_device().get()->get_pp_string() - << std::endl; - - compute_filter_params( hw_decim, - first_decim, - second_decim, - interpolation, - int(required_bandwidth / useful_bw_factor), - int(mcr), - last_channel._symbol_rate, - osr ); - - radio->set_samp_rate( mcr / double(hw_decim) ); - - sample_rate = radio->get_samp_rate(); -#else - /* create a usrp device */ - std::cout << boost::format("Creating the USRP device...") << std::endl; - usrp_source_c_sptr radio = usrp_make_source_c( 0 ); - - if (vm.count("mcr")) radio->set_fpga_master_clock_freq(long(mcr)); - mcr = double(radio->fpga_master_clock_freq()); - - usrp_subdev_spec spec(0, 0); /* use A-side daughterboard by default */ - - if (vm.count("side")) spec.side = (side == "B" ? 1 : 0); - - radio->set_mux( radio->determine_rx_mux_value(spec) ); - - db_base_sptr dboard = radio->selected_subdev(spec); - - std::cout << boost::format("Using side %s (%g - %g MHz)") - % dboard->side_and_name() - % (dboard->freq_min() / 1e6) - % (dboard->freq_max() / 1e6) - << std::endl; - - compute_filter_params( hw_decim, - first_decim, - second_decim, - interpolation, - int(required_bandwidth / useful_bw_factor), - int(mcr), - last_channel._symbol_rate, - osr ); - - radio->set_decim_rate( hw_decim ); - - sample_rate = mcr / radio->decim_rate(); -#endif - -#ifndef HAVE_FCD - std::cout << boost::format("Master Clock Rate is: %f MHz") -#ifdef HAVE_UHD - % (radio->get_clock_rate()/1e6) -#else - % (radio->fpga_master_clock_freq()/1e6) -#endif - << std::endl; -#endif - std::cout << boost::format("Output sample rate is: %f kHz") - % (sample_rate/1e3) - << std::endl; - - double available_bandwidth = sample_rate * useful_bw_factor; - - std::cout << boost::format("Available bandwidth is: %f kHz") - % (available_bandwidth / 1e3) - << std::endl; - - if ( available_bandwidth < required_bandwidth ) { - std::cerr << "Please specify less channels or increase acquisition bandwidth." << std::endl; - return ~0; - } - - /* calculate the frequency of the last channel of the group */ - double center_freq = last_channel.frequency(); - - /* tune away from center peak caused by dc offset / phase imbalance */ - center_freq -= last_channel._bandwidth / 2.0; - - /* tune even more from the center if the acquisition bandwidth allows it */ - double offset = available_bandwidth / 2.0; - while ( offset > last_channel._bandwidth ) - offset -= last_channel._bandwidth; - offset = available_bandwidth / 2.0 - offset; - center_freq -= offset; - - double tune_error = 0; - - std::cout << boost::format("Setting RX Freq: %f MHz...") % (center_freq/1e6) << std::endl; -#ifdef HAVE_FCD - double fitting_channels = required_bandwidth / last_channel._bandwidth; - - if ( 1 == fitting_channels ) - center_freq += offset - (sample_rate / 16.0); - else if ( 2 == fitting_channels ) - center_freq += offset; - else if ( 3 == fitting_channels ) - center_freq += offset - last_channel._bandwidth / 2.0; - - radio->set_freq( float(center_freq) ); -#elif defined(HAVE_UHD) - uhd::tune_result_t tres = radio->set_center_freq( center_freq ); - /*tune_error = tres.target_rf_freq - tres.actual_rf_freq - tres.actual_dsp_freq;*/ -#else - freq_result_t fres = dboard->set_freq( center_freq ); - std::cout << boost::format("Actual RX Freq: %f MHz...") % (fres.baseband_freq/1e6) << std::endl; - tune_error = center_freq - fres.baseband_freq; -#endif - - if ( tune_error != 0 ) /* we have to compensate this later in each ddc tuner */ - std::cout << boost::format("Tuning error is: %f kHz...") % (tune_error/1e3) << std::endl; - - /* set the rf gain */ - if (vm.count("gain")){ - std::cout << boost::format("Setting RX Gain: %f dB...") % gain << std::endl; -#ifdef HAVE_FCD - radio->set_lna_gain( gain ); -#else -#ifdef HAVE_UHD - radio->set_gain( gain ); -#else - if ( dboard->set_gain( gain ) ) - std::cout << boost::format("Actual RX Gain: %f dB...") % gain << std::endl; - else - std::cerr << "Failed to apply RX Gain" << std::endl; -#endif -#endif - } - -#ifndef HAVE_FCD - /* set the antenna */ - if (vm.count("ant")) -#ifdef HAVE_UHD - radio->set_antenna( ant ); -#else - dboard->select_rx_antenna( ant ); -#endif -#endif - -#if 1 - std::cout << boost::format("hw decimation stage: %i") % hw_decim << std::endl; - std::cout << boost::format("1st sw decimation stage: %i") % first_decim << std::endl; - std::cout << boost::format("2nd sw decimation stage: %i") % second_decim << std::endl; - std::cout << boost::format("interpolation stage: %i") % interpolation << std::endl; -#endif - - double ddc_cutoff = last_channel._bandwidth / 2.0; - - std::vector<float> ddc_taps = \ - gr_firdes::low_pass( 1, /* gain */ - sample_rate, - ddc_cutoff, - ddc_cutoff * 0.6 ); /* transition width */ - - double resampler_gain = interpolation; - double resampler_sample_rate = sample_rate * interpolation; - double resampler_cutoff = (interpolation * sample_rate) / (second_decim * 2.0); - - if ( interpolation > second_decim ) - resampler_cutoff = sample_rate / 2.0; - - std::vector<float> channel_taps = \ - gr_firdes::low_pass( resampler_gain, - resampler_sample_rate, - resampler_cutoff, - resampler_cutoff * 0.2 ); /* transition width */ - - std::cout << std::endl; - - gr_top_block_sptr fg = gr_make_top_block( "flowgraph" ); - - if ( udp.length() ) - { - std::vector< std::string > tokens; - split( tokens, udp, boost::is_any_of(":") ); - - if ( tokens.size() == 2 ) - { - unsigned short port = \ - boost::lexical_cast< unsigned short >( tokens[1] ); - - gr_udp_sink_sptr udp_sink = gr_make_udp_sink( sizeof(gr_complex), - tokens[0].c_str(), - port ); - - fg->connect(radio, 0, udp_sink, 0); - - std::cout << boost::format("Sending samples to %s:%u ...") - % tokens[0] - % port - << std::endl; - } - } - - for ( unsigned int i = 0; i < channels.size(); i++ ) - { - channel_base channel = channels[ i ]; - - /* calculate ddc offset from center frequency */ - double tune_freq = channel.frequency() - center_freq; - - /* we use the ddc to compensate the tuning error (if any) */ - tune_freq += tune_error; -#if 0 - std::cout << boost::format("DDC%d tune_freq is %f") - % i - % tune_freq - << std::endl; -#endif - gr_freq_xlating_fir_filter_ccf_sptr tuner = \ - gr_make_freq_xlating_fir_filter_ccf( first_decim, - ddc_taps, - -tune_freq, - sample_rate ); - - gr_rational_resampler_base_ccf_sptr resampler = \ - gr_make_rational_resampler_base_ccf( interpolation, - second_decim, - channel_taps ); - - std::string file_name = \ - str(boost::format("%s%s-%d-sps%d.cfile") - % prefix - % channel._name - % channel._number - % channel_rate); - - gr_file_sink_sptr file_sink = \ - gr_make_file_sink( sizeof(gr_complex), - file_name.c_str() ); - - fg->connect(radio, 0, tuner, 0); - fg->connect(tuner, 0, resampler, 0); - fg->connect(resampler, 0, file_sink, 0); - - std::cout << boost::format("Writing samples for ARFCN %i to %s ...") - % channel._number - % file_name - << std::endl; - } - - /* Block all signals for background thread. */ - sigset_t new_mask; - sigfillset(&new_mask); - sigset_t old_mask; - pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); - - /* Launch the flowgraph in a separate thread. */ - boost::thread fg_thread( boost::bind( &gr_top_block::run, fg.get(), 10000) ); - - /* Restore previous signals. */ - pthread_sigmask(SIG_SETMASK, &old_mask, 0); - - /* Wait for signal indicating time to shut down. */ - sigset_t wait_mask; - sigemptyset(&wait_mask); - sigaddset(&wait_mask, SIGINT); - sigaddset(&wait_mask, SIGQUIT); - sigaddset(&wait_mask, SIGTERM); - pthread_sigmask(SIG_BLOCK, &wait_mask, 0); - int sig = 0; - - if ( time ) - { - std::cout << std::endl << "Recording for " << time << " seconds..." - << std::endl; - - sleep( time ); - - std::cout << std::endl << "Finished recording, "; - } - else - { - std::cout << std::endl << "Press Ctrl + C to stop the receiver..." - << std::endl; - - sigwait(&wait_mask, &sig); - - std::cout << std::endl << strsignal(sig) << ", "; - } - - std::cout << "stopping flowgraph... " << std::flush; - - fg->stop(); - - fg_thread.join(); - - std::cout << "done" << std::endl << std::endl; - - return 0; -} |