diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fcd/fcd_source.cc | 78 | ||||
-rw-r--r-- | lib/fcd/fcd_source.h | 5 | ||||
-rw-r--r-- | lib/osmosdr/osmosdr_control.cc | 56 | ||||
-rw-r--r-- | lib/osmosdr/osmosdr_snk_c.cc | 22 | ||||
-rw-r--r-- | lib/osmosdr/osmosdr_snk_c.h | 5 | ||||
-rw-r--r-- | lib/osmosdr/osmosdr_src_c.cc | 34 | ||||
-rw-r--r-- | lib/osmosdr/osmosdr_src_c.h | 5 | ||||
-rw-r--r-- | lib/osmosdr_arg_helpers.h | 77 | ||||
-rw-r--r-- | lib/osmosdr_sink_c_impl.cc | 10 | ||||
-rw-r--r-- | lib/osmosdr_source_c_impl.cc | 202 | ||||
-rw-r--r-- | lib/osmosdr_source_c_impl.h | 4 | ||||
-rw-r--r-- | lib/rtl/rtl_source_c.cc | 11 | ||||
-rw-r--r-- | lib/rtl/rtl_source_c.h | 5 | ||||
-rw-r--r-- | lib/uhd/uhd_source_c.cc | 37 | ||||
-rw-r--r-- | lib/uhd/uhd_source_c.h | 5 |
15 files changed, 391 insertions, 165 deletions
diff --git a/lib/fcd/fcd_source.cc b/lib/fcd/fcd_source.cc index b7b268b..96f9993 100644 --- a/lib/fcd/fcd_source.cc +++ b/lib/fcd/fcd_source.cc @@ -28,33 +28,38 @@ #include <fcd_source.h> +#include <osmosdr_arg_helpers.h> + using namespace boost::assign; fcd_source_sptr make_fcd_source(const std::string &args) { - return gnuradio::get_initial_sptr(new fcd_source(args)); + return gnuradio::get_initial_sptr(new fcd_source(args)); } fcd_source::fcd_source(const std::string &args) : - gr_hier_block2("fcd_source", - gr_make_io_signature (0, 0, 0), - gr_make_io_signature (1, 1, sizeof (gr_complex))) + gr_hier_block2("fcd_source", + gr_make_io_signature (0, 0, 0), + gr_make_io_signature (1, 1, sizeof (gr_complex))) { - std::string device_name = args; + std::string dev_name; + unsigned int dev_index = 0; - if ( device_name.empty() ) - { - std::vector< std::string > devices = fcd_source::get_devices(); + dict_t dict = params_to_dict(args); - if ( devices.size() ) - device_name = devices.front(); // pick first available device - else - throw std::runtime_error("no FUNcube Dongle device found"); - } + if (dict.count("fcd")) + dev_index = boost::lexical_cast< unsigned int >( dict["fcd"] ); + + std::vector< std::string > devices = fcd_source::get_devices(); - _src = fcd_make_source_c( device_name ); + if ( devices.size() ) + dev_name = devices[dev_index]; + else + throw std::runtime_error("No FunCube Dongle found."); - connect( _src, 0, self(), 0 ); + _src = fcd_make_source_c( dev_name ); + + connect( _src, 0, self(), 0 ); } fcd_source::~fcd_source() @@ -63,42 +68,42 @@ fcd_source::~fcd_source() std::vector< std::string > fcd_source::get_devices() { - std::vector< std::string > devices; + std::vector< std::string > devices; - std::string line; - std::ifstream cards( "/proc/asound/cards" ); - if ( cards.is_open() ) + std::string line; + std::ifstream cards( "/proc/asound/cards" ); + if ( cards.is_open() ) + { + while ( cards.good() ) { - while ( cards.good() ) - { - getline (cards, line); - - if ( line.find( "USB-Audio - FUNcube Dongle" ) != std::string::npos ) - { - int id; - std::istringstream( line ) >> id; + getline (cards, line); - std::ostringstream hw_id; - hw_id << "hw:" << id; // build alsa identifier + if ( line.find( "USB-Audio - FUNcube Dongle" ) != std::string::npos ) + { + int id; + std::istringstream( line ) >> id; - devices += hw_id.str(); - } - } + std::ostringstream hw_id; + hw_id << "hw:" << id; // build alsa identifier - cards.close(); + devices += hw_id.str(); + } } - return devices; + cards.close(); + } + + return devices; } gr_basic_block_sptr fcd_source::self() { - return gr_hier_block2::self(); + return gr_hier_block2::self(); } std::string fcd_source::name() { - return "FUNcube Dongle"; + return "FUNcube Dongle"; } size_t fcd_source::get_num_channels( void ) @@ -223,4 +228,3 @@ std::string fcd_source::get_antenna( size_t chan ) { return "ANT"; } - diff --git a/lib/fcd/fcd_source.h b/lib/fcd/fcd_source.h index 1cd34b3..6fa00a3 100644 --- a/lib/fcd/fcd_source.h +++ b/lib/fcd/fcd_source.h @@ -32,8 +32,9 @@ typedef boost::shared_ptr< fcd_source > fcd_source_sptr; fcd_source_sptr make_fcd_source( const std::string & args = "" ); -class fcd_source : public gr_hier_block2, - public osmosdr_src_iface +class fcd_source : + public gr_hier_block2, + public osmosdr_src_iface { private: friend fcd_source_sptr make_fcd_source(const std::string &args); diff --git a/lib/osmosdr/osmosdr_control.cc b/lib/osmosdr/osmosdr_control.cc index 75f5398..4e3f70a 100644 --- a/lib/osmosdr/osmosdr_control.cc +++ b/lib/osmosdr/osmosdr_control.cc @@ -30,12 +30,12 @@ using namespace boost::assign; osmosdr_control::osmosdr_control(const std::string &args) { - /* lookup acm control channel device name for a given alsa device name */ + /* lookup acm control channel device name for a given alsa device name */ - /* - if (args.empty()) - pick first available device or throw an exception(); - */ + /* + if (args.empty()) + pick first available device or throw an exception(); + */ } osmosdr_control::~osmosdr_control() @@ -48,46 +48,46 @@ osmosdr_control::~osmosdr_control() */ std::vector< std::string > osmosdr_control::find_devices() { - std::vector< std::string > devices; + std::vector< std::string > devices; - std::string line; - std::ifstream cards( "/proc/asound/cards" ); - if ( cards.is_open() ) + std::string line; + std::ifstream cards( "/proc/asound/cards" ); + if ( cards.is_open() ) + { + while ( cards.good() ) { - while ( cards.good() ) - { - getline (cards, line); + getline (cards, line); - if ( line.find( "USB-Audio - OsmoSDR" ) != std::string::npos ) - { - int id; - std::istringstream( line ) >> id; + if ( line.find( "USB-Audio - OsmoSDR" ) != std::string::npos ) + { + int id; + std::istringstream( line ) >> id; - std::ostringstream hw_id; - hw_id << "hw:" << id; // build alsa identifier + std::ostringstream hw_id; + hw_id << "hw:" << id; // build alsa identifier - devices += hw_id.str(); - } - } - - cards.close(); + devices += hw_id.str(); + } } - return devices; + cards.close(); + } + + return devices; } std::string osmosdr_control::audio_dev_name() { - return "hw:1"; + return "hw:1"; } std::string osmosdr_control::control_dev_name() { - return "/dev/ttyUSB0"; + return "/dev/ttyUSB0"; } osmosdr_rx_control::osmosdr_rx_control(const std::string &args) : - osmosdr_control(args) + osmosdr_control(args) { } @@ -96,7 +96,7 @@ osmosdr_rx_control::~osmosdr_rx_control() } osmosdr_tx_control::osmosdr_tx_control(const std::string &args) : - osmosdr_control(args) + osmosdr_control(args) { } diff --git a/lib/osmosdr/osmosdr_snk_c.cc b/lib/osmosdr/osmosdr_snk_c.cc index 0a61bc1..edd589e 100644 --- a/lib/osmosdr/osmosdr_snk_c.cc +++ b/lib/osmosdr/osmosdr_snk_c.cc @@ -27,7 +27,7 @@ #include "config.h" #endif -#include <osmosdr_snk_c.h> +#include "osmosdr_snk_c.h" #include <gr_io_signature.h> #include <gr_audio_sink.h> #include <gr_complex_to_xxx.h> @@ -49,7 +49,7 @@ osmosdr_make_snk_c (const std::string &args) * output signatures are used by the runtime system to * check that a valid number and type of inputs and outputs * are connected to this block. In this case, we accept - * only 1 input and 1 output. + * only 1 input and 0 output. */ static const int MIN_IN = 1; // mininum number of input streams static const int MAX_IN = 1; // maximum number of input streams @@ -65,18 +65,18 @@ osmosdr_snk_c::osmosdr_snk_c (const std::string & args) gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex))), osmosdr_tx_control(args) { - throw std::runtime_error("FIXME: OsmoSDR sink is not yet implemented"); + throw std::runtime_error("FIXME: OsmoSDR sink is not yet implemented"); - /* Audio sink; sample rate is 96kHz by default */ - audio_sink::sptr snk = audio_make_sink(96000, audio_dev_name(), true); + /* Audio sink; sample rate is 96kHz by default */ + audio_sink::sptr snk = audio_make_sink(96000, audio_dev_name(), true); - gr_complex_to_real_sptr real_part = gr_make_complex_to_real(1); - gr_complex_to_imag_sptr imag_part = gr_make_complex_to_imag(1); + gr_complex_to_real_sptr real_part = gr_make_complex_to_real(1); + gr_complex_to_imag_sptr imag_part = gr_make_complex_to_imag(1); - connect(self(), 0, real_part, 0); - connect(self(), 0, imag_part, 0); - connect(imag_part, 0, snk, 0); /* Left is I */ - connect(real_part, 0, snk, 1); /* Right is Q */ + connect(self(), 0, real_part, 0); + connect(self(), 0, imag_part, 0); + connect(imag_part, 0, snk, 0); /* Left is I */ + connect(real_part, 0, snk, 1); /* Right is Q */ } /* diff --git a/lib/osmosdr/osmosdr_snk_c.h b/lib/osmosdr/osmosdr_snk_c.h index d85562f..efef0c8 100644 --- a/lib/osmosdr/osmosdr_snk_c.h +++ b/lib/osmosdr/osmosdr_snk_c.h @@ -54,8 +54,9 @@ OSMOSDR_API osmosdr_snk_c_sptr osmosdr_make_snk_c (const std::string & args = "" * * This uses the preferred technique: subclassing gr_hier_block2. */ -class OSMOSDR_API osmosdr_snk_c : public gr_hier_block2, - public osmosdr_tx_control +class OSMOSDR_API osmosdr_snk_c : + public gr_hier_block2, + public osmosdr_tx_control { private: // The friend declaration allows osmosdr_make_snk_c to diff --git a/lib/osmosdr/osmosdr_src_c.cc b/lib/osmosdr/osmosdr_src_c.cc index b239237..9557864 100644 --- a/lib/osmosdr/osmosdr_src_c.cc +++ b/lib/osmosdr/osmosdr_src_c.cc @@ -31,6 +31,8 @@ #include <gr_audio_source.h> #include <gr_float_to_complex.h> +#include <osmosdr_arg_helpers.h> + /* * Create a new instance of osmosdr_src_c and return * a boost shared_ptr. This is effectively the public constructor. @@ -42,37 +44,23 @@ osmosdr_make_src_c (const std::string &args) } /* - * Specify constraints on number of input and output streams. - * This info is used to construct the input and output signatures - * (2nd & 3rd args to gr_block's constructor). The input and - * output signatures are used by the runtime system to - * check that a valid number and type of inputs and outputs - * are connected to this block. In this case, we accept - * only 1 input and 1 output. - */ -static const int MIN_IN = 0; // mininum number of input streams -static const int MAX_IN = 0; // maximum number of input streams -static const int MIN_OUT = 1; // minimum number of output streams -static const int MAX_OUT = 1; // maximum number of output streams - -/* * The private constructor */ osmosdr_src_c::osmosdr_src_c (const std::string &args) : gr_hier_block2 ("osmosdr_src_c", - gr_make_io_signature (MIN_IN, MAX_IN, sizeof (gr_complex)), - gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex))), + gr_make_io_signature (0, 0, sizeof (gr_complex)), + args_to_io_signature(args)), osmosdr_rx_control(args) { - /* Audio source; sample rate is 500kHz by default */ - audio_source::sptr src = audio_make_source(500000, audio_dev_name(), true); + /* Audio source; sample rate is 500kHz by default */ + audio_source::sptr src = audio_make_source(500000, audio_dev_name(), true); - /* block to convert stereo audio to a complex stream */ - gr_float_to_complex_sptr f2c = gr_make_float_to_complex(1); + /* block to convert stereo audio to a complex stream */ + gr_float_to_complex_sptr f2c = gr_make_float_to_complex(1); - connect(src, 0, f2c, 0); /* Left is I */ - connect(src, 1, f2c, 1); /* Right is Q */ - connect(f2c, 0, self(), 0); + connect(src, 0, f2c, 0); /* Left is I */ + connect(src, 1, f2c, 1); /* Right is Q */ + connect(f2c, 0, self(), 0); } /* diff --git a/lib/osmosdr/osmosdr_src_c.h b/lib/osmosdr/osmosdr_src_c.h index 5b639b2..de8644b 100644 --- a/lib/osmosdr/osmosdr_src_c.h +++ b/lib/osmosdr/osmosdr_src_c.h @@ -54,8 +54,9 @@ OSMOSDR_API osmosdr_src_c_sptr osmosdr_make_src_c (const std::string & args = "" * * \sa osmosdr_sink_c for a version that subclasses gr_hier_block2. */ -class OSMOSDR_API osmosdr_src_c : public gr_hier_block2, - public osmosdr_rx_control +class OSMOSDR_API osmosdr_src_c : + public gr_hier_block2, + public osmosdr_rx_control { private: // The friend declaration allows osmosdr_make_src_c to diff --git a/lib/osmosdr_arg_helpers.h b/lib/osmosdr_arg_helpers.h index 0e7f525..85644a2 100644 --- a/lib/osmosdr_arg_helpers.h +++ b/lib/osmosdr_arg_helpers.h @@ -31,6 +31,9 @@ #include <boost/tokenizer.hpp> #include <boost/foreach.hpp> +typedef std::map< std::string, std::string > dict_t; +typedef std::pair<std::string, std::string> pair_t; + inline std::vector< std::string > args_to_vector( const std::string &args ) { std::vector< std::string > result; @@ -59,25 +62,91 @@ inline std::vector< std::string > params_to_vector( const std::string ¶ms ) return result; } -typedef std::map< std::string, std::string > dict_t; +inline pair_t param_to_pair( const std::string ¶m ) +{ + pair_t result; + + std::size_t pos = param.find('='); + if(pos != std::string::npos) + { + result.first = param.substr(0, pos); + result.second = param.substr(pos + 1); + } + else + { + result.first = param; + result.second = ""; + } + + return result; +} inline dict_t params_to_dict( const std::string ¶ms ) { dict_t result; std::vector< std::string > param_list = params_to_vector( params ); - BOOST_FOREACH(std::string param, param_list) { - std::cout << "D'" << param << "'" << std::endl; + BOOST_FOREACH(std::string param, param_list) + { + pair_t nchan = param_to_pair( param ); + std::string value = nchan.second; + if (value.length() && value[0] == '\'' && value[ value.length() - 1 ] == '\'') + value = value.substr(1, value.length() - 1); + result[ nchan.first ] = nchan.second; } return result; } +struct is_nchan_argument +{ + bool operator ()(const std::string &str) + { + return str.find("nchan=") == 0; + } +}; + inline gr_io_signature_sptr args_to_io_signature( const std::string &args ) { + size_t max_nchan = 0; + size_t dev_nchan = 0; std::vector< std::string > arg_list = args_to_vector( args ); - const size_t nchan = std::max<size_t>(arg_list.size(), 1); + BOOST_FOREACH( std::string arg, arg_list ) + { + if ( arg.find( "nchan=" ) == 0 ) // try to parse global nchan value + { + pair_t pair = param_to_pair( arg ); + max_nchan = boost::lexical_cast<size_t>( pair.second ); + } + } + + arg_list.erase( std::remove_if( // remove any global nchan tokens + arg_list.begin(), + arg_list.end(), + is_nchan_argument() ), + arg_list.end() ); + + // try to parse device specific nchan values, assume 1 channel if none given + + BOOST_FOREACH( std::string arg, arg_list ) + { + dict_t dict = params_to_dict(arg); + if (dict.count("nchan")) + { + dev_nchan += boost::lexical_cast<size_t>( dict["nchan"] ); + } + else // no channels given via args + { + dev_nchan++; // assume one channel + } + } + + // if at least one nchan was given, perform a sanity check + if ( max_nchan && dev_nchan && max_nchan != dev_nchan ) + throw std::runtime_error("Wrong device arguments specified. Missing nchan?"); + + const size_t nchan = std::max<size_t>(dev_nchan, 1); // assume at least one return gr_make_io_signature(nchan, nchan, sizeof(gr_complex)); } diff --git a/lib/osmosdr_sink_c_impl.cc b/lib/osmosdr_sink_c_impl.cc index 092bfe7..7e6a1ec 100644 --- a/lib/osmosdr_sink_c_impl.cc +++ b/lib/osmosdr_sink_c_impl.cc @@ -47,12 +47,12 @@ osmosdr_make_sink_c (const std::string &args) * output signatures are used by the runtime system to * check that a valid number and type of inputs and outputs * are connected to this block. In this case, we accept - * only 1 input and 1 output. + * only 1 input and 0 output. */ -static const int MIN_IN = 0; // mininum number of input streams -static const int MAX_IN = 0; // maximum number of input streams -static const int MIN_OUT = 1; // minimum number of output streams -static const int MAX_OUT = 1; // maximum number of output streams +static const int MIN_IN = 1; // mininum number of input streams +static const int MAX_IN = 1; // maximum number of input streams +static const int MIN_OUT = 0; // minimum number of output streams +static const int MAX_OUT = 0; // maximum number of output streams /* * The private constructor diff --git a/lib/osmosdr_source_c_impl.cc b/lib/osmosdr_source_c_impl.cc index 8365eba..92b371f 100644 --- a/lib/osmosdr_source_c_impl.cc +++ b/lib/osmosdr_source_c_impl.cc @@ -30,6 +30,22 @@ #include <osmosdr_source_c_impl.h> #include <gr_io_signature.h> +#ifdef ENABLE_OSMOSDR +#include <osmosdr_src_c.h> +#endif + +#ifdef ENABLE_FCD +#include <fcd_source.h> +#endif + +#ifdef ENABLE_RTL +#include <rtl_source_c.h> +#endif + +#ifdef ENABLE_UHD +#include <uhd_source_c.h> +#endif + #include <osmosdr_arg_helpers.h> /* @@ -50,34 +66,65 @@ osmosdr_source_c_impl::osmosdr_source_c_impl (const std::string &args) gr_make_io_signature (0, 0, 0), args_to_io_signature(args)) { - std::vector< std::string > arg_list = args_to_vector(args); + size_t channel = 0; - std::cout << "arg_list.size: " << arg_list.size() << std::endl; + BOOST_FOREACH(std::string arg, args_to_vector(args)) { - BOOST_FOREACH(std::string arg, arg_list) { dict_t dict = params_to_dict(arg); - std::cout << "" << std::endl; - BOOST_FOREACH( dict_t::value_type &entry, dict ) - std::cout << "'" << entry.first << "' '" << entry.second << "'" << std::endl; - } +// std::cout << std::endl; +// BOOST_FOREACH( dict_t::value_type &entry, dict ) +// std::cout << "'" << entry.first << "' = '" << entry.second << "'" << std::endl; - for ( int i = 0; i < 1; i++ ) { - std::string arg = boost::lexical_cast<std::string>(i); +#ifdef ENABLE_OSMOSDR + if ( dict.count("osmosdr") ) { + osmosdr_src_c_sptr src = osmosdr_make_src_c( arg ); - rtl_source_c_sptr src = make_rtl_source_c( arg ); +// for (size_t i = 0; i < src->get_num_channels(); i++) +// connect(src, i, self(), channel++); - connect(src, 0, self(), i); +// _srcs.push_back( (osmosdr_src_iface *)src.get() ); // FIXME: implement + } +#endif + +#ifdef ENABLE_FCD + if ( dict.count("fcd") ) { + fcd_source_sptr src = make_fcd_source( arg ); + connect(src, 0, self(), channel++); + _srcs.push_back( (osmosdr_src_iface *)src.get() ); + } +#endif + +#ifdef ENABLE_RTL + if ( dict.count("rtl") ) { + rtl_source_c_sptr src = make_rtl_source_c( arg ); + connect(src, 0, self(), channel++); + _srcs.push_back( (osmosdr_src_iface *)src.get() ); + } +#endif - _srcs.push_back( src ); +#ifdef ENABLE_UHD + if ( dict.count("uhd") ) { + uhd_source_c_sptr src = make_uhd_source_c( arg ); + + for (size_t i = 0; i < src->get_num_channels(); i++) + connect(src, i, self(), channel++); + + _srcs.push_back( (osmosdr_src_iface *)src.get() ); + } +#endif } + + if (!_srcs.size()) + throw std::runtime_error("No devices specified via device arguments."); } size_t osmosdr_source_c_impl::get_num_channels() { size_t channels = 0; - channels = _srcs[0]->get_num_channels(); + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + channels += dev->get_num_channels(); return channels; } @@ -89,8 +136,12 @@ osmosdr::meta_range_t osmosdr_source_c_impl::get_sample_rates() double osmosdr_source_c_impl::set_sample_rate(double rate) { - return _srcs[0]->set_sample_rate(rate); -// return rate; + double sample_rate = 0; + + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + sample_rate = dev->set_sample_rate(rate); + + return sample_rate; } double osmosdr_source_c_impl::get_sample_rate() @@ -100,76 +151,165 @@ double osmosdr_source_c_impl::get_sample_rate() osmosdr::freq_range_t osmosdr_source_c_impl::get_freq_range( size_t chan ) { - return _srcs[chan]->get_freq_range( chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->get_freq_range( chan ); + + return osmosdr::freq_range_t(); } double osmosdr_source_c_impl::set_center_freq( double freq, size_t chan ) { - return _srcs[chan]->set_center_freq( freq, chan ); -// return freq; + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->set_center_freq( freq, chan ); + + return 0; } double osmosdr_source_c_impl::get_center_freq( size_t chan ) { - return _srcs[chan]->get_center_freq( chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->get_center_freq( chan ); + + return 0; } double osmosdr_source_c_impl::set_freq_corr( double ppm, size_t chan ) { - return _srcs[chan]->set_freq_corr( ppm, chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->set_freq_corr( ppm, chan ); + + return 0; } double osmosdr_source_c_impl::get_freq_corr( size_t chan ) { - return _srcs[chan]->get_freq_corr( chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->get_freq_corr( chan ); + + return 0; } std::vector<std::string> osmosdr_source_c_impl::get_gain_names( size_t chan ) { - return _srcs[chan]->get_gain_names( chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->get_gain_names( chan ); + + return std::vector< std::string >(); } osmosdr::gain_range_t osmosdr_source_c_impl::get_gain_range( size_t chan ) { - return _srcs[chan]->get_gain_range( chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->get_gain_range( chan ); + + return osmosdr::gain_range_t(); } osmosdr::gain_range_t osmosdr_source_c_impl::get_gain_range( const std::string & name, size_t chan ) { - return _srcs[chan]->get_gain_range( name, chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->get_gain_range( name, chan ); + + return osmosdr::gain_range_t(); } double osmosdr_source_c_impl::set_gain( double gain, size_t chan ) { - return _srcs[chan]->set_gain( gain, chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->set_gain( gain, chan ); + + return 0; } double osmosdr_source_c_impl::set_gain( double gain, const std::string & name, size_t chan) { - return _srcs[chan]->set_gain( gain, name, chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->set_gain( gain, name, chan ); + + return 0; } double osmosdr_source_c_impl::get_gain( size_t chan ) { - return _srcs[chan]->get_gain( chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->get_gain( chan ); + + return 0; } double osmosdr_source_c_impl::get_gain( const std::string & name, size_t chan ) { - return _srcs[chan]->get_gain( name, chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->get_gain( name, chan ); + + return 0; } std::vector< std::string > osmosdr_source_c_impl::get_antennas( size_t chan ) { - return _srcs[chan]->get_antennas( chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->get_antennas( chan ); + + return std::vector< std::string >(); } std::string osmosdr_source_c_impl::set_antenna( const std::string & antenna, size_t chan ) { - return _srcs[chan]->set_antenna( antenna, chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->set_antenna( antenna, chan ); + + return ""; } std::string osmosdr_source_c_impl::get_antenna( size_t chan ) { - return _srcs[chan]->get_antenna( chan ); + size_t channel = 0; + BOOST_FOREACH( osmosdr_src_iface *dev, _srcs ) + for (size_t i = 0; i < dev->get_num_channels(); i++) + if ( chan == channel++ ) + return _srcs[chan]->get_antenna( chan ); + + return ""; } diff --git a/lib/osmosdr_source_c_impl.h b/lib/osmosdr_source_c_impl.h index a52fdf7..1cc1fe1 100644 --- a/lib/osmosdr_source_c_impl.h +++ b/lib/osmosdr_source_c_impl.h @@ -23,7 +23,7 @@ #include <osmosdr_api.h> #include <osmosdr_source_c.h> -#include <rtl_source_c.h> +#include <osmosdr_src_iface.h> class OSMOSDR_API osmosdr_source_c_impl : public osmosdr_source_c { @@ -60,7 +60,7 @@ private: friend OSMOSDR_API osmosdr_source_c_sptr osmosdr_make_source_c (const std::string & args); size_t _nchan; - std::vector< rtl_source_c_sptr > _srcs; + std::vector< osmosdr_src_iface * > _srcs; }; #endif /* INCLUDED_OSMOSDR_SOURCE_C_IMPL_H */ diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc index 75a0ae4..532d86a 100644 --- a/lib/rtl/rtl_source_c.cc +++ b/lib/rtl/rtl_source_c.cc @@ -38,6 +38,8 @@ #include <rtl-sdr.h> +#include <osmosdr_arg_helpers.h> + using namespace boost::assign; #define BUF_SIZE (16 * 32 * 512) @@ -59,7 +61,7 @@ make_rtl_source_c (const std::string &args) * output signatures are used by the runtime system to * check that a valid number and type of inputs and outputs * are connected to this block. In this case, we accept - * only 1 input and 1 output. + * only 0 input and 1 output. */ static const int MIN_IN = 0; // mininum number of input streams static const int MAX_IN = 0; // maximum number of input streams @@ -75,9 +77,12 @@ rtl_source_c::rtl_source_c (const std::string &args) gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex))) { int ret; - unsigned int dev_index = atoi( args.c_str() ); + unsigned int dev_index = 0; + + dict_t dict = params_to_dict(args); - std::cout << "'" << args << "'" << std::endl; + if (dict.count("rtl")) + dev_index = boost::lexical_cast< unsigned int >( dict["rtl"] ); _buf_num = 32; _buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *)); diff --git a/lib/rtl/rtl_source_c.h b/lib/rtl/rtl_source_c.h index 1f2b1f4..944d153 100644 --- a/lib/rtl/rtl_source_c.h +++ b/lib/rtl/rtl_source_c.h @@ -61,8 +61,9 @@ OSMOSDR_API rtl_source_c_sptr make_rtl_source_c (const std::string & args = ""); * \ingroup block * */ -class OSMOSDR_API rtl_source_c : public gr_sync_block, - public osmosdr_src_iface +class OSMOSDR_API rtl_source_c : + public gr_sync_block, + public osmosdr_src_iface { private: // The friend declaration allows make_rtl_source_c to diff --git a/lib/uhd/uhd_source_c.cc b/lib/uhd/uhd_source_c.cc index 3bede37..3baeed6 100644 --- a/lib/uhd/uhd_source_c.cc +++ b/lib/uhd/uhd_source_c.cc @@ -25,23 +25,38 @@ #include <gr_io_signature.h> +#include <osmosdr_arg_helpers.h> + #include "uhd_source_c.h" using namespace boost::assign; uhd_source_c_sptr make_uhd_source_c(const std::string &args) { - return gnuradio::get_initial_sptr(new uhd_source_c(args)); + return gnuradio::get_initial_sptr(new uhd_source_c(args)); } uhd_source_c::uhd_source_c(const std::string &args) : gr_hier_block2("uhd_source_c", gr_make_io_signature (0, 0, 0), - gr_make_io_signature (1, 1, sizeof (gr_complex))) + args_to_io_signature(args)) { - _src = uhd_make_usrp_source( args, uhd::io_type_t::COMPLEX_FLOAT32, 1 ); + size_t num_channels = 1; + + dict_t dict = params_to_dict(args); + + if (dict.count("nchan")) + num_channels = boost::lexical_cast< unsigned int >( dict["nchan"] ); + + _src = uhd_make_usrp_source( args, + uhd::io_type_t::COMPLEX_FLOAT32, + num_channels ); + + if (dict.count("subdev")) + _src->set_subdev_spec( dict["subdev"] ); - connect( _src, 0, self(), 0 ); + for ( size_t i = 0; i < num_channels; i++ ) + connect( _src, i, self(), i ); } uhd_source_c::~uhd_source_c() @@ -50,18 +65,18 @@ uhd_source_c::~uhd_source_c() std::vector< std::string > uhd_source_c::get_devices() { - std::vector< std::string > devices; + std::vector< std::string > devices; - uhd::device_addr_t hint; - BOOST_FOREACH(uhd::device_addr_t device, uhd::device::find(hint)) - devices += device.to_string(); + uhd::device_addr_t hint; + BOOST_FOREACH(uhd::device_addr_t device, uhd::device::find(hint)) + devices += device.to_string(); - return devices; + return devices; } gr_basic_block_sptr uhd_source_c::self() { - return gr_hier_block2::self(); + return gr_hier_block2::self(); } std::string uhd_source_c::name() @@ -132,7 +147,7 @@ double uhd_source_c::set_freq_corr( double ppm, size_t chan ) double uhd_source_c::get_freq_corr( size_t chan ) { - throw std::runtime_error( "frequency correction is not supported with UHD" ); + return 0; // frequency correction is not supported with UHD } std::vector<std::string> uhd_source_c::get_gain_names( size_t chan ) diff --git a/lib/uhd/uhd_source_c.h b/lib/uhd/uhd_source_c.h index bc398bf..84e7f66 100644 --- a/lib/uhd/uhd_source_c.h +++ b/lib/uhd/uhd_source_c.h @@ -32,8 +32,9 @@ typedef boost::shared_ptr< uhd_source_c > uhd_source_c_sptr; uhd_source_c_sptr make_uhd_source_c(const std::string &args = ""); -class uhd_source_c : public gr_hier_block2, - public osmosdr_src_iface +class uhd_source_c : + public gr_hier_block2, + public osmosdr_src_iface { private: friend uhd_source_c_sptr make_uhd_source_c(const std::string &args); |