From e38dc2f42738ab3068bb03b7c44cb203e135675f Mon Sep 17 00:00:00 2001 From: Dimitri Stolnikov Date: Sun, 6 May 2012 19:42:27 +0200 Subject: [PATCH] rtl_tcp: implement sample rate and gain control --- grc/gen_osmosdr_blocks.py | 2 +- lib/rtl/rtl_source_c.cc | 2 +- lib/rtl_tcp/rtl_tcp_source_c.cc | 79 ++++++++++++++++++++++++++++----- lib/rtl_tcp/rtl_tcp_source_c.h | 3 +- lib/rtl_tcp/rtl_tcp_source_f.cc | 32 ++++++++----- lib/rtl_tcp/rtl_tcp_source_f.h | 7 +-- 6 files changed, 96 insertions(+), 29 deletions(-) diff --git a/grc/gen_osmosdr_blocks.py b/grc/gen_osmosdr_blocks.py index 595fd17..1af1009 100644 --- a/grc/gen_osmosdr_blocks.py +++ b/grc/gen_osmosdr_blocks.py @@ -115,7 +115,7 @@ of devices. If left blank, the first device found will be used. Examples (some arguments may be optional): fcd=0 rtl=0,rtl_xtal=28.80001e6,tuner_xtal=26e6,buffers=64 ... - rtl_tcp=host=127.0.0.1,port=1234,eof=false,wait=true,psize=16384 + rtl_tcp=host=127.0.0.1,port=1234,psize=16384 uhd=0|name,mcr=52e6,nchan=2,subdev='\\\\'B:0 A:0'\\\\' ... osmosdr=0|name,mcr=64e6,nchan=5,port=/dev/ttyUSB0 ... file=/path/to/file.ext,freq=428e6,rate=1e6,repeat=true,throttle=true ... diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc index 732f8e7..7150590 100644 --- a/lib/rtl/rtl_source_c.cc +++ b/lib/rtl/rtl_source_c.cc @@ -435,7 +435,7 @@ bool rtl_source_c::get_gain_mode( size_t chan ) return _auto_gain; } -double pick_closest_gain(osmosdr::gain_range_t &gains, double required) +static double pick_closest_gain(osmosdr::gain_range_t &gains, double required) { double result = required; double distance = 100; diff --git a/lib/rtl_tcp/rtl_tcp_source_c.cc b/lib/rtl_tcp/rtl_tcp_source_c.cc index de3c730..c1f2869 100644 --- a/lib/rtl_tcp/rtl_tcp_source_c.cc +++ b/lib/rtl_tcp/rtl_tcp_source_c.cc @@ -46,12 +46,12 @@ rtl_tcp_source_c::rtl_tcp_source_c(const std::string &args) : { std::string host = "127.0.0.1"; unsigned short port = 1234; - bool eof = false; - bool wait = true; int payload_size = 16384; _freq = 0; _rate = 0; + _gain = 0; + _auto_gain = false; dict_t dict = params_to_dict(args); @@ -61,12 +61,6 @@ rtl_tcp_source_c::rtl_tcp_source_c(const std::string &args) : if (dict.count("port")) port = boost::lexical_cast< unsigned short >( dict["port"] ); - if (dict.count("eof")) - eof = "true" == dict["eof"] ? true : false; - - if (dict.count("wait")) - wait = "true" == dict["wait"] ? true : false; - if (dict.count("psize")) payload_size = boost::lexical_cast< int >( dict["psize"] ); @@ -80,7 +74,9 @@ rtl_tcp_source_c::rtl_tcp_source_c(const std::string &args) : payload_size = 16384; _src = make_rtl_tcp_source_f(sizeof(float), host.c_str(), port, payload_size, - eof, wait); + false, false); + + set_gain_mode(false); // enable manual gain mode by default /* rtl tcp source provides a stream of interleaved IQ floats */ gr_deinterleave_sptr deinterleave = gr_make_deinterleave(sizeof(float)); @@ -117,13 +113,24 @@ osmosdr::meta_range_t rtl_tcp_source_c::get_sample_rates( void ) { osmosdr::meta_range_t range; - range += osmosdr::range_t( get_sample_rate() ); + 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 return range; } double rtl_tcp_source_c::set_sample_rate( double rate ) { + _src->set_sample_rate( int(rate) ); + + _rate = rate; + return get_sample_rate(); } @@ -170,7 +177,26 @@ std::vector rtl_tcp_source_c::get_gain_names( size_t chan ) osmosdr::gain_range_t rtl_tcp_source_c::get_gain_range( size_t chan ) { - osmosdr::gain_range_t range(0, 0); + osmosdr::gain_range_t range; + + 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 ); return range; } @@ -182,16 +208,45 @@ osmosdr::gain_range_t rtl_tcp_source_c::get_gain_range( const std::string & name bool rtl_tcp_source_c::set_gain_mode( bool mode, size_t chan ) { + _src->set_gain_mode(int(!mode)); + + _auto_gain = mode; + return get_gain_mode(chan); } bool rtl_tcp_source_c::get_gain_mode( size_t chan ) { - return true; + return _auto_gain; +} + +static double pick_closest_gain(osmosdr::gain_range_t &gains, double required) +{ + double result = required; + double distance = 100; + + BOOST_FOREACH(osmosdr::range_t gain, gains) + { + double diff = fabs(gain.start() - required); + + if (diff < distance) { + distance = diff; + result = gain.start(); + } + } + + return result; } double rtl_tcp_source_c::set_gain( double gain, size_t chan ) { + osmosdr::gain_range_t gains = rtl_tcp_source_c::get_gain_range( chan ); + double picked_gain = pick_closest_gain( gains, gain ); + + _src->set_gain( int(picked_gain * 10.0) ); + + _gain = gain; + return get_gain(chan); } diff --git a/lib/rtl_tcp/rtl_tcp_source_c.h b/lib/rtl_tcp/rtl_tcp_source_c.h index 7545534..f5431c7 100644 --- a/lib/rtl_tcp/rtl_tcp_source_c.h +++ b/lib/rtl_tcp/rtl_tcp_source_c.h @@ -75,7 +75,8 @@ public: std::string get_antenna( size_t chan = 0 ); private: - double _freq, _rate; + double _freq, _rate, _gain; + bool _auto_gain; rtl_tcp_source_f_sptr _src; }; diff --git a/lib/rtl_tcp/rtl_tcp_source_f.cc b/lib/rtl_tcp/rtl_tcp_source_f.cc index 7e283fb..4d962a9 100644 --- a/lib/rtl_tcp/rtl_tcp_source_f.cc +++ b/lib/rtl_tcp/rtl_tcp_source_f.cc @@ -82,9 +82,7 @@ rtl_tcp_source_f::rtl_tcp_source_f(size_t itemsize, d_eof(eof), d_wait(wait), d_socket(-1), - d_residual(0), - d_temp_offset(0), - curr_freq(0) + d_temp_offset(0) { int ret = 0; struct sockaddr_in cliaddr; @@ -248,12 +246,24 @@ struct command{ void rtl_tcp_source_f::set_freq(int freq) { - struct command cmd; - - if (freq != curr_freq) { - cmd.cmd = 0x01; - cmd.param = freq; - send(d_socket, (const char*)&cmd, sizeof(cmd), 0); - curr_freq = freq; - } + struct command cmd = { 0x01, freq }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); +} + +void rtl_tcp_source_f::set_sample_rate(int sample_rate) +{ + struct command cmd = { 0x02, sample_rate }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); +} + +void rtl_tcp_source_f::set_gain_mode(int manual) +{ + struct command cmd = { 0x03, manual }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); +} + +void rtl_tcp_source_f::set_gain(int gain) +{ + struct command cmd = { 0x04, gain }; + send(d_socket, (const char*)&cmd, sizeof(cmd), 0); } diff --git a/lib/rtl_tcp/rtl_tcp_source_f.h b/lib/rtl_tcp/rtl_tcp_source_f.h index 402d637..1c2d265 100644 --- a/lib/rtl_tcp/rtl_tcp_source_f.h +++ b/lib/rtl_tcp/rtl_tcp_source_f.h @@ -66,9 +66,7 @@ private: bool d_wait; // wait if data if not immediately available int d_socket; // handle to socket unsigned char *d_temp_buff; // hold buffer between calls - ssize_t d_residual; // hold information about number of bytes stored in the temp buffer - size_t d_temp_offset; // point to temp buffer location offset - int curr_freq; + size_t d_temp_offset; // point to temp buffer location offset float *d_LUT; private: @@ -93,6 +91,9 @@ private: gr_vector_void_star &output_items); void set_freq(int freq); + void set_sample_rate(int sample_rate); + void set_gain_mode(int manual); + void set_gain(int gain); };