first working multichannel source

This commit is contained in:
Dimitri Stolnikov 2012-04-28 20:18:14 +02:00
parent 31a4356ba5
commit c1c0c2f212
15 changed files with 394 additions and 168 deletions

View File

@ -28,33 +28,38 @@
#include <fcd_source.h> #include <fcd_source.h>
#include <osmosdr_arg_helpers.h>
using namespace boost::assign; using namespace boost::assign;
fcd_source_sptr make_fcd_source(const std::string &args) 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) : fcd_source::fcd_source(const std::string &args) :
gr_hier_block2("fcd_source", gr_hier_block2("fcd_source",
gr_make_io_signature (0, 0, 0), gr_make_io_signature (0, 0, 0),
gr_make_io_signature (1, 1, sizeof (gr_complex))) 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() ) dict_t dict = params_to_dict(args);
{
std::vector< std::string > devices = fcd_source::get_devices();
if ( devices.size() ) if (dict.count("fcd"))
device_name = devices.front(); // pick first available device dev_index = boost::lexical_cast< unsigned int >( dict["fcd"] );
else
throw std::runtime_error("no FUNcube Dongle device found");
}
_src = fcd_make_source_c( device_name ); std::vector< std::string > devices = fcd_source::get_devices();
connect( _src, 0, self(), 0 ); if ( devices.size() )
dev_name = devices[dev_index];
else
throw std::runtime_error("No FunCube Dongle found.");
_src = fcd_make_source_c( dev_name );
connect( _src, 0, self(), 0 );
} }
fcd_source::~fcd_source() fcd_source::~fcd_source()
@ -63,42 +68,42 @@ fcd_source::~fcd_source()
std::vector< std::string > fcd_source::get_devices() std::vector< std::string > fcd_source::get_devices()
{ {
std::vector< std::string > devices; std::vector< std::string > devices;
std::string line; std::string line;
std::ifstream cards( "/proc/asound/cards" ); std::ifstream cards( "/proc/asound/cards" );
if ( cards.is_open() ) if ( cards.is_open() )
{
while ( cards.good() )
{ {
while ( cards.good() ) getline (cards, line);
{
getline (cards, line);
if ( line.find( "USB-Audio - FUNcube Dongle" ) != std::string::npos ) if ( line.find( "USB-Audio - FUNcube Dongle" ) != std::string::npos )
{ {
int id; int id;
std::istringstream( line ) >> id; std::istringstream( line ) >> id;
std::ostringstream hw_id; std::ostringstream hw_id;
hw_id << "hw:" << id; // build alsa identifier hw_id << "hw:" << id; // build alsa identifier
devices += hw_id.str(); devices += hw_id.str();
} }
}
cards.close();
} }
return devices; cards.close();
}
return devices;
} }
gr_basic_block_sptr fcd_source::self() gr_basic_block_sptr fcd_source::self()
{ {
return gr_hier_block2::self(); return gr_hier_block2::self();
} }
std::string fcd_source::name() std::string fcd_source::name()
{ {
return "FUNcube Dongle"; return "FUNcube Dongle";
} }
size_t fcd_source::get_num_channels( void ) size_t fcd_source::get_num_channels( void )
@ -223,4 +228,3 @@ std::string fcd_source::get_antenna( size_t chan )
{ {
return "ANT"; return "ANT";
} }

View File

