1
0
Fork 0

Pilot PPS logging works.

This commit is contained in:
Joris van Rantwijk 2014-01-19 15:49:43 +01:00
parent f6bca05bf0
commit 6d735bb0f0
4 changed files with 69 additions and 10 deletions

View File

@ -219,9 +219,9 @@ void PilotPhaseLock::process(const SampleVector& samples_in,
m_pilot_periods = 0;
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.pps_index = m_pps_cnt;
ev.sample_index = m_sample_cnt + i;
ev.block_position = double(i) / double(n);
m_pps_events.push_back(ev);
m_pps_cnt++;
}

View File

@ -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;
};
/**

View File

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

68
main.cc
View File

@ -31,6 +31,7 @@
#include <thread>
#include <unistd.h>
#include <getopt.h>
#include <sys/time.h>
#include "SoftFM.h"
#include "RtlSdrSource.h"
@ -212,7 +213,7 @@ static void handle_sigterm(int sig)
void usage()
{
fprintf(stderr,
"Usage: softfm -f freq [options]\n"
"Usage: softfm -f freq [options]\n"
" -f freq Frequency of radio station in Hz\n"
" -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"
@ -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) {