rtl: automatically increase if gain when required

This commit is contained in:
Dimitri Stolnikov 2012-07-08 23:56:05 +02:00
parent 10f0d89348
commit f9acc7edf6
1 changed files with 56 additions and 3 deletions

View File

@ -440,10 +440,63 @@ 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 gains = rtl_source_c::get_gain_range( chan );
osmosdr::gain_range_t rf_gains = rtl_source_c::get_gain_range( chan );
std::vector< osmosdr::gain_range_t > if_gains;
if (_dev)
rtlsdr_set_tuner_gain( _dev, int(gains.clip(gain) * 10.0) );
if_gains += osmosdr::gain_range_t(-3, 6, 9);
if_gains += osmosdr::gain_range_t(0, 9, 3);
if_gains += osmosdr::gain_range_t(0, 9, 3);
if_gains += osmosdr::gain_range_t(0, 2, 1);
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 */
for (unsigned int i = 0; i < if_gains.size(); i++) {
gains[ i + 1 ] = if_gains[ i ].start();
}
for (int i = if_gains.size() - 1; i >= 0; i--) {
osmosdr::gain_range_t range = if_gains[ i ];
double error = missing_gain;
for( double g = range.start(); g <= range.stop(); g += range.step() ) {
double sum = 0;
for (int j = 0; j < int(gains.size()); j++) {
if ( i == j )
sum += g;
else
sum += gains[ j + 1 ];
}
double err = abs(missing_gain - sum);
if (err < error) {
error = err;
gains[ i + 1 ] = g;
}
}
}
#if 0
std::cerr << missing_gain << " => "; double sum = 0;
for (unsigned int i = 0; i < gains.size(); i++) {
sum += gains[ i + 1 ];
std::cerr << gains[ i + 1 ] << " ";
}
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 );
}