From 3a47e3661c616de677a813adb31e0d325f8ae0f1 Mon Sep 17 00:00:00 2001 From: Dimitri Stolnikov Date: Sat, 5 May 2012 00:43:32 +0200 Subject: [PATCH] add api for manual gain mode control --- apps/osmosdr_source.grc | 136 +++++++++++++++++------------ grc/gen_osmosdr_blocks.py | 23 ++++- include/osmosdr/osmosdr_source_c.h | 16 ++++ lib/fcd/fcd_source.cc | 10 +++ lib/fcd/fcd_source.h | 2 + lib/file/file_source_c.cc | 10 +++ lib/file/file_source_c.h | 2 + lib/osmosdr_source_c_impl.cc | 22 +++++ lib/osmosdr_source_c_impl.h | 2 + lib/osmosdr_src_iface.h | 16 ++++ lib/rtl/rtl_source_c.cc | 46 +++++++++- lib/rtl/rtl_source_c.h | 4 + lib/uhd/uhd_source_c.cc | 10 +++ lib/uhd/uhd_source_c.h | 2 + 14 files changed, 239 insertions(+), 62 deletions(-) diff --git a/apps/osmosdr_source.grc b/apps/osmosdr_source.grc index 939a7e4..5936672 100644 --- a/apps/osmosdr_source.grc +++ b/apps/osmosdr_source.grc @@ -1,6 +1,6 @@ - Sat Apr 28 19:58:05 2012 + Sat May 5 00:40:44 2012 options @@ -43,6 +43,10 @@ run True + + max_nouts + 0 + realtime_scheduling @@ -56,61 +60,6 @@ 0 - - variable_slider - - id - gain - - - _enabled - True - - - label - - - - value - 10 - - - min - 0 - - - max - 30 - - - num_steps - 31 - - - style - wx.SL_HORIZONTAL - - - converver - float_converter - - - grid_pos - - - - notebook - - - - _coordinate - (472, 65) - - - _rotation - 0 - - variable @@ -410,6 +359,57 @@ 0 + + variable_chooser + + id + gain_chooser + + + _enabled + True + + + label + + + + value + 9.0 + + + choices + [-1.0, 1.5, 4.0, 6.5, 9.0, 11.5, 14.0, 16.5, 19.0, 21.5, 24.0, 29.0, 34.0, 42.0, 43.0, 45.0, 47.0, 49.0] + + + labels + [] + + + type + drop_down + + + style + wx.RA_HORIZONTAL + + + grid_pos + + + + notebook + + + + _coordinate + (461, 63) + + + _rotation + 0 + + osmosdr_source_c @@ -446,7 +446,11 @@ gain0 - gain + gain_chooser + + + gain_mode0 + 1 ant0 @@ -462,7 +466,11 @@ gain1 - gain + gain_chooser + + + gain_mode1 + 0 ant1 @@ -480,6 +488,10 @@ gain2 0 + + gain_mode2 + 0 + ant2 @@ -496,6 +508,10 @@ gain3 0 + + gain_mode3 + 0 + ant3 @@ -512,6 +528,10 @@ gain4 0 + + gain_mode4 + 0 + ant4 diff --git a/grc/gen_osmosdr_blocks.py b/grc/gen_osmosdr_blocks.py index 23211e0..b1d8294 100644 --- a/grc/gen_osmosdr_blocks.py +++ b/grc/gen_osmosdr_blocks.py @@ -32,6 +32,7 @@ self.\$(id).set_sample_rate(\$sample_rate) self.\$(id).set_center_freq(\$freq$(n), $n) self.\$(id).set_freq_corr(\$corr$(n), $n) self.\$(id).set_gain(\$gain$(n), $n) +self.\$(id).set_gain_mode(\$gain_mode$(n), $n) \#if \$ant$(n)() self.\$(id).set_antenna(\$ant$(n), $n) \#end if @@ -43,6 +44,7 @@ self.\$(id).set_antenna(\$ant$(n), $n) set_center_freq(\$freq$(n), $n) set_freq_corr(\$corr$(n), $n) set_gain(\$gain$(n), $n) + set_gain_mode(\$gain_mode$(n), $n) set_antenna(\$ant$(n), $n) #end for @@ -125,7 +127,11 @@ Freq. Corr.: The frequency correction factor in parts per million (ppm). Leave 0 if unknown. Gain: -Overall gain of the device's signal path. +Overall gain of the device's signal path. For the gain setting to apply the +manual gain mode must be enabled first for some devices (namely rtlsdr). + +Gain Mode: +Chooses between the automatic (default) and manual gain mode where appropriate. Antenna: For devices with only one antenna, this may be left blank. @@ -159,6 +165,21 @@ PARAMS_TMPL = """ real \#if \$nchan() > $n then 'none' else 'all'# + + Ch$(n): Gain Mode + gain_mode$(n) + + enum + \#if \$nchan() > $n then 'none' else 'all'# + + + Ch$(n): Antenna ant$(n) diff --git a/include/osmosdr/osmosdr_source_c.h b/include/osmosdr/osmosdr_source_c.h index f5d603a..fae0f05 100644 --- a/include/osmosdr/osmosdr_source_c.h +++ b/include/osmosdr/osmosdr_source_c.h @@ -145,6 +145,22 @@ public: virtual osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 ) = 0; + /*! + * Set the gain mode for the underlying radio hardware. + * This might be supported only for certain hardware types. + * \param mode the gain mode (true means manual gain mode) + * \param chan the channel index 0 to N-1 + * \return the actual gain mode + */ + virtual bool set_gain_mode( bool mode, size_t chan = 0 ) = 0; + + /*! + * Get the gain mode selected for the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return the actual gain mode + */ + virtual bool get_gain_mode( size_t chan = 0 ) = 0; + /*! * Set the gain for the underlying radio hardware. * This function will automatically distribute the desired gain value over diff --git a/lib/fcd/fcd_source.cc b/lib/fcd/fcd_source.cc index 96f9993..8ed7103 100644 --- a/lib/fcd/fcd_source.cc +++ b/lib/fcd/fcd_source.cc @@ -186,6 +186,16 @@ osmosdr::gain_range_t fcd_source::get_gain_range( const std::string & name, size return get_gain_range( chan ); } +bool fcd_source::set_gain_mode( bool mode, size_t chan ) +{ + return get_gain_mode(chan); +} + +bool fcd_source::get_gain_mode( size_t chan ) +{ + return true; +} + double fcd_source::set_gain( double gain, size_t chan ) { _src->set_lna_gain(gain); diff --git a/lib/fcd/fcd_source.h b/lib/fcd/fcd_source.h index 6fa00a3..5d23a26 100644 --- a/lib/fcd/fcd_source.h +++ b/lib/fcd/fcd_source.h @@ -65,6 +65,8 @@ public: std::vector get_gain_names( size_t chan = 0 ); osmosdr::gain_range_t get_gain_range( size_t chan = 0 ); osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 ); + bool set_gain_mode( bool mode, size_t chan = 0 ); + bool get_gain_mode( size_t chan = 0 ); double set_gain( double gain, size_t chan = 0 ); double set_gain( double gain, const std::string & name, size_t chan = 0 ); double get_gain( size_t chan = 0 ); diff --git a/lib/file/file_source_c.cc b/lib/file/file_source_c.cc index a706442..87de181 100644 --- a/lib/file/file_source_c.cc +++ b/lib/file/file_source_c.cc @@ -172,6 +172,16 @@ osmosdr::gain_range_t file_source_c::get_gain_range( const std::string & name, s return get_gain_range( chan ); } +bool file_source_c::set_gain_mode( bool mode, size_t chan ) +{ + return get_gain_mode(chan); +} + +bool file_source_c::get_gain_mode( size_t chan ) +{ + return true; +} + double file_source_c::set_gain( double gain, size_t chan ) { return get_gain(chan); diff --git a/lib/file/file_source_c.h b/lib/file/file_source_c.h index 83ad24e..78cc985 100644 --- a/lib/file/file_source_c.h +++ b/lib/file/file_source_c.h @@ -61,6 +61,8 @@ public: std::vector get_gain_names( size_t chan = 0 ); osmosdr::gain_range_t get_gain_range( size_t chan = 0 ); osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 ); + bool set_gain_mode( bool mode, size_t chan = 0 ); + bool get_gain_mode( size_t chan = 0 ); double set_gain( double gain, size_t chan = 0 ); double set_gain( double gain, const std::string & name, size_t chan = 0 ); double get_gain( size_t chan = 0 ); diff --git a/lib/osmosdr_source_c_impl.cc b/lib/osmosdr_source_c_impl.cc index 64d53e3..f9ed41d 100644 --- a/lib/osmosdr_source_c_impl.cc +++ b/lib/osmosdr_source_c_impl.cc @@ -249,6 +249,28 @@ osmosdr::gain_range_t osmosdr_source_c_impl::get_gain_range( const std::string & return osmosdr::gain_range_t(); } +bool osmosdr_source_c_impl::set_gain_mode( bool mode, size_t 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_mode( mode, chan ); + + return false; +} + +bool osmosdr_source_c_impl::get_gain_mode( size_t 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_mode( chan ); + + return false; +} + double osmosdr_source_c_impl::set_gain( double gain, size_t chan ) { size_t channel = 0; diff --git a/lib/osmosdr_source_c_impl.h b/lib/osmosdr_source_c_impl.h index 1cc1fe1..6f3042b 100644 --- a/lib/osmosdr_source_c_impl.h +++ b/lib/osmosdr_source_c_impl.h @@ -43,6 +43,8 @@ public: std::vector get_gain_names( size_t chan = 0 ); osmosdr::gain_range_t get_gain_range( size_t chan = 0 ); osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 ); + bool set_gain_mode( bool mode, size_t chan = 0 ); + bool get_gain_mode( size_t chan = 0 ); double set_gain( double gain, size_t chan = 0 ); double set_gain( double gain, const std::string & name, size_t chan = 0 ); double get_gain( size_t chan = 0 ); diff --git a/lib/osmosdr_src_iface.h b/lib/osmosdr_src_iface.h index 649b0ab..2a6ae40 100644 --- a/lib/osmosdr_src_iface.h +++ b/lib/osmosdr_src_iface.h @@ -123,6 +123,22 @@ public: virtual osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 ) = 0; + /*! + * Set the gain mode for the underlying radio hardware. + * This might be supported only for certain hardware types. + * \param mode the gain mode (true means manual gain mode) + * \param chan the channel index 0 to N-1 + * \return the actual gain mode + */ + virtual bool set_gain_mode( bool mode, size_t chan = 0 ) = 0; + + /*! + * Get the gain mode selected for the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return the actual gain mode + */ + virtual bool get_gain_mode( size_t chan = 0 ) = 0; + /*! * Set the gain for the underlying radio hardware. * This function will automatically distribute the desired gain value over diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc index 4a63824..c2e3b88 100644 --- a/lib/rtl/rtl_source_c.cc +++ b/lib/rtl/rtl_source_c.cc @@ -145,6 +145,8 @@ rtl_source_c::rtl_source_c (const std::string &args) _running = true; + _manual_gain = false; + _thread = gruel::thread(_rtlsdr_wait, this); } @@ -278,7 +280,12 @@ osmosdr::meta_range_t rtl_source_c::get_sample_rates() osmosdr::meta_range_t range; range += osmosdr::range_t( 1024000 ); // known to work + range += osmosdr::range_t( 1800000 ); // known to work range += osmosdr::range_t( 2048000 ); // known to work + range += osmosdr::range_t( 2400000 ); // may work + range += osmosdr::range_t( 2600000 ); // may work + range += osmosdr::range_t( 2800000 ); // may work + range += osmosdr::range_t( 3000000 ); // may work range += osmosdr::range_t( 3200000 ); // max rate, may work // TODO: read from the librtlsdr as soon as the api is available @@ -359,7 +366,24 @@ osmosdr::gain_range_t rtl_source_c::get_gain_range( size_t chan ) { osmosdr::gain_range_t range; - range += osmosdr::range_t( -5, 30, 2.5 ); + range += osmosdr::range_t( -1.0 ); + range += osmosdr::range_t( 1.5 ); + range += osmosdr::range_t( 4.0 ); + range += osmosdr::range_t( 6.5 ); + range += osmosdr::range_t( 9.0 ); + range += osmosdr::range_t( 11.5 ); + range += osmosdr::range_t( 14.0 ); + range += osmosdr::range_t( 16.5 ); + range += osmosdr::range_t( 19.0 ); + range += osmosdr::range_t( 21.5 ); + range += osmosdr::range_t( 24.0 ); + range += osmosdr::range_t( 29.0 ); + range += osmosdr::range_t( 34.0 ); + range += osmosdr::range_t( 42.0 ); + range += osmosdr::range_t( 43.0 ); + range += osmosdr::range_t( 45.0 ); + range += osmosdr::range_t( 47.0 ); + range += osmosdr::range_t( 49.0 ); // TODO: read from the librtlsdr as soon as the api is available @@ -371,10 +395,26 @@ osmosdr::gain_range_t rtl_source_c::get_gain_range( const std::string & name, si return get_gain_range( chan ); } +bool rtl_source_c::set_gain_mode( bool mode, size_t chan ) +{ + if (_dev) { + if (!rtlsdr_set_tuner_gain_mode(_dev, int(mode))) { + _manual_gain = mode; + } + } + + return get_gain_mode(chan); +} + +bool rtl_source_c::get_gain_mode( size_t chan ) +{ + return _manual_gain; +} + double rtl_source_c::set_gain( double gain, size_t chan ) { if (_dev) - rtlsdr_set_tuner_gain( _dev, gain ); + rtlsdr_set_tuner_gain( _dev, int(gain * 10.0) ); return get_gain( chan ); } @@ -387,7 +427,7 @@ double rtl_source_c::set_gain( double gain, const std::string & name, size_t cha double rtl_source_c::get_gain( size_t chan ) { if ( _dev ) - return (double)rtlsdr_get_tuner_gain( _dev ); + return ((double)rtlsdr_get_tuner_gain( _dev )) / 10.0; return 0; } diff --git a/lib/rtl/rtl_source_c.h b/lib/rtl/rtl_source_c.h index 944d153..a957f9d 100644 --- a/lib/rtl/rtl_source_c.h +++ b/lib/rtl/rtl_source_c.h @@ -98,6 +98,8 @@ public: std::vector get_gain_names( size_t chan = 0 ); osmosdr::gain_range_t get_gain_range( size_t chan = 0 ); osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 ); + bool set_gain_mode( bool mode, size_t chan = 0 ); + bool get_gain_mode( size_t chan = 0 ); double set_gain( double gain, size_t chan = 0 ); double set_gain( double gain, const std::string & name, size_t chan = 0 ); double get_gain( size_t chan = 0 ); @@ -127,6 +129,8 @@ private: unsigned int _buf_offset; unsigned int _samp_avail; + + bool _manual_gain; }; #endif /* INCLUDED_RTLSDR_SOURCE_C_H */ diff --git a/lib/uhd/uhd_source_c.cc b/lib/uhd/uhd_source_c.cc index 3baeed6..5c60f21 100644 --- a/lib/uhd/uhd_source_c.cc +++ b/lib/uhd/uhd_source_c.cc @@ -175,6 +175,16 @@ osmosdr::gain_range_t uhd_source_c::get_gain_range( const std::string & name, si return range; } +bool uhd_source_c::set_gain_mode( bool mode, size_t chan ) +{ + return get_gain_mode(chan); +} + +bool uhd_source_c::get_gain_mode( size_t chan ) +{ + return true; +} + double uhd_source_c::set_gain( double gain, size_t chan ) { _src->set_gain(gain, chan); diff --git a/lib/uhd/uhd_source_c.h b/lib/uhd/uhd_source_c.h index 84e7f66..18529ce 100644 --- a/lib/uhd/uhd_source_c.h +++ b/lib/uhd/uhd_source_c.h @@ -65,6 +65,8 @@ public: std::vector get_gain_names( size_t chan = 0 ); osmosdr::gain_range_t get_gain_range( size_t chan = 0 ); osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 ); + bool set_gain_mode( bool mode, size_t chan = 0 ); + bool get_gain_mode( size_t chan = 0 ); double set_gain( double gain, size_t chan = 0 ); double set_gain( double gain, const std::string & name, size_t chan = 0 ); double get_gain( size_t chan = 0 );