rtl_tcp: implement sample rate and gain control

This commit is contained in:
Dimitri Stolnikov 2012-05-06 19:42:27 +02:00
parent f94d8da48e
commit e38dc2f427
6 changed files with 96 additions and 29 deletions

View File

@ -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 ...

View File

@ -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;

View File

@ -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<std::string> 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);
}

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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);
};