diff --git a/grc/gen_osmosdr_blocks.py b/grc/gen_osmosdr_blocks.py index a10c871..c93ace6 100644 --- a/grc/gen_osmosdr_blocks.py +++ b/grc/gen_osmosdr_blocks.py @@ -26,7 +26,7 @@ MAIN_TMPL = """\ $($sourk.title())s 1 import osmosdr - osmosdr.$(sourk)( args="numchan=" + str(\$nchan) + " " + \$args ) + osmosdr.$(sourk)( args=\$args ) self.\$(id).set_sample_rate(\$sample_rate) #for $n in range($max_nchan) \#if \$nchan() > $n @@ -69,6 +69,21 @@ self.\$(id).set_bandwidth(\$bw$(n), $n) fc32 type:fc32 + + + Device Arguments @@ -132,8 +147,11 @@ While primarily being developed for the OsmoSDR hardware, this block as well sup By using the osmocom $sourk block you can take advantage of a common software api in your application(s) independent of the underlying radio hardware. -Output Type: -This parameter controls the data type of the stream in gnuradio. Only complex float32 samples are supported at the moment. +$(dir.title())put Type: +This parameter controls the data type of the stream in gnuradio. +Complex float32, Complex int16 and Complex int8 are available for UHD devices. +Complex float32 and Octet stream are available for bladeRF sink. +Complex float32 must be used for everything else. Device Arguments: The device argument is a comma delimited string used to locate devices on your system. Device arguments for multiple devices may be given by separating them with a space. @@ -167,7 +185,7 @@ Num Channels: Selects the total number of channels in this multi-device configuration. Required when specifying multiple device arguments. Sample Rate: -The sample rate is the number of samples per second output by this block on each channel. +The sample rate is the number of samples per second on each channel. Frequency: The center frequency is the frequency the RF chain is tuned to. diff --git a/lib/sink_impl.cc b/lib/sink_impl.cc index 3f4db4b..9d3cdbe 100644 --- a/lib/sink_impl.cc +++ b/lib/sink_impl.cc @@ -64,7 +64,7 @@ osmosdr::sink::make( const std::string &args ) */ sink_impl::sink_impl( const std::string &args ) : gr::hier_block2 ("sink_impl", - args_to_io_signature(args), + gr::io_signature::make(1, 1, sizeof(gr_complex)), gr::io_signature::make(0, 0, 0)), _sample_rate(NAN) { @@ -129,6 +129,10 @@ sink_impl::sink_impl( const std::string &args ) throw std::runtime_error("No supported devices found to pick from."); } + int min_streams = 0, max_streams = 0; + std::vector stream_items; + std::vector< gr::basic_block_sptr > blocks; + BOOST_FOREACH(std::string arg, arg_list) { dict_t dict = params_to_dict(arg); @@ -161,15 +165,36 @@ sink_impl::sink_impl( const std::string &args ) if ( iface != NULL && long(block.get()) != 0 ) { _devs.push_back( iface ); + blocks.push_back( block ); - for (size_t i = 0; i < iface->get_num_channels(); i++) { - connect(self(), channel++, block, i); - } + min_streams += block->input_signature()->min_streams(); + max_streams += block->input_signature()->max_streams(); + + if ( stream_items.empty() ) + stream_items.push_back( block->input_signature()->sizeof_stream_item(0) ); + +// BOOST_FOREACH(int size, block->input_signature()->sizeof_stream_items()) +// { +// stream_items.push_back( size ); +// } } else if ( (iface != NULL) || (long(block.get()) != 0) ) throw std::runtime_error("Eitner iface or block are NULL."); } + set_input_signature( gr::io_signature::makev( min_streams, + max_streams, + stream_items ) ); + + for (size_t k = 0; k < _devs.size(); k++) + { + gr::basic_block_sptr block = blocks[k]; + + for (size_t i = 0; i < _devs[k]->get_num_channels(); i++) { + connect(self(), channel++, block, i); + } + } + if (!_devs.size()) throw std::runtime_error("No devices specified via device arguments."); #ifdef WORKAROUND_GR_HIER_BLOCK2_BUG diff --git a/lib/source_impl.cc b/lib/source_impl.cc index 1e9af47..2e5f876 100644 --- a/lib/source_impl.cc +++ b/lib/source_impl.cc @@ -99,7 +99,7 @@ osmosdr::source::make( const std::string &args ) source_impl::source_impl( const std::string &args ) : gr::hier_block2 ("source_impl", gr::io_signature::make(0, 0, 0), - args_to_io_signature(args)), + gr::io_signature::make(1, 1, sizeof(gr_complex))), _sample_rate(NAN) { size_t channel = 0; @@ -217,6 +217,10 @@ source_impl::source_impl( const std::string &args ) throw std::runtime_error("No supported devices found to pick from."); } + int min_streams = 0, max_streams = 0; + std::vector stream_items; + std::vector< gr::basic_block_sptr > blocks; + BOOST_FOREACH(std::string arg, arg_list) { dict_t dict = params_to_dict(arg); @@ -310,29 +314,72 @@ source_impl::source_impl( const std::string &args ) if ( iface != NULL && long(block.get()) != 0 ) { _devs.push_back( iface ); + blocks.push_back( block ); - for (size_t i = 0; i < iface->get_num_channels(); i++) { -#ifdef HAVE_IQBALANCE - gr::iqbalance::optimize_c::sptr iq_opt = gr::iqbalance::optimize_c::make( 0 ); - gr::iqbalance::fix_cc::sptr iq_fix = gr::iqbalance::fix_cc::make(); + min_streams += block->output_signature()->min_streams(); + max_streams += block->output_signature()->max_streams(); - connect(block, i, iq_fix, 0); - connect(iq_fix, 0, self(), channel++); - - connect(block, i, iq_opt, 0); - msg_connect(iq_opt, "iqbal_corr", iq_fix, "iqbal_corr"); - - _iq_opt.push_back( iq_opt.get() ); - _iq_fix.push_back( iq_fix.get() ); -#else - connect(block, i, self(), channel++); -#endif + BOOST_FOREACH(int size, block->output_signature()->sizeof_stream_items()) + { + stream_items.push_back( size ); } } else if ( (iface != NULL) || (long(block.get()) != 0) ) throw std::runtime_error("Eitner iface or block are NULL."); } + std::cerr << min_streams << " " << max_streams << " { "; + for ( size_t i = 0; i < stream_items.size(); ++i ) + std::cerr << stream_items[i] << " "; + std::cerr << "}" << std::endl; + + set_output_signature( gr::io_signature::makev( min_streams, + max_streams, + stream_items ) ); + + for (size_t k = 0; k < _devs.size(); k++) + { + gr::basic_block_sptr block = blocks[k]; + + for (int i = 0; i < block->output_signature()->max_streams(); i++) { +#ifdef HAVE_IQBALANCE +#if 0 + gr::iqbalance::optimize_c::sptr iq_opt = gr::iqbalance::optimize_c::make( 0 ); + gr::iqbalance::fix_cc::sptr iq_fix = gr::iqbalance::fix_cc::make(); + + std::cerr << block->output_signature()->sizeof_stream_item(i) << " " + << iq_fix->input_signature()->sizeof_stream_item(0) << " "; + + if ( block->output_signature()->sizeof_stream_item(i) == + iq_fix->input_signature()->sizeof_stream_item(0) ) + { + connect(block, i, iq_fix, 0); + connect(iq_fix, 0, self(), channel++); + + connect(block, i, iq_opt, 0); + msg_connect(iq_opt, "iqbal_corr", iq_fix, "iqbal_corr"); + + _iq_opt.push_back( iq_opt.get() ); + _iq_fix.push_back( iq_fix.get() ); + } + else +#endif + { +// std::cerr << "Signatures don't match, bypassing gr::iqbalance on channel " +// << channel << std::endl; + + std::cerr << "connect" << k << ": out" << i << " to in" << channel << std::endl; + + connect(block, i, self(), channel++); + } +#else + connect(block, i, self(), channel++); +#endif + } + } + + std::cerr << "connect passed" << std::endl; + if (!_devs.size()) throw std::runtime_error("No devices specified via device arguments."); #ifdef WORKAROUND_GR_HIER_BLOCK2_BUG