Set RTL AGC mode by default (no improvement), with command-line option to disable.
This commit is contained in:
parent
ff985cd623
commit
761b368282
|
@ -29,9 +29,7 @@ settings during a run. The LNA gain seems to switch between ~ 24 dB
|
|||
and ~ 34 dB without intermediate steps.
|
||||
|
||||
With RTL in AGC mode, the level of the digital sample stream is normalized
|
||||
to -6 dB FS.
|
||||
Unknown whether this is an analog or digital gain stage.
|
||||
Does this improve SNR or not?
|
||||
to -6 dB FS. Unknown whether this is an analog or digital gain stage.
|
||||
|
||||
At first I suspected that AGC mode may be a cooperation between the RTL and
|
||||
the Elonics tuner. I thought that the RTL would monitor the level and send
|
||||
|
|
|
@ -39,7 +39,8 @@ RtlSdrSource::~RtlSdrSource()
|
|||
bool RtlSdrSource::configure(uint32_t sample_rate,
|
||||
uint32_t frequency,
|
||||
int tuner_gain,
|
||||
int block_length)
|
||||
int block_length,
|
||||
bool agcmode)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
@ -78,6 +79,13 @@ bool RtlSdrSource::configure(uint32_t sample_rate,
|
|||
}
|
||||
}
|
||||
|
||||
// set RTL AGC mode
|
||||
r = rtlsdr_set_agc_mode(m_dev, int(agcmode));
|
||||
if (r < 0) {
|
||||
m_error = "rtlsdr_set_agc_mode failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
// set block length
|
||||
m_block_length = (block_length < 4096) ? 4096 :
|
||||
(block_length > 1024 * 1024) ? 1024 * 1024 :
|
||||
|
|
|
@ -25,13 +25,14 @@ public:
|
|||
*
|
||||
* sample_rate :: desired sample rate in Hz.
|
||||
* frequency :: desired center frequency in Hz.
|
||||
* gain :: desired tuner gain index, or -1 for auto-gain.
|
||||
* tuner_gain :: desired tuner gain in 0.1 dB, or -1 for auto-gain.
|
||||
* block_length :: preferred number of samples per block.
|
||||
*
|
||||
* Return true for success, false if an error occurred.
|
||||
*/
|
||||
bool configure(uint32_t sample_rate, uint32_t frequency, int tuner_gain,
|
||||
int block_length=default_block_length);
|
||||
int block_length=default_block_length,
|
||||
bool agcmode=false);
|
||||
|
||||
/** Return current sample frequency in Hz. */
|
||||
uint32_t get_sample_rate();
|
||||
|
|
3
TODO.txt
3
TODO.txt
|
@ -1,12 +1,9 @@
|
|||
* (experiment) consider reducing IF filter bandwidth to ~ 80 kHz
|
||||
* (experiment) consider downsampling IF signal before FM detection
|
||||
* (experiment) try if RTL AGC mode improves FM decoding
|
||||
|
||||
* (feature) support 'M' 'k' suffixes for sample rates and tuning frequency
|
||||
* (feature) implement stereo pilot pulse-per-second
|
||||
* (speedup) maybe replace high-order FIR downsampling filter with 2nd order butterworth followed by lower order FIR filter
|
||||
* figure out why we sometimes lose stereo lock
|
||||
* it looks like IF level sometimes varies so much that it saturates the receiver; perhaps this can be solved by dynamically managing the hardware gain in response to level measurements
|
||||
* (quality) figure out if hardware gain settings can improve weak stations
|
||||
* (feature) implement RDS decoding
|
||||
* (quality) consider FM demodulation with PLL instead of phase discriminator
|
||||
|
|
23
main.cc
23
main.cc
|
@ -217,6 +217,7 @@ void usage()
|
|||
" -d devidx RTL-SDR device index, 'list' to show device list (default 0)\n"
|
||||
" -s ifrate IF sample rate in Hz (default 1000000, min 900001)\n"
|
||||
" -r pcmrate Audio sample rate in Hz (default 48000 Hz)\n"
|
||||
" -a 0 Disable RTL AGC mode (default 1 = enabled)\n"
|
||||
" -M Disable stereo decoding\n"
|
||||
" -R filename Write audio data as raw S16_LE samples\n"
|
||||
" use filename '-' to write to stdout\n"
|
||||
|
@ -266,6 +267,7 @@ int main(int argc, char **argv)
|
|||
string filename;
|
||||
string alsadev("default");
|
||||
double bufsecs = -1;
|
||||
int agcmode = 1;
|
||||
|
||||
fprintf(stderr,
|
||||
"SoftFM - Software decoder for FM broadcast radio with RTL-SDR\n");
|
||||
|
@ -275,6 +277,7 @@ int main(int argc, char **argv)
|
|||
{ "dev", 1, NULL, 'd' },
|
||||
{ "ifrate", 1, NULL, 's' },
|
||||
{ "pcmrate", 1, NULL, 'r' },
|
||||
{ "agc", 1, NULL, 'a' },
|
||||
{ "mono", 0, NULL, 'M' },
|
||||
{ "raw", 1, NULL, 'R' },
|
||||
{ "wav", 1, NULL, 'W' },
|
||||
|
@ -284,7 +287,7 @@ int main(int argc, char **argv)
|
|||
|
||||
int c, longindex;
|
||||
while ((c = getopt_long(argc, argv,
|
||||
"f:d:s:r:MR:W:P::b:",
|
||||
"f:d:s:r:MR:W:P::b:a:",
|
||||
longopts, &longindex)) >= 0) {
|
||||
switch (c) {
|
||||
case 'f':
|
||||
|
@ -328,13 +331,24 @@ int main(int argc, char **argv)
|
|||
badarg("-b");
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
if (!parse_opt(optarg, agcmode)) {
|
||||
badarg("-a");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
fprintf(stderr, "ERROR: Unknown option\n");
|
||||
fprintf(stderr, "ERROR: Invalid command line options\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
usage();
|
||||
fprintf(stderr, "ERROR: Invalid command line options\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
vector<string> devnames = RtlSdrSource::get_device_names();
|
||||
if (devidx < 0 || (unsigned int)devidx >= devnames.size()) {
|
||||
fprintf(stderr, "ERROR: invalid device index %d\n", devidx);
|
||||
|
@ -377,7 +391,8 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
// Configure RTL-SDR device and start streaming.
|
||||
rtlsdr.configure(ifrate, tuner_freq, -1);
|
||||
rtlsdr.configure(ifrate, tuner_freq, -1,
|
||||
RtlSdrSource::default_block_length, agcmode);
|
||||
if (!rtlsdr) {
|
||||
fprintf(stderr, "ERROR: RtlSdr: %s\n", rtlsdr.error().c_str());
|
||||
exit(1);
|
||||
|
@ -389,6 +404,8 @@ int main(int argc, char **argv)
|
|||
ifrate = rtlsdr.get_sample_rate();
|
||||
fprintf(stderr, "IF sample rate %.0f Hz\n", ifrate);
|
||||
|
||||
fprintf(stderr, "RTL AGC mode %s\n", agcmode ? "enabled" : "disabled");
|
||||
|
||||
// Create source data queue.
|
||||
DataBuffer<IQSample> source_buffer;
|
||||
|
||||
|
|
Loading…
Reference in New Issue