view src/libsamplerate-0.1.9/tests/multichan_throughput_test.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 481f5f8c5634
children
line wrap: on
line source
/*
** Copyright (c) 2008-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include <samplerate.h>

#include "config.h"

#include "util.h"
#include "float_cast.h"

#define BUFFER_LEN	(1<<17)

static float input [BUFFER_LEN] ;
static float output [BUFFER_LEN] ;

static long
throughput_test (int converter, int channels, long best_throughput)
{	SRC_DATA src_data ;
	clock_t start_time, clock_time ;
	double duration ;
	long total_frames = 0, throughput ;
	int error ;

	printf ("    %-30s     %2d         ", src_get_name (converter), channels) ;
	fflush (stdout) ;

	src_data.data_in = input ;
	src_data.input_frames = ARRAY_LEN (input) / channels ;

	src_data.data_out = output ;
	src_data.output_frames = ARRAY_LEN (output) / channels ;

	src_data.src_ratio = 0.99 ;

	sleep (2) ;

	start_time = clock () ;

	do
	{
		if ((error = src_simple (&src_data, converter, channels)) != 0)
		{	puts (src_strerror (error)) ;
			exit (1) ;
			} ;

		total_frames += src_data.output_frames_gen ;

		clock_time = clock () - start_time ;
		duration = (1.0 * clock_time) / CLOCKS_PER_SEC ;
	}
	while (duration < 5.0) ;

	if (src_data.input_frames_used != src_data.input_frames)
	{	printf ("\n\nLine %d : input frames used %ld should be %ld\n", __LINE__, src_data.input_frames_used, src_data.input_frames) ;
		exit (1) ;
		} ;

	if (fabs (src_data.src_ratio * src_data.input_frames_used - src_data.output_frames_gen) > 2)
	{	printf ("\n\nLine %d : input / output length mismatch.\n\n", __LINE__) ;
		printf ("    input len  : %d\n", ARRAY_LEN (input) / channels) ;
		printf ("    output len : %ld (should be %g +/- 2)\n\n", src_data.output_frames_gen,
				floor (0.5 + src_data.src_ratio * src_data.input_frames_used)) ;
		exit (1) ;
		} ;

	throughput = lrint (floor (total_frames / duration)) ;

	if (best_throughput == 0)
	{	best_throughput = MAX (throughput, best_throughput) ;
		printf ("%5.2f      %10ld\n", duration, throughput) ;
		}
	else
	{	best_throughput = MAX (throughput, best_throughput) ;
		printf ("%5.2f      %10ld       %10ld\n", duration, throughput, best_throughput) ;
		}

	return best_throughput ;
} /* throughput_test */

static void
single_run (void)
{	const int max_channels = 10 ;
	int k ;

	printf ("\n    CPU name : %s\n", get_cpu_name ()) ;

	puts (
		"\n"
		"    Converter                        Channels    Duration      Throughput\n"
		"    ---------------------------------------------------------------------"
		) ;

	for (k = 1 ; k <= max_channels / 2 ; k++)
		throughput_test (SRC_SINC_FASTEST, k, 0) ;

	puts ("") ;
	for (k = 1 ; k <= max_channels / 2 ; k++)
		throughput_test (SRC_SINC_MEDIUM_QUALITY, k, 0) ;

	puts ("") ;
	for (k = 1 ; k <= max_channels ; k++)
		throughput_test (SRC_SINC_BEST_QUALITY, k, 0) ;

	puts ("") ;
	return ;
} /* single_run */

static void
multi_run (int run_count)
{	int k, ch ;

	printf ("\n    CPU name : %s\n", get_cpu_name ()) ;

	puts (
		"\n"
		"    Converter                        Channels    Duration      Throughput    Best Throughput\n"
		"    ----------------------------------------------------------------------------------------"
		) ;

	for (ch = 1 ; ch <= 5 ; ch++)
	{	long sinc_fastest = 0, sinc_medium = 0, sinc_best = 0 ;

		for (k = 0 ; k < run_count ; k++)
		{	sinc_fastest =		throughput_test (SRC_SINC_FASTEST, ch, sinc_fastest) ;
			sinc_medium =		throughput_test (SRC_SINC_MEDIUM_QUALITY, ch, sinc_medium) ;
			sinc_best =			throughput_test (SRC_SINC_BEST_QUALITY, ch, sinc_best) ;

			puts ("") ;

			/* Let the CPU cool down. We might be running on a laptop. */
			sleep (10) ;
			} ;

		puts (
			"\n"
			"    Converter                        Best Throughput\n"
			"    ------------------------------------------------"
			) ;

		printf ("    %-30s    %10ld\n", src_get_name (SRC_SINC_FASTEST), sinc_fastest) ;
		printf ("    %-30s    %10ld\n", src_get_name (SRC_SINC_MEDIUM_QUALITY), sinc_medium) ;
		printf ("    %-30s    %10ld\n", src_get_name (SRC_SINC_BEST_QUALITY), sinc_best) ;
		} ;

	puts ("") ;
} /* multi_run */

static void
usage_exit (const char * argv0)
{	const char * cptr ;

	if ((cptr = strrchr (argv0, '/')) != NULL)
		argv0 = cptr ;

	printf (
		"Usage :\n"
	 	"    %s                 - Single run of the throughput test.\n"
		"    %s --best-of N     - Do N runs of test a print bext result.\n"
		"\n",
		argv0, argv0) ;

	exit (0) ;
} /* usage_exit */

int
main (int argc, char ** argv)
{	double freq ;

	memset (input, 0, sizeof (input)) ;
	freq = 0.01 ;
	gen_windowed_sines (1, &freq, 1.0, input, BUFFER_LEN) ;

	if (argc == 1)
		single_run () ;
	else if (argc == 3 && strcmp (argv [1], "--best-of") == 0)
	{	int run_count = atoi (argv [2]) ;

		if (run_count < 1 || run_count > 20)
		{	printf ("Please be sensible. Run count should be in range (1, 10].\n") ;
			exit (1) ;
			} ;

		multi_run (run_count) ;
		}
	else
		usage_exit (argv [0]) ;

	puts (
		"            Duration is in seconds.\n"
		"            Throughput is in frames/sec (more is better).\n"
		) ;

	return 0 ;
} /* main */