Pilot PPS logging works.
This commit is contained in:
		
							parent
							
								
									f6bca05bf0
								
							
						
					
					
						commit
						6d735bb0f0
					
				|  | @ -220,8 +220,8 @@ void PilotPhaseLock::process(const SampleVector& samples_in, | |||
|                 if (was_locked) { | ||||
|                     struct PpsEvent ev; | ||||
|                     ev.pps_index      = m_pps_cnt; | ||||
|                     ev.abs_sample_index   = m_sample_cnt + i; | ||||
|                     ev.block_sample_index = i; | ||||
|                     ev.sample_index   = m_sample_cnt + i; | ||||
|                     ev.block_position = double(i) / double(n); | ||||
|                     m_pps_events.push_back(ev); | ||||
|                     m_pps_cnt++; | ||||
|                 } | ||||
|  |  | |||
|  | @ -46,8 +46,8 @@ public: | |||
|     struct PpsEvent | ||||
|     { | ||||
|         std::uint64_t   pps_index; | ||||
|         std::uint64_t   abs_sample_index; | ||||
|         std::uint64_t   block_sample_index; | ||||
|         std::uint64_t   sample_index; | ||||
|         double          block_position; | ||||
|     }; | ||||
| 
 | ||||
|     /**
 | ||||
|  |  | |||
							
								
								
									
										1
									
								
								TODO.txt
								
								
								
								
							
							
						
						
									
										1
									
								
								TODO.txt
								
								
								
								
							|  | @ -1,4 +1,3 @@ | |||
| * (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 | ||||
| * (feature) implement RDS decoding | ||||
|  |  | |||
							
								
								
									
										66
									
								
								main.cc
								
								
								
								
							
							
						
						
									
										66
									
								
								main.cc
								
								
								
								
							|  | @ -31,6 +31,7 @@ | |||
| #include <thread> | ||||
| #include <unistd.h> | ||||
| #include <getopt.h> | ||||
| #include <sys/time.h> | ||||
| 
 | ||||
| #include "SoftFM.h" | ||||
| #include "RtlSdrSource.h" | ||||
|  | @ -223,6 +224,8 @@ void usage() | |||
|             "                use filename '-' to write to stdout\n" | ||||
|             "  -W filename   Write audio data to .WAV file\n" | ||||
|             "  -P [device]   Play audio via ALSA device (default 'default')\n" | ||||
|             "  -T filename   Write pulse-per-second timestamps\n" | ||||
|             "                use filename '-' to write to stdout\n" | ||||
|             "  -b seconds    Set audio buffer size in seconds\n" | ||||
|             "\n"); | ||||
| } | ||||
|  | @ -274,6 +277,15 @@ bool parse_dbl(const char *s, double& v) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| /** Return Unix time stamp in seconds. */ | ||||
| double get_time() | ||||
| { | ||||
|     struct timeval tv; | ||||
|     gettimeofday(&tv, NULL); | ||||
|     return tv.tv_sec + 1.0e-6 * tv.tv_usec; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
|     double  freq    = -1; | ||||
|  | @ -285,6 +297,8 @@ int main(int argc, char **argv) | |||
|     OutputMode outmode = MODE_ALSA; | ||||
|     string  filename; | ||||
|     string  alsadev("default"); | ||||
|     string  ppsfilename; | ||||
|     FILE *  ppsfile = NULL; | ||||
|     double  bufsecs = -1; | ||||
|     int     agcmode = 1; | ||||
| 
 | ||||
|  | @ -301,12 +315,13 @@ int main(int argc, char **argv) | |||
|         { "raw",        1, NULL, 'R' }, | ||||
|         { "wav",        1, NULL, 'W' }, | ||||
|         { "play",       2, NULL, 'P' }, | ||||
|         { "pps",        1, NULL, 'T' }, | ||||
|         { "buffer",     1, NULL, 'b' }, | ||||
|         { NULL,         0, NULL, 0 } }; | ||||
| 
 | ||||
|     int c, longindex; | ||||
|     while ((c = getopt_long(argc, argv, | ||||
|                             "f:d:s:r:MR:W:P::b:a:", | ||||
|                             "f:d:s:r:MR:W:P::T:b:a:", | ||||
|                             longopts, &longindex)) >= 0) { | ||||
|         switch (c) { | ||||
|             case 'f': | ||||
|  | @ -345,6 +360,9 @@ int main(int argc, char **argv) | |||
|                 if (optarg != NULL) | ||||
|                     alsadev = optarg; | ||||
|                 break; | ||||
|             case 'T': | ||||
|                 ppsfilename = optarg; | ||||
|                 break; | ||||
|             case 'b': | ||||
|                 if (!parse_dbl(optarg, bufsecs) || bufsecs < 0) { | ||||
|                     badarg("-b"); | ||||
|  | @ -469,6 +487,25 @@ int main(int argc, char **argv) | |||
|                 outputbuf_samples / double(pcmrate)); | ||||
|     } | ||||
| 
 | ||||
|     // Open PPS file.
 | ||||
|     if (!ppsfilename.empty()) { | ||||
|         if (ppsfilename == "-") { | ||||
|             fprintf(stderr, "Writing pulse-per-second markers to stdout\n"); | ||||
|             ppsfile = stdout; | ||||
|         } else { | ||||
|             fprintf(stderr, "Writing pulse-per-second markers to '%s'\n", | ||||
|                     ppsfilename.c_str()); | ||||
|             ppsfile = fopen(ppsfilename.c_str(), "w"); | ||||
|             if (ppsfile == NULL) { | ||||
|                 fprintf(stderr, "ERROR: can not open '%s' (%s)\n", | ||||
|                         ppsfilename.c_str(), strerror(errno)); | ||||
|                 exit(1); | ||||
|             } | ||||
|         } | ||||
|         fprintf(ppsfile, "#pps_index sample_index   unix_time\n"); | ||||
|         fflush(ppsfile); | ||||
|     } | ||||
| 
 | ||||
|     // Prepare output writer.
 | ||||
|     unique_ptr<AudioOutput> audio_output; | ||||
|     switch (outmode) { | ||||
|  | @ -511,6 +548,8 @@ int main(int argc, char **argv) | |||
|     double audio_level = 0; | ||||
|     bool got_stereo = false; | ||||
| 
 | ||||
|     double block_time = get_time(); | ||||
| 
 | ||||
|     // Main loop.
 | ||||
|     for (unsigned int block = 0; !stop_flag.load(); block++) { | ||||
| 
 | ||||
|  | @ -527,6 +566,9 @@ int main(int argc, char **argv) | |||
|         if (iqsamples.empty()) | ||||
|             break; | ||||
| 
 | ||||
|         double prev_block_time = block_time; | ||||
|         block_time = get_time(); | ||||
| 
 | ||||
|         // Decode FM signal.
 | ||||
|         fm.process(iqsamples, audiosamples); | ||||
| 
 | ||||
|  | @ -535,10 +577,10 @@ int main(int argc, char **argv) | |||
|         samples_mean_rms(audiosamples, audio_mean, audio_rms); | ||||
|         audio_level = 0.95 * audio_level + 0.05 * audio_rms; | ||||
| 
 | ||||
|         // Set nominal audio volume.
 | ||||
|         adjust_gain(audiosamples, 0.5); | ||||
| 
 | ||||
| // TODO : investigate I/Q imbalance to fix Radio4 noise
 | ||||
| 
 | ||||
|         // Show statistics.
 | ||||
|         fprintf(stderr, | ||||
|                 "\rblk=%6d  freq=%8.4fMHz  IF=%+5.1fdB  BB=%+5.1fdB  audio=%+5.1fdB ", | ||||
|                 block, | ||||
|  | @ -555,6 +597,7 @@ int main(int argc, char **argv) | |||
|         } | ||||
|         fflush(stderr); | ||||
| 
 | ||||
|         // Show stereo status.
 | ||||
|         if (fm.stereo_detected() != got_stereo) { | ||||
|             got_stereo = fm.stereo_detected(); | ||||
|             if (got_stereo) | ||||
|  | @ -564,6 +607,23 @@ int main(int argc, char **argv) | |||
|                 fprintf(stderr, "\nlost stereo signal\n"); | ||||
|         } | ||||
| 
 | ||||
|         // Write PPS markers.
 | ||||
|         if (ppsfile != NULL) { | ||||
|             for (const PilotPhaseLock::PpsEvent& ev : fm.get_pps_events()) { | ||||
|                 double ts = prev_block_time; | ||||
|                 ts += ev.block_position * (block_time - prev_block_time); | ||||
|                 if (ppsfile == stdout && isatty(fileno(ppsfile))) { | ||||
|                     fprintf(stderr, "\n"); | ||||
|                     fflush(stderr); | ||||
|                 } | ||||
|                 fprintf(ppsfile, "%8s %14s %18.6f\n", | ||||
|                         to_string(ev.pps_index).c_str(), | ||||
|                         to_string(ev.sample_index).c_str(), | ||||
|                         ts); | ||||
|                 fflush(ppsfile); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Throw away first block. It is noisy because IF filters
 | ||||
|         // are still starting up.
 | ||||
|         if (block > 0) { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue