1
0
Fork 0

Set RTL AGC mode by default (no improvement), with command-line option to disable.

This commit is contained in:
Joris van Rantwijk 2014-01-18 20:44:17 +01:00
parent ff985cd623
commit 761b368282
5 changed files with 33 additions and 12 deletions

View File

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

View File

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

View File

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

View File

@ -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
View File

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