aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--grc/gen_osmosdr_blocks.py50
-rw-r--r--include/osmosdr/osmosdr_source_c.h10
-rw-r--r--lib/osmosdr/osmosdr_src_c.cc61
-rw-r--r--lib/osmosdr/osmosdr_src_c.h2
-rw-r--r--lib/osmosdr_source_c_impl.cc22
-rw-r--r--lib/osmosdr_source_c_impl.h3
-rw-r--r--lib/osmosdr_src_iface.h10
-rw-r--r--lib/rtl/rtl_source_c.cc61
-rw-r--r--lib/rtl/rtl_source_c.h2
9 files changed, 143 insertions, 78 deletions
diff --git a/grc/gen_osmosdr_blocks.py b/grc/gen_osmosdr_blocks.py
index 8e9fbc2..d5631ca 100644
--- a/grc/gen_osmosdr_blocks.py
+++ b/grc/gen_osmosdr_blocks.py
@@ -26,7 +26,7 @@ MAIN_TMPL = """\
<category>Sources</category>
<throttle>1</throttle>
<import>import osmosdr</import>
- <make>osmosdr.$(sourk)_c( args="nchan=" + str(\$nchan) + " " + \$args )
+ <make>osmosdr.$(sourk)_c( args="nchan=" + str(\$nchan) + " " + \$args )
self.\$(id).set_sample_rate(\$sample_rate)
#for $n in range($max_nchan)
\#if \$nchan() > $n
@@ -34,18 +34,20 @@ self.\$(id).set_center_freq(\$freq$(n), $n)
self.\$(id).set_freq_corr(\$corr$(n), $n)
self.\$(id).set_gain_mode(\$gain_mode$(n), $n)
self.\$(id).set_gain(\$gain$(n), $n)
+self.\$(id).set_if_gain(\$if_gain$(n), $n)
\#if \$ant$(n)()
self.\$(id).set_antenna(\$ant$(n), $n)
\#end if
\#end if
#end for
-</make>
+ </make>
<callback>set_sample_rate(\$sample_rate)</callback>
#for $n in range($max_nchan)
<callback>set_center_freq(\$freq$(n), $n)</callback>
<callback>set_freq_corr(\$corr$(n), $n)</callback>
<callback>set_gain_mode(\$gain_mode$(n), $n)</callback>
<callback>set_gain(\$gain$(n), $n)</callback>
+ <callback>set_if_gain(\$if_gain$(n), $n)</callback>
<callback>set_antenna(\$ant$(n), $n)</callback>
#end for
<param>
@@ -100,18 +102,15 @@ self.\$(id).set_antenna(\$ant$(n), $n)
<doc>
The OsmoSDR $sourk.title() block:
-While primarily being developed for the OsmoSDR hardware, this block also
-supports the FunCube Dongle, Ettus UHD, rtl-sdr radios and cfile source.
-By using the OsmoSDR block you can take advantage of a common software api in
-your application(s) independent of the underlying radio hardware.
+While primarily being developed for the OsmoSDR hardware, this block also supports the FunCube Dongle, Ettus UHD, rtl-sdr radios and cfile source.
+By using the OsmoSDR 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.
Device Arguments:
The device argument is a delimited string used to locate devices on your system.
-Use the device id or name (if applicable) to specify a certain device or list
-of devices. If left blank, the first device found will be used.
+Use the device id or name (if applicable) to specify a certain device or list of devices. If left blank, the first device found will be used.
Examples (some arguments may be optional):
fcd=0
@@ -133,14 +132,18 @@ The center frequency is the overall frequency of the RF chain.
Freq. Corr.:
The frequency correction factor in parts per million (ppm). Leave 0 if unknown.
-Gain:
-Overall gain of the device's signal path. For the new gain value to be applied,
-the manual gain mode must be enabled first.
-
Gain Mode:
Chooses between the manual (default) and automatic gain mode where appropriate.
Currently, only rtlsdr devices support automatic gain mode.
+Gain:
+Overall gain of the device's signal path. For the new gain value to be applied, the manual gain mode must be enabled first.
+
+IF Gain:
+Overall IF gain of the device's signal path. For the new gain value to be applied, the manual gain mode must be enabled first.
+This setting has only effect for rtl-sdr and OsmoSDR devices with E4000 tuners.
+Observations lead to an useful gain range from 15 to 30dB.
+
Antenna:
For devices with only one antenna, this may be left blank.
Otherwise, the user should specify one of the possible antenna choices.
@@ -157,7 +160,7 @@ PARAMS_TMPL = """
<param>
<name>Ch$(n): Frequency (Hz)</name>
<key>freq$(n)</key>
- <value>0</value>
+ <value>100e6</value>
<type>real</type>
<hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
</param>
@@ -169,13 +172,6 @@ PARAMS_TMPL = """
<hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
</param>
<param>
- <name>Ch$(n): Gain (dB)</name>
- <key>gain$(n)</key>
- <value>0</value>
- <type>real</type>
- <hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
- </param>
- <param>
<name>Ch$(n): Gain Mode</name>
<key>gain_mode$(n)</key>
<value>0</value>
@@ -191,6 +187,20 @@ PARAMS_TMPL = """
</option>
</param>
<param>
+ <name>Ch$(n): Gain (dB)</name>
+ <key>gain$(n)</key>
+ <value>10</value>
+ <type>real</type>
+ <hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
+ </param>
+ <param>
+ <name>Ch$(n): IF Gain (dB)</name>
+ <key>if_gain$(n)</key>
+ <value>20</value>
+ <type>real</type>
+ <hide>\#if \$nchan() > $n then 'none' else 'all'#</hide>
+ </param>
+ <param>
<name>Ch$(n): Antenna</name>
<key>ant$(n)</key>
<value></value>
diff --git a/include/osmosdr/osmosdr_source_c.h b/include/osmosdr/osmosdr_source_c.h
index 425902d..55a9a0f 100644
--- a/include/osmosdr/osmosdr_source_c.h
+++ b/include/osmosdr/osmosdr_source_c.h
@@ -198,6 +198,16 @@ public:
virtual double get_gain( const std::string & name, size_t chan = 0 ) = 0;
/*!
+ * Set the IF gain for the underlying radio hardware.
+ * This function will automatically distribute the desired gain value over
+ * available IF gain stages in an appropriate way and return the actual value.
+ * \param gain the gain in dB
+ * \param chan the channel index 0 to N-1
+ * \return the actual gain in dB
+ */
+ virtual double set_if_gain( double gain, size_t chan = 0 ) = 0;
+
+ /*!
* Get the available antennas of the underlying radio hardware.
* \param chan the channel index 0 to N-1
* \return a vector of strings containing the names of available antennas
diff --git a/lib/osmosdr/osmosdr_src_c.cc b/lib/osmosdr/osmosdr_src_c.cc
index bba0550..68c4a27 100644
--- a/lib/osmosdr/osmosdr_src_c.cc
+++ b/lib/osmosdr/osmosdr_src_c.cc
@@ -131,6 +131,8 @@ osmosdr_src_c::osmosdr_src_c (const std::string &args)
if (ret < 0)
throw std::runtime_error("Failed to reset usb buffers.");
+ set_if_gain( 24 ); /* preset to a reasonable default (non-GRC use case) */
+
_buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *));
for(unsigned int i = 0; i < _buf_num; ++i)
@@ -410,6 +412,34 @@ bool osmosdr_src_c::get_gain_mode( size_t chan )
double osmosdr_src_c::set_gain( double gain, size_t chan )
{
osmosdr::gain_range_t rf_gains = osmosdr_src_c::get_gain_range( chan );
+
+ if (_dev) {
+ osmosdr_set_tuner_gain( _dev, int(rf_gains.clip(gain) * 10.0) );
+ }
+
+ return get_gain( chan );
+}
+
+double osmosdr_src_c::set_gain( double gain, const std::string & name, size_t chan)
+{
+ return set_gain( gain, chan );
+}
+
+double osmosdr_src_c::get_gain( size_t chan )
+{
+ if ( _dev )
+ return ((double)osmosdr_get_tuner_gain( _dev )) / 10.0;
+
+ return 0;
+}
+
+double osmosdr_src_c::get_gain( const std::string & name, size_t chan )
+{
+ return get_gain( chan );
+}
+
+double osmosdr_src_c::set_if_gain(double gain, size_t chan)
+{
std::vector< osmosdr::gain_range_t > if_gains;
if_gains += osmosdr::gain_range_t(-3, 6, 9);
@@ -419,9 +449,6 @@ double osmosdr_src_c::set_gain( double gain, size_t chan )
if_gains += osmosdr::gain_range_t(3, 15, 3);
if_gains += osmosdr::gain_range_t(3, 15, 3);
- double rf_gain = rf_gains.clip(gain);
- double missing_gain = gain - rf_gain;
-
std::map< int, double > gains;
/* initialize with min gains */
@@ -432,7 +459,7 @@ double osmosdr_src_c::set_gain( double gain, size_t chan )
for (int i = if_gains.size() - 1; i >= 0; i--) {
osmosdr::gain_range_t range = if_gains[ i ];
- double error = missing_gain;
+ double error = gain;
for( double g = range.start(); g <= range.stop(); g += range.step() ) {
@@ -444,7 +471,7 @@ double osmosdr_src_c::set_gain( double gain, size_t chan )
sum += gains[ j + 1 ];
}
- double err = abs(missing_gain - sum);
+ double err = abs(gain - sum);
if (err < error) {
error = err;
gains[ i + 1 ] = g;
@@ -452,7 +479,7 @@ double osmosdr_src_c::set_gain( double gain, size_t chan )
}
}
#if 0
- std::cerr << missing_gain << " => "; double sum = 0;
+ std::cerr << gain << " => "; double sum = 0;
for (unsigned int i = 0; i < gains.size(); i++) {
sum += gains[ i + 1 ];
std::cerr << gains[ i + 1 ] << " ";
@@ -460,32 +487,12 @@ double osmosdr_src_c::set_gain( double gain, size_t chan )
std::cerr << " = " << sum << std::endl;
#endif
if (_dev) {
- osmosdr_set_tuner_gain( _dev, int(rf_gain * 10.0) );
-
for (unsigned int stage = 1; stage <= gains.size(); stage++) {
osmosdr_set_tuner_if_gain( _dev, stage, int(gains[ stage ] * 10.0));
}
}
- return get_gain( chan );
-}
-
-double osmosdr_src_c::set_gain( double gain, const std::string & name, size_t chan)
-{
- return set_gain( gain, chan );
-}
-
-double osmosdr_src_c::get_gain( size_t chan )
-{
- if ( _dev )
- return ((double)osmosdr_get_tuner_gain( _dev )) / 10.0;
-
- return 0;
-}
-
-double osmosdr_src_c::get_gain( const std::string & name, size_t chan )
-{
- return get_gain( chan );
+ return gain;
}
std::vector< std::string > osmosdr_src_c::get_antennas( size_t chan )
diff --git a/lib/osmosdr/osmosdr_src_c.h b/lib/osmosdr/osmosdr_src_c.h
index 227ccae..9156454 100644
--- a/lib/osmosdr/osmosdr_src_c.h
+++ b/lib/osmosdr/osmosdr_src_c.h
@@ -105,6 +105,8 @@ private:
double get_gain( size_t chan = 0 );
double get_gain( const std::string & name, size_t chan = 0 );
+ double set_if_gain( double gain, size_t chan = 0 );
+
std::vector< std::string > get_antennas( size_t chan = 0 );
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
std::string get_antenna( size_t chan = 0 );
diff --git a/lib/osmosdr_source_c_impl.cc b/lib/osmosdr_source_c_impl.cc
index 4c5c3f9..5eec5c8 100644
--- a/lib/osmosdr_source_c_impl.cc
+++ b/lib/osmosdr_source_c_impl.cc
@@ -227,7 +227,7 @@ double osmosdr_source_c_impl::set_sample_rate(double rate)
if (_sample_rate != rate) {
BOOST_FOREACH( osmosdr_src_iface *dev, _devs )
- sample_rate = dev->set_sample_rate(rate);
+ sample_rate = dev->set_sample_rate(rate);
_sample_rate = sample_rate;
}
@@ -382,7 +382,7 @@ double osmosdr_source_c_impl::set_gain( double gain, const std::string & name, s
BOOST_FOREACH( osmosdr_src_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
- return dev->set_gain( gain, name, dev_chan );
+ return dev->set_gain( gain, name, dev_chan );
return 0;
}
@@ -409,6 +409,20 @@ double osmosdr_source_c_impl::get_gain( const std::string & name, size_t chan )
return 0;
}
+double osmosdr_source_c_impl::set_if_gain(double gain, size_t chan)
+{
+ size_t channel = 0;
+ BOOST_FOREACH( osmosdr_src_iface *dev, _devs )
+ for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
+ if ( chan == channel++ )
+ if ( _if_gain[ chan ] != gain ) {
+ _if_gain[ chan ] = gain;
+ return dev->set_if_gain( gain, dev_chan );
+ }
+
+ return 0;
+}
+
std::vector< std::string > osmosdr_source_c_impl::get_antennas( size_t chan )
{
size_t channel = 0;
@@ -427,8 +441,8 @@ std::string osmosdr_source_c_impl::set_antenna( const std::string & antenna, siz
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
if ( _antenna[ chan ] != antenna ) {
- _antenna[ chan ] = antenna;
- return dev->set_antenna( antenna, dev_chan );
+ _antenna[ chan ] = antenna;
+ return dev->set_antenna( antenna, dev_chan );
}
return "";
diff --git a/lib/osmosdr_source_c_impl.h b/lib/osmosdr_source_c_impl.h
index 1bdf6b3..a34bf3b 100644
--- a/lib/osmosdr_source_c_impl.h
+++ b/lib/osmosdr_source_c_impl.h
@@ -51,6 +51,8 @@ public:
double get_gain( size_t chan = 0 );
double get_gain( const std::string & name, size_t chan = 0 );
+ double set_if_gain( double gain, size_t chan = 0 );
+
std::vector< std::string > get_antennas( size_t chan = 0 );
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
std::string get_antenna( size_t chan = 0 );
@@ -67,6 +69,7 @@ private:
std::map< size_t, double > _freq_corr;
std::map< size_t, bool > _gain_mode;
std::map< size_t, double > _gain;
+ std::map< size_t, double > _if_gain;
std::map< size_t, std::string > _antenna;
std::vector< osmosdr_src_iface * > _devs;
};
diff --git a/lib/osmosdr_src_iface.h b/lib/osmosdr_src_iface.h
index b9ab9f8..a169e0d 100644
--- a/lib/osmosdr_src_iface.h
+++ b/lib/osmosdr_src_iface.h
@@ -176,6 +176,16 @@ public:
virtual double get_gain( const std::string & name, size_t chan = 0 ) = 0;
/*!
+ * Set the IF gain for the underlying radio hardware.
+ * This function will automatically distribute the desired gain value over
+ * available IF gain stages in an appropriate way and return the actual value.
+ * \param gain the gain in dB
+ * \param chan the channel index 0 to N-1
+ * \return the actual gain in dB
+ */
+ virtual double set_if_gain( double gain, size_t chan = 0 ) { return 0; }
+
+ /*!
* Get the available antennas of the underlying radio hardware.
* \param chan the channel index 0 to N-1
* \return a vector of strings containing the names of available antennas
diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc
index 3a16bff..18db321 100644
--- a/lib/rtl/rtl_source_c.cc
+++ b/lib/rtl/rtl_source_c.cc
@@ -158,6 +158,8 @@ rtl_source_c::rtl_source_c (const std::string &args)
if (ret < 0)
throw std::runtime_error("Failed to reset usb buffers.");
+ set_if_gain( 24 ); /* preset to a reasonable default (non-GRC use case) */
+
_buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *));
for(unsigned int i = 0; i < _buf_num; ++i)
@@ -441,6 +443,34 @@ bool rtl_source_c::get_gain_mode( size_t chan )
double rtl_source_c::set_gain( double gain, size_t chan )
{
osmosdr::gain_range_t rf_gains = rtl_source_c::get_gain_range( chan );
+
+ if (_dev) {
+ rtlsdr_set_tuner_gain( _dev, int(rf_gains.clip(gain) * 10.0) );
+ }
+
+ return get_gain( chan );
+}
+
+double rtl_source_c::set_gain( double gain, const std::string & name, size_t chan)
+{
+ return set_gain( gain, chan );
+}
+
+double rtl_source_c::get_gain( size_t chan )
+{
+ if ( _dev )
+ return ((double)rtlsdr_get_tuner_gain( _dev )) / 10.0;
+
+ return 0;
+}
+
+double rtl_source_c::get_gain( const std::string & name, size_t chan )
+{
+ return get_gain( chan );
+}
+
+double rtl_source_c::set_if_gain(double gain, size_t chan)
+{
std::vector< osmosdr::gain_range_t > if_gains;
if_gains += osmosdr::gain_range_t(-3, 6, 9);
@@ -450,9 +480,6 @@ double rtl_source_c::set_gain( double gain, size_t chan )
if_gains += osmosdr::gain_range_t(3, 15, 3);
if_gains += osmosdr::gain_range_t(3, 15, 3);
- double rf_gain = rf_gains.clip(gain);
- double missing_gain = gain - rf_gain;
-
std::map< int, double > gains;
/* initialize with min gains */
@@ -463,7 +490,7 @@ double rtl_source_c::set_gain( double gain, size_t chan )
for (int i = if_gains.size() - 1; i >= 0; i--) {
osmosdr::gain_range_t range = if_gains[ i ];
- double error = missing_gain;
+ double error = gain;
for( double g = range.start(); g <= range.stop(); g += range.step() ) {
@@ -475,7 +502,7 @@ double rtl_source_c::set_gain( double gain, size_t chan )
sum += gains[ j + 1 ];
}
- double err = abs(missing_gain - sum);
+ double err = abs(gain - sum);
if (err < error) {
error = err;
gains[ i + 1 ] = g;
@@ -483,7 +510,7 @@ double rtl_source_c::set_gain( double gain, size_t chan )
}
}
#if 0
- std::cerr << missing_gain << " => "; double sum = 0;
+ std::cerr << gain << " => "; double sum = 0;
for (unsigned int i = 0; i < gains.size(); i++) {
sum += gains[ i + 1 ];
std::cerr << gains[ i + 1 ] << " ";
@@ -491,32 +518,12 @@ double rtl_source_c::set_gain( double gain, size_t chan )
std::cerr << " = " << sum << std::endl;
#endif
if (_dev) {
- rtlsdr_set_tuner_gain( _dev, int(rf_gain * 10.0) );
-
for (unsigned int stage = 1; stage <= gains.size(); stage++) {
rtlsdr_set_tuner_if_gain( _dev, stage, int(gains[ stage ] * 10.0));
}
}
- return get_gain( chan );
-}
-
-double rtl_source_c::set_gain( double gain, const std::string & name, size_t chan)
-{
- return set_gain( gain, chan );
-}
-
-double rtl_source_c::get_gain( size_t chan )
-{
- if ( _dev )
- return ((double)rtlsdr_get_tuner_gain( _dev )) / 10.0;
-
- return 0;
-}
-
-double rtl_source_c::get_gain( const std::string & name, size_t chan )
-{
- return get_gain( chan );
+ return gain;
}
std::vector< std::string > rtl_source_c::get_antennas( size_t chan )
diff --git a/lib/rtl/rtl_source_c.h b/lib/rtl/rtl_source_c.h
index 70dcf0e..5f4ccdd 100644
--- a/lib/rtl/rtl_source_c.h
+++ b/lib/rtl/rtl_source_c.h
@@ -106,6 +106,8 @@ public:
double get_gain( size_t chan = 0 );
double get_gain( const std::string & name, size_t chan = 0 );
+ double set_if_gain( double gain, size_t chan = 0 );
+
std::vector< std::string > get_antennas( size_t chan = 0 );
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
std::string get_antenna( size_t chan = 0 );