Quellcode durchsuchen

rtl_test: useful ppm

Signed-off-by: Steve Markgraf <steve@steve-m.de>
Kyle Keen vor 11 Jahren
Ursprung
Commit
835bd23542
1 geänderte Dateien mit 63 neuen und 27 gelöschten Zeilen
  1. 63 27
      src/rtl_test.c

+ 63 - 27
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);