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