aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Keen <keenerd@gmail.com>2014-01-23 01:25:43 -0500
committerSteve Markgraf <steve@steve-m.de>2014-01-23 23:26:05 +0100
commit835bd23542f1ec3f48e3da918cb6f80a6f9ea92a (patch)
tree99dc468885a668ff67af2b805de87007a4addc40
parent8520c7c3d7286e32e2d867adb2419a0410866bec (diff)
rtl_test: useful ppm
Signed-off-by: Steve Markgraf <steve@steve-m.de>
-rw-r--r--src/rtl_test.c90
1 files changed, 63 insertions, 27 deletions
diff --git a/src/rtl_test.c b/src/rtl_test.c
index d7dbf81..571614c 100644
--- a/src/rtl_test.c
+++ b/src/rtl_test.c
@@ -53,8 +53,13 @@ static int do_exit = 0;
static rtlsdr_dev_t *dev = NULL;
static int ppm_benchmark = 0;
+static int ppm_running = 0;
static int64_t ppm_count = 0L;
static int64_t ppm_total = 0L;
+uint32_t samp_rate = DEFAULT_SAMPLE_RATE;
+
+long total_samples;
+long dropped_samples;
#ifndef _WIN32
static struct timespec ppm_start;
@@ -103,17 +108,15 @@ static void sighandler(int signum)
}
#endif
-static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
+static void underrun_test(unsigned char *buf, uint32_t len, int mute)
{
uint32_t i, lost = 0;
- int64_t ns;
static uint8_t bcnt, uninit = 1;
if (uninit) {
bcnt = buf[0];
uninit = 0;
}
-
for (i = 0; i < len; i++) {
if(bcnt != buf[i]) {
lost += (buf[i] > bcnt) ? (buf[i] - bcnt) : (bcnt - buf[i]);
@@ -123,12 +126,43 @@ static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
bcnt++;
}
+ total_samples += (long)len;
+ dropped_samples += (long)lost;
+ if (mute)
+ return;
if (lost)
printf("lost at least %d bytes\n", lost);
- if (!ppm_benchmark) {
- return;
- }
+}
+
+static void ppm_clock_init(void)
+{
+#ifdef __APPLE__
+ gettimeofday(&tv, NULL);
+ ppm_recent.tv_sec = tv.tv_sec;
+ ppm_recent.tv_nsec = tv.tv_usec*1000;
+ ppm_start.tv_sec = tv.tv_sec;
+ ppm_start.tv_nsec = tv.tv_usec*1000;
+#elif __unix__
+ clock_gettime(CLOCK_REALTIME, &ppm_recent);
+ clock_gettime(CLOCK_REALTIME, &ppm_start);
+#endif
+}
+
+static int ppm_report(void)
+{
+ int real_rate;
+ int64_t ns;
+ ns = 1000000000L * (int64_t)(ppm_recent.tv_sec - ppm_start.tv_sec);
+ ns += (int64_t)(ppm_recent.tv_nsec - ppm_start.tv_nsec);
+ real_rate = (int)(ppm_total * 1000000000L / ns);
+ return (int)round((double)(1000000 * (real_rate - (int)samp_rate)) / (double)samp_rate);
+}
+
+static void ppm_test(uint32_t len)
+{
+ int64_t ns;
+
ppm_count += (int64_t)len;
#ifndef _WIN32
#ifndef __APPLE__
@@ -141,7 +175,7 @@ static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
if (ppm_now.tv_sec - ppm_recent.tv_sec > PPM_DURATION) {
ns = 1000000000L * (int64_t)(ppm_now.tv_sec - ppm_recent.tv_sec);
ns += (int64_t)(ppm_now.tv_nsec - ppm_recent.tv_nsec);
- printf("real sample rate: %i\n",
+ printf("real sample rate: %i",
(int)((1000000000L * ppm_count / 2L) / ns));
#ifndef __APPLE__
clock_gettime(CLOCK_REALTIME, &ppm_recent);
@@ -152,10 +186,26 @@ static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
#endif
ppm_total += ppm_count / 2L;
ppm_count = 0L;
+ printf(" cumulative ppm: %i\n", ppm_report());
}
#endif
}
+static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
+{
+ underrun_test(buf, len, 0);
+
+ if (ppm_benchmark && !ppm_running) {
+ ppm_clock_init();
+ ppm_running = 1;
+ return;
+ }
+
+ if (ppm_benchmark) {
+ ppm_test(len);
+ }
+}
+
void e4k_benchmark(void)
{
uint32_t freq, gap_start = 0, gap_end = 0;
@@ -214,12 +264,9 @@ int main(int argc, char **argv)
uint8_t *buffer;
int dev_index = 0;
int dev_given = 0;
- uint32_t samp_rate = DEFAULT_SAMPLE_RATE;
uint32_t out_block_size = DEFAULT_BUF_LENGTH;
int count;
int gains[100];
- int real_rate;
- int64_t ns;
while ((opt = getopt(argc, argv, "d:s:b:tpS::")) != -1) {
switch (opt) {
@@ -314,16 +361,6 @@ int main(int argc, char **argv)
if (ppm_benchmark && !sync_mode) {
fprintf(stderr, "Reporting PPM error measurement every %i seconds...\n", ppm_benchmark);
fprintf(stderr, "Press ^C after a few minutes.\n");
-#ifdef __APPLE__
- gettimeofday(&tv, NULL);
- ppm_recent.tv_sec = tv.tv_sec;
- ppm_recent.tv_nsec = tv.tv_usec*1000;
- ppm_start.tv_sec = tv.tv_sec;
- ppm_start.tv_nsec = tv.tv_usec*1000;
-#elif __unix__
- clock_gettime(CLOCK_REALTIME, &ppm_recent);
- clock_gettime(CLOCK_REALTIME, &ppm_start);
-#endif
}
if (!ppm_benchmark) {
@@ -335,6 +372,7 @@ int main(int argc, char **argv)
if (sync_mode) {
fprintf(stderr, "Reading samples in sync mode...\n");
+ fprintf(stderr, "(Samples are being lost but not reported.)\n");
while (!do_exit) {
r = rtlsdr_read_sync(dev, buffer, out_block_size, &n_read);
if (r < 0) {
@@ -346,6 +384,7 @@ int main(int argc, char **argv)
fprintf(stderr, "Short read, samples lost, exiting!\n");
break;
}
+ underrun_test(buffer, n_read, 1);
}
} else {
fprintf(stderr, "Reading samples in async mode...\n");
@@ -355,15 +394,12 @@ int main(int argc, char **argv)
if (do_exit) {
fprintf(stderr, "\nUser cancel, exiting...\n");
- if (ppm_benchmark) {
+ fprintf(stderr, "Samples per million lost (minimum): %i\n", (int)(1000000L * dropped_samples / total_samples));
#ifndef _WIN32
- ns = 1000000000L * (int64_t)(ppm_recent.tv_sec - ppm_start.tv_sec);
- ns += (int64_t)(ppm_recent.tv_nsec - ppm_start.tv_nsec);
- real_rate = (int)(ppm_total * 1000000000L / ns);
- printf("Cumulative PPM error: %i\n",
- (int)round((double)(1000000 * (real_rate - (int)samp_rate)) / (double)samp_rate));
-#endif
+ if (ppm_benchmark) {
+ printf("Cumulative PPM error: %i\n", ppm_report());
}
+#endif
}
else
fprintf(stderr, "\nLibrary error %d, exiting...\n", r);