mirror of
				https://github.com/rtlsdrblog/rtl-sdr-blog.git
				synced 2025-10-31 00:48:08 +01:00 
			
		
		
		
	
				
					committed by
					
						 Steve Markgraf
						Steve Markgraf
					
				
			
			
				
	
			
			
			
						parent
						
							8520c7c3d7
						
					
				
				
					commit
					835bd23542
				
			| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user