@ -32,8 +32,9 @@ typedef boost::shared_ptr< fcd_source > fcd_source_sptr;
fcd_source_sptr make_fcd_source( const std::string & args = "" ); fcd_source_sptr make_fcd_source( const std::string & args = "" );
class fcd_source : public gr_hier_block2, class fcd_source :
public osmosdr_src_iface public gr_hier_block2,
public osmosdr_src_iface
{ {
private: private:
friend fcd_source_sptr make_fcd_source(const std::string &args); friend fcd_source_sptr make_fcd_source(const std::string &args);

View File

@ -30,12 +30,12 @@ using namespace boost::assign;
osmosdr_control::osmosdr_control(const std::string &args) 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()) if (args.empty())
pick first available device or throw an exception(); pick first available device or throw an exception();
*/ */
} }
osmosdr_control::~osmosdr_control() osmosdr_control::~osmosdr_control()
@ -48,46 +48,46 @@ osmosdr_control::~osmosdr_control()
*/ */
std::vector< std::string > osmosdr_control::find_devices() std::vector< std::string > osmosdr_control::find_devices()
{ {
std::vector< std::string > devices; std::vector< std::string > devices;
std::string line; std::string line;
std::ifstream cards( "/proc/asound/cards" ); std::ifstream cards( "/proc/asound/cards" );
if ( cards.is_open() ) 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 ) if ( line.find( "USB-Audio - OsmoSDR" ) != std::string::npos )
{ {
int id; int id;
std::istringstream( line ) >> id; std::istringstream( line ) >> id;
std::ostringstream hw_id; std::ostringstream hw_id;
hw_id << "hw:" << id; // build alsa identifier hw_id << "hw:" << id; // build alsa identifier
devices += hw_id.str(); devices += hw_id.str();
} }
}
cards.close();
} }
return devices; cards.close();
}
return devices;
} }
std::string osmosdr_control::audio_dev_name() std::string osmosdr_control::audio_dev_name()
{ {
return "hw:1"; return "hw:1";
} }
std::string osmosdr_control::control_dev_name() std::string osmosdr_control::control_dev_name()
{ {
return "/dev/ttyUSB0"; return "/dev/ttyUSB0";
} }
osmosdr_rx_control::osmosdr_rx_control(const std::string &args) : 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_tx_control::osmosdr_tx_control(const std::string &args) :
osmosdr_control(args) osmosdr_control(args)
{ {
} }

View File

@ -27,7 +27,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include <osmosdr_snk_c.h> #include "osmosdr_snk_c.h"
#include <gr_io_signature.h> #include <gr_io_signature.h>
#include <gr_audio_sink.h> #include <gr_audio_sink.h>
#include <gr_complex_to_xxx.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 * output signatures are used by the runtime system to
* check that a valid number and type of inputs and outputs * check that a valid number and type of inputs and outputs
* are connected to this block. In this case, we accept * 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 MIN_IN = 1; // mininum number of input streams
static const int MAX_IN = 1; // maximum 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))), gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex))),
osmosdr_tx_control(args) 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; sample rate is 96kHz by default */
audio_sink::sptr snk = audio_make_sink(96000, audio_dev_name(), true); 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_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_imag_sptr imag_part = gr_make_complex_to_imag(1);
connect(self(), 0, real_part, 0); connect(self(), 0, real_part, 0);
connect(self(), 0, imag_part, 0); connect(self(), 0, imag_part, 0);
connect(imag_part, 0, snk, 0); /* Left is I */ connect(imag_part, 0, snk, 0); /* Left is I */
connect(real_part, 0, snk, 1); /* Right is Q */ connect(real_part, 0, snk, 1); /* Right is Q */
} }
/* /*

View File

@ -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. * This uses the preferred technique: subclassing gr_hier_block2.
*/ */
class OSMOSDR_API osmosdr_snk_c : public gr_hier_block2, class OSMOSDR_API osmosdr_snk_c :
public osmosdr_tx_control public gr_hier_block2,
public osmosdr_tx_control
{ {
private: private:
// The friend declaration allows osmosdr_make_snk_c to // The friend declaration allows osmosdr_make_snk_c to

View File

@ -31,6 +31,8 @@
#include <gr_audio_source.h> #include <gr_audio_source.h>
#include <gr_float_to_complex.h> #include <gr_float_to_complex.h>
#include <osmosdr_arg_helpers.h>
/* /*
* Create a new instance of osmosdr_src_c and return * Create a new instance of osmosdr_src_c and return
* a boost shared_ptr. This is effectively the public constructor. * a boost shared_ptr. This is effectively the public constructor.
@ -41,38 +43,24 @@ osmosdr_make_src_c (const std::string &args)
return gnuradio::get_initial_sptr(new osmosdr_src_c (args)); return gnuradio::get_initial_sptr(new osmosdr_src_c (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 * The private constructor
*/ */
osmosdr_src_c::osmosdr_src_c (const std::string &args) osmosdr_src_c::osmosdr_src_c (const std::string &args)
: gr_hier_block2 ("osmosdr_src_c", : gr_hier_block2 ("osmosdr_src_c",
gr_make_io_signature (MIN_IN, MAX_IN, sizeof (gr_complex)), gr_make_io_signature (0, 0, sizeof (gr_complex)),
gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex))), args_to_io_signature(args)),
osmosdr_rx_control(args) osmosdr_rx_control(args)
{ {
/* Audio source; sample rate is 500kHz by default */ /* Audio source; sample rate is 500kHz by default */
audio_source::sptr src = audio_make_source(500000, audio_dev_name(), true); audio_source::sptr src = audio_make_source(500000, audio_dev_name(), true);
/* block to convert stereo audio to a complex stream */ /* block to convert stereo audio to a complex stream */
gr_float_to_complex_sptr f2c = gr_make_float_to_complex(1); gr_float_to_complex_sptr f2c = gr_make_float_to_complex(1);
connect(src, 0, f2c, 0); /* Left is I */ connect(src, 0, f2c, 0); /* Left is I */
connect(src, 1, f2c, 1); /* Right is Q */ connect(src, 1, f2c, 1); /* Right is Q */
connect(f2c, 0, self(), 0); connect(f2c, 0, self(), 0);
} }
/* /*

View File

@ -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. * \sa osmosdr_sink_c for a version that subclasses gr_hier_block2.
*/ */
class OSMOSDR_API osmosdr_src_c : public gr_hier_block2, class OSMOSDR_API osmosdr_src_c :
public osmosdr_rx_control public gr_hier_block2,
public osmosdr_rx_control
{ {
private: private:
// The friend declaration allows osmosdr_make_src_c to // The friend declaration allows osmosdr_make_src_c to

View File

@ -31,6 +31,9 @@
#include <boost/tokenizer.hpp> #include <boost/tokenizer.hpp>
#include <boost/foreach.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 ) inline std::vector< std::string > args_to_vector( const std::string &args )
{ {
std::vector< std::string > result; std::vector< std::string > result;
@ -59,25 +62,91 @@ inline std::vector< std::string > params_to_vector( const std::string &params )
return result; return result;
} }
typedef std::map< std::string, std::string > dict_t; inline pair_t param_to_pair( const std::string &param )
{
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 &params ) inline dict_t params_to_dict( const std::string &params )
{ {
dict_t result; dict_t result;
std::vector< std::string > param_list = params_to_vector( params ); std::vector< std::string > param_list = params_to_vector( params );
BOOST_FOREACH(std::string param, param_list) { BOOST_FOREACH(std::string param, param_list)
std::cout << "D'" << param << "'" << std::endl; {
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; 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 ) 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 ); 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)); return gr_make_io_signature(nchan, nchan, sizeof(gr_complex));
} }

