Compare commits

...

1 Commits

Author SHA1 Message Date
Dimitri Stolnikov d94645c17c wip: dynamic signatures 2014-05-07 14:59:18 +02:00
3 changed files with 114 additions and 24 deletions

View File

@ -26,7 +26,7 @@ MAIN_TMPL = """\
<category>$($sourk.title())s</category> <category>$($sourk.title())s</category>
<throttle>1</throttle> <throttle>1</throttle>
<import>import osmosdr</import> <import>import osmosdr</import>
<make>osmosdr.$(sourk)( args="numchan=" + str(\$nchan) + " " + \$args ) <make>osmosdr.$(sourk)( args=\$args )
self.\$(id).set_sample_rate(\$sample_rate) self.\$(id).set_sample_rate(\$sample_rate)
#for $n in range($max_nchan) #for $n in range($max_nchan)
\#if \$nchan() > $n \#if \$nchan() > $n
@ -69,6 +69,21 @@ self.\$(id).set_bandwidth(\$bw$(n), $n)
<key>fc32</key> <key>fc32</key>
<opt>type:fc32</opt> <opt>type:fc32</opt>
</option> </option>
<option>
<name>Complex int16</name>
<key>sc16</key>
<opt>type:sc16</opt>
</option>
<option>
<name>Complex int8</name>
<key>sc8</key>
<opt>type:sc8</opt>
</option>
<option>
<name>Octet stream</name>
<key>s8</key>
<opt>type:s8</opt>
</option>
</param> </param>
<param> <param>
<name>Device Arguments</name> <name>Device Arguments</name>
@ -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. 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: $(dir.title())put Type:
This parameter controls the data type of the stream in gnuradio. Only complex float32 samples are supported at the moment. 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: 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. 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. Selects the total number of channels in this multi-device configuration. Required when specifying multiple device arguments.
Sample Rate: 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: Frequency:
The center frequency is the frequency the RF chain is tuned to. The center frequency is the frequency the RF chain is tuned to.

View File

@ -64,7 +64,7 @@ osmosdr::sink::make( const std::string &args )
*/ */
sink_impl::sink_impl( const std::string &args ) sink_impl::sink_impl( const std::string &args )
: gr::hier_block2 ("sink_impl", : 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)), gr::io_signature::make(0, 0, 0)),
_sample_rate(NAN) _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."); throw std::runtime_error("No supported devices found to pick from.");
} }
int min_streams = 0, max_streams = 0;
std::vector<int> stream_items;
std::vector< gr::basic_block_sptr > blocks;
BOOST_FOREACH(std::string arg, arg_list) { BOOST_FOREACH(std::string arg, arg_list) {
dict_t dict = params_to_dict(arg); 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 ) { if ( iface != NULL && long(block.get()) != 0 ) {
_devs.push_back( iface ); _devs.push_back( iface );
blocks.push_back( block );
for (size_t i = 0; i < iface->get_num_channels(); i++) { min_streams += block->input_signature()->min_streams();
connect(self(), channel++, block, i); 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) ) } else if ( (iface != NULL) || (long(block.get()) != 0) )
throw std::runtime_error("Eitner iface or block are NULL."); 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()) if (!_devs.size())
throw std::runtime_error("No devices specified via device arguments."); throw std::runtime_error("No devices specified via device arguments.");
#ifdef WORKAROUND_GR_HIER_BLOCK2_BUG #ifdef WORKAROUND_GR_HIER_BLOCK2_BUG

View File

@ -99,7 +99,7 @@ osmosdr::source::make( const std::string &args )
source_impl::source_impl( const std::string &args ) source_impl::source_impl( const std::string &args )
: gr::hier_block2 ("source_impl", : gr::hier_block2 ("source_impl",
gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0),
args_to_io_signature(args)), gr::io_signature::make(1, 1, sizeof(gr_complex))),
_sample_rate(NAN) _sample_rate(NAN)
{ {
size_t channel = 0; 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."); throw std::runtime_error("No supported devices found to pick from.");
} }
int min_streams = 0, max_streams = 0;
std::vector<int> stream_items;
std::vector< gr::basic_block_sptr > blocks;
BOOST_FOREACH(std::string arg, arg_list) { BOOST_FOREACH(std::string arg, arg_list) {
dict_t dict = params_to_dict(arg); 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 ) { if ( iface != NULL && long(block.get()) != 0 ) {
_devs.push_back( iface ); _devs.push_back( iface );
blocks.push_back( block );
for (size_t i = 0; i < iface->get_num_channels(); i++) { min_streams += block->output_signature()->min_streams();
#ifdef HAVE_IQBALANCE max_streams += block->output_signature()->max_streams();
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();
connect(block, i, iq_fix, 0); BOOST_FOREACH(int size, block->output_signature()->sizeof_stream_items())
connect(iq_fix, 0, self(), channel++); {
stream_items.push_back( size );
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
} }
} else if ( (iface != NULL) || (long(block.get()) != 0) ) } else if ( (iface != NULL) || (long(block.get()) != 0) )
throw std::runtime_error("Eitner iface or block are NULL."); 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()) if (!_devs.size())
throw std::runtime_error("No devices specified via device arguments."); throw std::runtime_error("No devices specified via device arguments.");
#ifdef WORKAROUND_GR_HIER_BLOCK2_BUG #ifdef WORKAROUND_GR_HIER_BLOCK2_BUG