#14411: cross-compile libsample

Signed-off-by: Emeric Vigier <emeric.vigier@savoirfairelinux.com>
diff --git a/jni/libsamplerate-0.1.8/tests/src-evaluate.c b/jni/libsamplerate-0.1.8/tests/src-evaluate.c
new file mode 100644
index 0000000..7fe3478
--- /dev/null
+++ b/jni/libsamplerate-0.1.8/tests/src-evaluate.c
@@ -0,0 +1,529 @@
+/*
+** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "config.h"
+
+#if (HAVE_FFTW3 && HAVE_SNDFILE && HAVE_SYS_TIMES_H)
+
+#include <time.h>
+#include <sys/times.h>
+
+#include <sndfile.h>
+#include <math.h>
+#include <sys/utsname.h>
+
+#include "util.h"
+
+#define	MAX_FREQS		4
+#define	BUFFER_LEN		80000
+
+#define SAFE_STRNCAT(dest,src,len)								\
+		{	int safe_strncat_count ;							\
+			safe_strncat_count = (len) - strlen (dest) - 1 ;	\
+			strncat ((dest), (src), safe_strncat_count) ;		\
+			(dest) [(len) - 1] = 0 ;							\
+			} ;
+
+typedef struct
+{	int		freq_count ;
+	double	freqs [MAX_FREQS] ;
+
+	int		output_samplerate ;
+	int		pass_band_peaks ;
+
+	double	peak_value ;
+} SNR_TEST ;
+
+typedef struct
+{	const char	*progname ;
+	const char	*version_cmd ;
+	const char	*version_start ;
+	const char	*convert_cmd ;
+	int			format ;
+} RESAMPLE_PROG ;
+
+static char *get_progname (char *) ;
+static void usage_exit (const char *, const RESAMPLE_PROG *prog, int count) ;
+static void measure_program (const RESAMPLE_PROG *prog, int verbose) ;
+static void generate_source_wav (const char *filename, const double *freqs, int freq_count, int format) ;
+static const char* get_machine_details (void) ;
+
+static char	version_string [512] ;
+
+int
+main (int argc, char *argv [])
+{	static RESAMPLE_PROG resample_progs [] =
+	{	{	"sndfile-resample",
+			"examples/sndfile-resample --version",
+			"libsamplerate",
+			"examples/sndfile-resample --max-speed -c 0 -to %d source.wav destination.wav",
+			SF_FORMAT_WAV | SF_FORMAT_PCM_32
+			},
+		{	"sox",
+			"sox -h 2>&1",
+			"sox",
+			"sox source.wav -r %d destination.wav resample 0.835",
+			SF_FORMAT_WAV | SF_FORMAT_PCM_32
+			},
+		{	"ResampAudio",
+			"ResampAudio --version",
+			"ResampAudio",
+			"ResampAudio -f cutoff=0.41,atten=100,ratio=128 -s %d source.wav destination.wav",
+			SF_FORMAT_WAV | SF_FORMAT_PCM_32
+			},
+
+		/*-
+		{	/+*
+			** The Shibatch converter doesn't work for all combinations of
+			** source and destination sample rates. Therefore it can't be
+			** included in this test.
+			*+/
+			"shibatch",
+			"ssrc",
+			"Shibatch",
+			"ssrc --rate %d source.wav destination.wav",
+			SF_FORMAT_WAV | SF_FORMAT_PCM_32
+			},-*/
+
+		/*-
+		{	/+*
+			** The resample program is not able to match the bandwidth and SNR
+			** specs or sndfile-resample and hence will not be tested.
+			*+/
+			"resample",
+			"resample -version",
+			"resample",
+			"resample -to %d source.wav destination.wav",
+			SF_FORMAT_WAV | SF_FORMAT_FLOAT
+			},-*/
+
+		/*-
+		{	"mplayer",
+			"mplayer -v 2>&1",
+			"MPlayer ",
+			"mplayer -ao pcm -srate %d source.wav >/dev/null 2>&1 && mv audiodump.wav destination.wav",
+			SF_FORMAT_WAV | SF_FORMAT_PCM_32
+			},-*/
+
+		} ; /* resample_progs */
+
+	char	*progname ;
+	int 	prog = 0, verbose = 0 ;
+
+	progname = get_progname (argv [0]) ;
+
+	printf ("\n  %s : evaluate a sample rate converter.\n", progname) ;
+
+	if (argc == 3 && strcmp ("--verbose", argv [1]) == 0)
+	{	verbose = 1 ;
+		prog = atoi (argv [2]) ;
+		}
+	else if (argc == 2)
+	{	verbose = 0 ;
+		prog = atoi (argv [1]) ;
+		}
+	else
+		usage_exit (progname, resample_progs, ARRAY_LEN (resample_progs)) ;
+
+	if (prog < 0 || prog >= ARRAY_LEN (resample_progs))
+		usage_exit (progname, resample_progs, ARRAY_LEN (resample_progs)) ;
+
+	measure_program (& (resample_progs [prog]), verbose) ;
+
+	puts ("") ;
+
+	return 0 ;
+} /* main */
+
+/*==============================================================================
+*/
+
+static char *
+get_progname (char *progname)
+{	char *cptr ;
+
+	if ((cptr = strrchr (progname, '/')) != NULL)
+		progname = cptr + 1 ;
+
+	if ((cptr = strrchr (progname, '\\')) != NULL)
+		progname = cptr + 1 ;
+
+	return progname ;
+} /* get_progname */
+
+static void
+usage_exit (const char *progname, const RESAMPLE_PROG *prog, int count)
+{	int k ;
+
+	printf ("\n  Usage : %s <number>\n\n", progname) ;
+
+	puts ("  where <number> specifies the program to test:\n") ;
+
+	for (k = 0 ; k < count ; k++)
+		printf ("    %d : %s\n", k, prog [k].progname) ;
+
+	puts ("\n"
+		" Obviously to test a given program you have to have it available on\n"
+		" your system. See http://www.mega-nerd.com/SRC/quality.html for\n"
+		" the download location of these programs.\n") ;
+
+	exit (1) ;
+} /* usage_exit */
+
+static const char*
+get_machine_details (void)
+{	static char namestr [256] ;
+
+	struct utsname name ;
+
+	if (uname (&name) != 0)
+	{	snprintf (namestr, sizeof (namestr), "Unknown") ;
+		return namestr ;
+		} ;
+
+	snprintf (namestr, sizeof (namestr), "%s (%s %s %s)", name.nodename,
+			name.machine, name.sysname, name.release) ;
+
+	return namestr ;
+} /* get_machine_details */
+
+
+/*==============================================================================
+*/
+
+static void
+get_version_string (const RESAMPLE_PROG *prog)
+{	FILE *file ;
+	char *cptr ;
+
+	/* Default. */
+	snprintf (version_string, sizeof (version_string), "no version") ;
+
+	if (prog->version_cmd == NULL)
+		return ;
+
+	if ((file = popen (prog->version_cmd, "r")) == NULL)
+		return ;
+
+	while ((cptr = fgets (version_string, sizeof (version_string), file)) != NULL)
+	{
+		if (strstr (cptr, prog->version_start) != NULL)
+			break ;
+
+		version_string [0] = 0 ;
+		} ;
+
+	pclose (file) ;
+
+	/* Remove trailing newline. */
+	if ((cptr = strchr (version_string, '\n')) != NULL)
+		cptr [0] = 0 ;
+
+	/* Remove leading whitespace from version string. */
+	cptr = version_string ;
+	while (cptr [0] != 0 && isspace (cptr [0]))
+		cptr ++ ;
+
+	if (cptr != version_string)
+		strncpy (version_string, cptr, sizeof (version_string)) ;
+
+	return ;
+} /* get_version_string */
+
+static void
+generate_source_wav (const char *filename, const double *freqs, int freq_count, int format)
+{	static float buffer [BUFFER_LEN] ;
+
+	SNDFILE *sndfile ;
+	SF_INFO sfinfo ;
+
+	sfinfo.channels = 1 ;
+	sfinfo.samplerate = 44100 ;
+	sfinfo.format = format ;
+
+	if ((sndfile = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
+	{	printf ("Line %d : cound not open '%s' : %s\n", __LINE__, filename, sf_strerror (NULL)) ;
+		exit (1) ;
+		} ;
+
+	sf_command (sndfile, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE) ;
+
+	gen_windowed_sines (freq_count, freqs, 0.9, buffer, ARRAY_LEN (buffer)) ;
+
+	if (sf_write_float (sndfile, buffer, ARRAY_LEN (buffer)) != ARRAY_LEN (buffer))
+	{	printf ("Line %d : sf_write_float short write.\n", __LINE__) ;
+		exit (1) ;
+		} ;
+
+	sf_close (sndfile) ;
+} /* generate_source_wav */
+
+static double
+measure_destination_wav (char *filename, int *output_samples, int expected_peaks)
+{	static float buffer [250000] ;
+
+	SNDFILE *sndfile ;
+	SF_INFO sfinfo ;
+	double snr ;
+
+	if ((sndfile = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
+	{	printf ("Line %d : Cound not open '%s' : %s\n", __LINE__, filename, sf_strerror (NULL)) ;
+		exit (1) ;
+		} ;
+
+	if (sfinfo.channels != 1)
+	{	printf ("Line %d : Bad channel count (%d). Should be 1.\n", __LINE__, sfinfo.channels) ;
+		exit (1) ;
+		} ;
+
+	if (sfinfo.frames > ARRAY_LEN (buffer))
+	{	printf ("Line %d : Too many frames (%ld) of data in file.\n", __LINE__, (long) sfinfo.frames) ;
+		exit (1) ;
+		} ;
+
+	*output_samples = (int) sfinfo.frames ;
+
+	if (sf_read_float (sndfile, buffer, sfinfo.frames) != sfinfo.frames)
+	{	printf ("Line %d : Bad read.\n", __LINE__) ;
+		exit (1) ;
+		} ;
+
+	sf_close (sndfile) ;
+
+	snr = calculate_snr (buffer, sfinfo.frames, expected_peaks) ;
+
+	return snr ;
+} /* measure_desination_wav */
+
+static double
+measure_snr (const RESAMPLE_PROG *prog, int *output_samples, int verbose)
+{	static SNR_TEST snr_test [] =
+	{
+		{	1,	{ 0.211111111111 },		48000,		1,	1.0 },
+		{	1,	{ 0.011111111111 },		132301,		1,	1.0 },
+		{	1,	{ 0.111111111111 },		92301,		1,	1.0 },
+		{	1,	{ 0.011111111111 },		26461,		1,	1.0 },
+		{	1,	{ 0.011111111111 },		13231,		1,	1.0 },
+		{	1,	{ 0.011111111111 },		44101,		1,	1.0 },
+		{	2,	{ 0.311111, 0.49 },		78199,		2,	1.0 },
+		{	2,	{ 0.011111, 0.49 },		12345,		1,	0.5 },
+		{	2,	{ 0.0123456, 0.4 },		20143,		1,	0.5 },
+		{	2,	{ 0.0111111, 0.4 },		26461,		1,	0.5 },
+		{	1,	{ 0.381111111111 },		58661,		1,	1.0 }
+		} ; /* snr_test */
+	static char command [256] ;
+
+	double snr, worst_snr = 500.0 ;
+	int k , retval, sample_count ;
+
+	*output_samples = 0 ;
+
+	for (k = 0 ; k < ARRAY_LEN (snr_test) ; k++)
+	{	remove ("source.wav") ;
+		remove ("destination.wav") ;
+
+		if (verbose)
+			printf ("       SNR test #%d : ", k) ;
+		fflush (stdout) ;
+		generate_source_wav ("source.wav", snr_test [k].freqs, snr_test [k].freq_count, prog->format) ;
+
+		snprintf (command, sizeof (command), prog->convert_cmd, snr_test [k].output_samplerate) ;
+		SAFE_STRNCAT (command, " >/dev/null 2>&1", sizeof (command)) ;
+		if ((retval = system (command)) != 0)
+			printf ("system returned %d\n", retval) ;
+
+		snr = measure_destination_wav ("destination.wav", &sample_count, snr_test->pass_band_peaks) ;
+
+		*output_samples += sample_count ;
+
+		if (fabs (snr) < fabs (worst_snr))
+			worst_snr = fabs (snr) ;
+
+		if (verbose)
+			printf ("%6.2f dB\n", snr) ;
+		} ;
+
+	return worst_snr ;
+} /* measure_snr */
+
+/*------------------------------------------------------------------------------
+*/
+
+static double
+measure_destination_peak (const char *filename)
+{	static float data [2 * BUFFER_LEN] ;
+	SNDFILE		*sndfile ;
+	SF_INFO		sfinfo ;
+	double		peak = 0.0 ;
+	int			k = 0 ;
+
+	if ((sndfile = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
+	{	printf ("Line %d : failed to open file %s\n", __LINE__, filename) ;
+		exit (1) ;
+		} ;
+
+	if (sfinfo.channels != 1)
+	{	printf ("Line %d : bad channel count.\n", __LINE__) ;
+		exit (1) ;
+		} ;
+
+	if (sfinfo.frames > ARRAY_LEN (data) + 4 || sfinfo.frames < ARRAY_LEN (data) - 100)
+	{	printf ("Line %d : bad frame count (got %d, expected %d).\n", __LINE__, (int) sfinfo.frames, ARRAY_LEN (data)) ;
+		exit (1) ;
+		} ;
+
+	if (sf_read_float (sndfile, data, sfinfo.frames) != sfinfo.frames)
+	{	printf ("Line %d : bad read.\n", __LINE__) ;
+		exit (1) ;
+		} ;
+
+	sf_close (sndfile) ;
+
+	for (k = 0 ; k < (int) sfinfo.frames ; k++)
+		if (fabs (data [k]) > peak)
+			peak = fabs (data [k]) ;
+
+	return peak ;
+} /* measure_destination_peak */
+
+static double
+find_attenuation (double freq, const RESAMPLE_PROG *prog, int verbose)
+{	static char	command [256] ;
+	double	output_peak ;
+	int		retval ;
+	char	*filename ;
+
+	filename = "destination.wav" ;
+
+	generate_source_wav ("source.wav", &freq, 1, prog->format) ;
+
+	remove (filename) ;
+
+	snprintf (command, sizeof (command), prog->convert_cmd, 88189) ;
+	SAFE_STRNCAT (command, " >/dev/null 2>&1", sizeof (command)) ;
+	if ((retval = system (command)) != 0)
+		printf ("system returned %d\n", retval) ;
+
+	output_peak = measure_destination_peak (filename) ;
+
+	if (verbose)
+		printf ("        freq : %f     peak : %f\n", freq, output_peak) ;
+
+	return fabs (20.0 * log10 (output_peak)) ;
+} /* find_attenuation */
+
+static double
+bandwidth_test (const RESAMPLE_PROG *prog, int verbose)
+{	double	f1, f2, a1, a2 ;
+	double	freq, atten ;
+
+	f1 = 0.35 ;
+	a1 = find_attenuation (f1, prog, verbose) ;
+
+	f2 = 0.49999 ;
+	a2 = find_attenuation (f2, prog, verbose) ;
+
+
+	if (fabs (a1) < 1e-2 && a2 < 3.0)
+		return -1.0 ;
+
+	if (a1 > 3.0 || a2 < 3.0)
+	{	printf ("\n\nLine %d : cannot bracket 3dB point.\n\n", __LINE__) ;
+		exit (1) ;
+		} ;
+
+	while (a2 - a1 > 1.0)
+	{	freq = f1 + 0.5 * (f2 - f1) ;
+		atten = find_attenuation (freq, prog, verbose) ;
+
+		if (atten < 3.0)
+		{	f1 = freq ;
+			a1 = atten ;
+			}
+		else
+		{	f2 = freq ;
+			a2 = atten ;
+			} ;
+		} ;
+
+	freq = f1 + (3.0 - a1) * (f2 - f1) / (a2 - a1) ;
+
+	return 200.0 * freq ;
+} /* bandwidth_test */
+
+static void
+measure_program (const RESAMPLE_PROG *prog, int verbose)
+{	double	snr, bandwidth, conversion_rate ;
+	int		output_samples ;
+	struct	tms	time_data ;
+	time_t	time_now ;
+
+	printf ("\n  Machine : %s\n", get_machine_details ()) ;
+	time_now = time (NULL) ;
+	printf ("  Date    : %s", ctime (&time_now)) ;
+
+	get_version_string (prog) ;
+	printf ("  Program : %s\n", version_string) ;
+	printf ("  Command : %s\n\n", prog->convert_cmd) ;
+
+	snr = measure_snr (prog, &output_samples, verbose) ;
+
+	printf ("  Worst case SNR     : %6.2f dB\n", snr) ;
+
+	times (&time_data) ;
+
+	conversion_rate = (1.0 * output_samples * sysconf (_SC_CLK_TCK)) / time_data.tms_cutime ;
+
+	printf ("  Conversion rate    : %5.0f samples/sec\n", conversion_rate) ;
+
+	bandwidth = bandwidth_test (prog, verbose) ;
+
+	if (bandwidth > 0.0)
+		printf ("  Measured bandwidth : %5.2f %%\n", bandwidth) ;
+	else
+		printf ("  Could not measure bandwidth (no -3dB point found).\n") ;
+
+	return ;
+} /* measure_program */
+
+/*##############################################################################
+*/
+
+#else
+
+int
+main (void)
+{	puts ("\n"
+		"****************************************************************\n"
+		" This program has been compiled without :\n"
+		"	1) FFTW (http://www.fftw.org/).\n"
+		"	2) libsndfile (http://www.zip.com.au/~erikd/libsndfile/).\n"
+		" Without these two libraries there is not much it can do.\n"
+		"****************************************************************\n") ;
+
+	return 0 ;
+} /* main */
+
+#endif /* (HAVE_FFTW3 && HAVE_SNDFILE) */
+