View File

@ -47,12 +47,12 @@ osmosdr_make_sink_c (const std::string &args)
* output signatures are used by the runtime system to * output signatures are used by the runtime system to
* check that a valid number and type of inputs and outputs * check that a valid number and type of inputs and outputs
* are connected to this block. In this case, we accept * 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 MIN_IN = 1; // mininum number of input streams
static const int MAX_IN = 0; // maximum number of input streams static const int MAX_IN = 1; // maximum number of input streams
static const int MIN_OUT = 1; // minimum number of output streams static const int MIN_OUT = 0; // minimum number of output streams
static const int MAX_OUT = 1; // maximum number of output streams static const int MAX_OUT = 0; // maximum number of output streams
/* /*
* The private constructor * The private constructor

View File

@ -30,6 +30,22 @@
#include <osmosdr_source_c_impl.h> #include <osmosdr_source_c_impl.h>
#include <gr_io_signature.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> #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), gr_make_io_signature (0, 0, 0),
args_to_io_signature(args)) 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); dict_t dict = params_to_dict(arg);
std::cout << "" << std::endl; // std::cout << std::endl;
BOOST_FOREACH( dict_t::value_type &entry, dict ) // BOOST_FOREACH( dict_t::value_type &entry, dict )
std::cout << "'" << entry.first << "' '" << entry.second << "'" << std::endl; // std::cout << "'" << entry.first << "' = '" << entry.second << "'" << std::endl;
#ifdef ENABLE_OSMOSDR
if ( dict.count("osmosdr") ) {
osmosdr_src_c_sptr src = osmosdr_make_src_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() ); // 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
#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
} }
for ( int i = 0; i < 1; i++ ) { if (!_srcs.size())
std::string arg = boost::lexical_cast<std::string>(i); throw std::runtime_error("No devices specified via device arguments.");
rtl_source_c_sptr src = make_rtl_source_c( arg );
connect(src, 0, self(), i);
_srcs.push_back( src );
}
} }
size_t osmosdr_source_c_impl::get_num_channels() size_t osmosdr_source_c_impl::get_num_channels()
{ {
size_t channels = 0; size_t channels = 0;
channels = _srcs[0]->get_num_channels(); BOOST_FOREACH( osmosdr_src_iface *dev, _srcs )
channels += dev->get_num_channels();
return 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) double osmosdr_source_c_impl::set_sample_rate(double rate)
{ {
return _srcs[0]->set_sample_rate(rate); double sample_rate = 0;
// return rate;
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() 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 ) 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 ) double osmosdr_source_c_impl::set_center_freq( double freq, size_t chan )
{ {
return _srcs[chan]->set_center_freq( freq, chan ); size_t channel = 0;
// return freq; 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 ) 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 ) 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 ) 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 ) 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 ) 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 ) 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 ) 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) 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 ) 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 ) 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 ) 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 ) 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 ) 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 "";
} }

View File

@ -23,7 +23,7 @@
#include <osmosdr_api.h> #include <osmosdr_api.h>
#include <osmosdr_source_c.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 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); friend OSMOSDR_API osmosdr_source_c_sptr osmosdr_make_source_c (const std::string & args);
size_t _nchan; size_t _nchan;
std::vector< rtl_source_c_sptr > _srcs; std::vector< osmosdr_src_iface * > _srcs;
}; };
#endif /* INCLUDED_OSMOSDR_SOURCE_C_IMPL_H */ #endif /* INCLUDED_OSMOSDR_SOURCE_C_IMPL_H */

View File

@ -38,6 +38,8 @@
#include <rtl-sdr.h> #include <rtl-sdr.h>
#include <osmosdr_arg_helpers.h>
using namespace boost::assign; using namespace boost::assign;
#define BUF_SIZE (16 * 32 * 512) #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 * output signatures are used by the runtime system to
* check that a valid number and type of inputs and outputs * check that a valid number and type of inputs and outputs
* are connected to this block. In this case, we accept * 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 MIN_IN = 0; // mininum number of input streams
static const int MAX_IN = 0; // maximum 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))) gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex)))
{ {
int ret; int ret;
unsigned int dev_index = atoi( args.c_str() ); unsigned int dev_index = 0;
std::cout << "'" << args << "'" << std::endl; dict_t dict = params_to_dict(args);
if (dict.count("rtl"))
dev_index = boost::lexical_cast< unsigned int >( dict["rtl"] );
_buf_num = 32; _buf_num = 32;
_buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *)); _buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *));

View File

@ -61,8 +61,9 @@ OSMOSDR_API rtl_source_c_sptr make_rtl_source_c (const std::string & args = "");
* \ingroup block * \ingroup block
* *
*/ */
class OSMOSDR_API rtl_source_c : public gr_sync_block, class OSMOSDR_API rtl_source_c :
public osmosdr_src_iface public gr_sync_block,
public osmosdr_src_iface
{ {
private: private:
// The friend declaration allows make_rtl_source_c to // The friend declaration allows make_rtl_source_c to

View File

@ -25,23 +25,38 @@
#include <gr_io_signature.h> #include <gr_io_signature.h>
#include <osmosdr_arg_helpers.h>
#include "uhd_source_c.h" #include "uhd_source_c.h"
using namespace boost::assign; using namespace boost::assign;
uhd_source_c_sptr make_uhd_source_c(const std::string &args) 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) : uhd_source_c::uhd_source_c(const std::string &args) :
gr_hier_block2("uhd_source_c", gr_hier_block2("uhd_source_c",
gr_make_io_signature (0, 0, 0), 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;
connect( _src, 0, self(), 0 ); 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"] );
for ( size_t i = 0; i < num_channels; i++ )
connect( _src, i, self(), i );
} }
uhd_source_c::~uhd_source_c() 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 > uhd_source_c::get_devices()
{ {
std::vector< std::string > devices; std::vector< std::string > devices;
uhd::device_addr_t hint; uhd::device_addr_t hint;
BOOST_FOREACH(uhd::device_addr_t device, uhd::device::find(hint)) BOOST_FOREACH(uhd::device_addr_t device, uhd::device::find(hint))
devices += device.to_string(); devices += device.to_string();
return devices; return devices;
} }
gr_basic_block_sptr uhd_source_c::self() gr_basic_block_sptr uhd_source_c::self()
{ {
return gr_hier_block2::self(); return gr_hier_block2::self();
} }
std::string uhd_source_c::name() 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 ) 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 ) std::vector<std::string> uhd_source_c::get_gain_names( size_t chan )

View File

@ -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 = ""); uhd_source_c_sptr make_uhd_source_c(const std::string &args = "");
class uhd_source_c : public gr_hier_block2, class uhd_source_c :
public osmosdr_src_iface public gr_hier_block2,
public osmosdr_src_iface
{ {
private: private:
friend uhd_source_c_sptr make_uhd_source_c(const std::string &args); friend uhd_source_c_sptr make_uhd_source_c(const std::string &args);