Exemplo n.º 1
0
static void
callback_reset_test (int converter)
{   static TEST_CB_DATA test_callback_data ;

    static float output [BUFFER_LEN] ;

    SRC_STATE *src_state ;

    double src_ratio = 1.1 ;
    long read_count, read_total ;
    int k, error ;

    printf ("\tcallback_reset_test (%-28s) ....... ", src_get_name (converter)) ;
    fflush (stdout) ;

    for (k = 0 ; k < ARRAY_LEN (data_one) ; k++)
    {   data_one [k] = 1.0 ;
        data_zero [k] = 0.0 ;
    } ;

    if ((src_state = src_callback_new (test_callback_func, converter, 1, &error, &test_callback_data)) == NULL)
    {   printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
        exit (1) ;
    } ;

    /* Process a bunch of 1.0 valued samples. */
    test_callback_data.channels = 1 ;
    test_callback_data.count = 0 ;
    test_callback_data.total = ARRAY_LEN (data_one) ;
    test_callback_data.data = data_one ;

    read_total = 0 ;
    do
    {   read_count = (ARRAY_LEN (output) - read_total > CB_READ_LEN) ? CB_READ_LEN : ARRAY_LEN (output) - read_total ;
        read_count = src_callback_read (src_state, src_ratio, read_count, output + read_total) ;
        read_total += read_count ;
    }
    while (read_count > 0) ;

    /* Check for errors. */
    if ((error = src_error (src_state)) != 0)
    {   printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
        exit (1) ;
    } ;

    /* Reset the state of the converter.*/
    src_reset (src_state) ;

    /* Process a bunch of 0.0 valued samples. */
    test_callback_data.channels = 1 ;
    test_callback_data.count = 0 ;
    test_callback_data.total = ARRAY_LEN (data_zero) ;
    test_callback_data.data = data_zero ;

    /* Now process some zero data. */
    read_total = 0 ;
    do
    {   read_count = (ARRAY_LEN (output) - read_total > CB_READ_LEN) ? CB_READ_LEN : ARRAY_LEN (output) - read_total ;
        read_count = src_callback_read (src_state, src_ratio, read_count, output + read_total) ;
        read_total += read_count ;
    }
    while (read_count > 0) ;

    /* Check for errors. */
    if ((error = src_error (src_state)) != 0)
    {   printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
        exit (1) ;
    } ;

    /* Finally make sure that the output data is zero ie reset was sucessful. */
    for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
        if (output [k] != 0.0)
        {   printf ("\n\nLine %d : output [%d] should be 0.0, is %f.\n\n", __LINE__, k, output [k]) ;
            save_oct_float ("output.dat", data_one, ARRAY_LEN (data_one), output, ARRAY_LEN (output)) ;
            exit (1) ;
        } ;

    /* Make sure that this function has been exported. */
    src_set_ratio (src_state, 1.0) ;

    /* Delete converter. */
    src_state = src_delete (src_state) ;

    puts ("ok") ;
} /* callback_reset_test */
Exemplo n.º 2
0
static double
snr_test (SINGLE_TEST *test_data, int number, int converter, int verbose)
{	static float data [BUFFER_LEN + 1] ;
	static float output [MAX_SPEC_LEN] ;

	SRC_STATE	*src_state ;
	SRC_DATA	src_data ;

	double		output_peak, snr ;
	int 		k, output_len, input_len, error ;

	if (verbose != 0)
	{	printf ("\tSignal-to-Noise Ratio Test %d.\n"
				"\t=====================================\n", number) ;
		printf ("\tFrequencies : [ ") ;
		for (k = 0 ; k < test_data->freq_count ; k++)
			printf ("%6.4f ", test_data->freqs [k]) ;

		printf ("]\n\tSRC Ratio   : %8.4f\n", test_data->src_ratio) ;
		}
	else
	{	printf ("\tSignal-to-Noise Ratio Test %d : ", number) ;
		fflush (stdout) ;
		} ;

	/* Set up the output array. */
	if (test_data->src_ratio >= 1.0)
	{	output_len = MAX_SPEC_LEN ;
		input_len = (int) ceil (MAX_SPEC_LEN / test_data->src_ratio) ;
		if (input_len > BUFFER_LEN)
			input_len = BUFFER_LEN ;
		}
	else
	{	input_len = BUFFER_LEN ;
		output_len = (int) ceil (BUFFER_LEN * test_data->src_ratio) ;
		output_len &= ((-1) << 4) ;
		if (output_len > MAX_SPEC_LEN)
			output_len = MAX_SPEC_LEN ;
		input_len = (int) ceil (output_len / test_data->src_ratio) ;
		} ;

	memset (output, 0, sizeof (output)) ;

	/* Generate input data array. */
	gen_windowed_sines (test_data->freq_count, test_data->freqs, 1.0, data, input_len) ;

	/* Perform sample rate conversion. */
	if ((src_state = src_new (converter, 1, &error)) == NULL)
	{	printf ("\n\nLine %d : src_new() failed : %s.\n\n", __LINE__, src_strerror (error)) ;
		exit (1) ;
		} ;

	src_data.end_of_input = 1 ; /* Only one buffer worth of input. */

	src_data.data_in = data ;
	src_data.input_frames = input_len ;

	src_data.src_ratio = test_data->src_ratio ;

	src_data.data_out = output ;
	src_data.output_frames = output_len ;

	if ((error = src_process (src_state, &src_data)))
	{	printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
		exit (1) ;
		} ;

	src_state = src_delete (src_state) ;

	if (verbose != 0)
		printf ("\tOutput Len  :   %ld\n", src_data.output_frames_gen) ;

	if (abs (src_data.output_frames_gen - output_len) > 4)
	{	printf ("\n\nLine %d : output data length should be %d.\n\n", __LINE__, output_len) ;
		exit (1) ;
		} ;

	/* Check output peak. */
	output_peak = find_peak (output, src_data.output_frames_gen) ;

	if (verbose != 0)
		printf ("\tOutput Peak :   %6.4f\n", output_peak) ;

	if (fabs (output_peak - test_data->peak_value) > 0.01)
	{	printf ("\n\nLine %d : output peak (%6.4f) should be %6.4f\n\n", __LINE__, output_peak, test_data->peak_value) ;
		save_oct_float ("snr_test.dat", data, BUFFER_LEN, output, output_len) ;
		exit (1) ;
		} ;

	/* Calculate signal-to-noise ratio. */
	snr = calculate_snr (output, src_data.output_frames_gen, test_data->pass_band_peaks) ;

	if (snr < 0.0)
	{	/* An error occurred. */
		save_oct_float ("snr_test.dat", data, BUFFER_LEN, output, src_data.output_frames_gen) ;
		exit (1) ;
		} ;

	if (verbose != 0)
		printf ("\tSNR Ratio   :   %.2f dB\n", snr) ;

	if (snr < test_data->snr)
	{	printf ("\n\nLine %d : SNR (%5.2f) should be > %6.2f dB\n\n", __LINE__, snr, test_data->snr) ;
		exit (1) ;
		} ;

	if (verbose != 0)
		puts ("\t-------------------------------------\n\tPass\n") ;
	else
		puts ("Pass") ;

	return snr ;
} /* snr_test */
Exemplo n.º 3
0
static void
callback_test (int converter, int channel_count, double target_snr)
{	TEST_CB_DATA test_callback_data ;
	SRC_STATE	*src_state = NULL ;

	double	freq, snr, src_ratio ;
	int		ch, error, frames, read_total, read_count ;

	printf ("\t%-22s (%d channel%c) ............. ", "callback_test", channel_count, channel_count > 1 ? 's' : ' ') ;
	fflush (stdout) ;

	memset (input_serial, 0, sizeof (input_serial)) ;
	memset (input_interleaved, 0, sizeof (input_interleaved)) ;
	memset (output_interleaved, 0, sizeof (output_interleaved)) ;
	memset (output_serial, 0, sizeof (output_serial)) ;
	memset (&test_callback_data, 0, sizeof (test_callback_data)) ;

	frames = MIN (ARRAY_LEN (input_serial) / channel_count, 1 << 16) ;

	/* Calculate channel_count separate windowed sine waves. */
	for (ch = 0 ; ch < channel_count ; ch++)
	{	freq = (200.0 + 33.333333333 * ch) / 44100.0 ;
		gen_windowed_sines (1, &freq, 1.0, input_serial + ch * frames, frames) ;
		} ;

	/* Interleave the data in preparation for SRC. */
	interleave_data (input_serial, input_interleaved, frames, channel_count) ;

	/* Perform sample rate conversion. */
	src_ratio = 0.95 ;
	test_callback_data.channels = channel_count ;
	test_callback_data.total_frames = frames ;
	test_callback_data.current_frame = 0 ;
	test_callback_data.data = input_interleaved ;

	if ((src_state = src_callback_new (test_callback_func, converter, channel_count, &error, &test_callback_data)) == NULL)
	{	printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
		exit (1) ;
		} ;

	read_total = 0 ;
	while (read_total < frames)
	{	read_count = src_callback_read (src_state, src_ratio, frames - read_total, output_interleaved + read_total * channel_count) ;

		if (read_count <= 0)
			break ;

		read_total += read_count ;
		} ;

	if ((error = src_error (src_state)) != 0)
	{	printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
		exit (1) ;
		} ;

	src_state = src_delete (src_state) ;

	if (fabs (read_total - src_ratio * frames) > 2)
	{	printf ("\n\nLine %d : bad output data length %d should be %d.\n", __LINE__,
					read_total, (int) floor (src_ratio * frames)) ;
		printf ("\tsrc_ratio  : %.4f\n", src_ratio) ;
		printf ("\tinput_len  : %d\n", frames) ;
		printf ("\toutput_len : %d\n\n", read_total) ;
		exit (1) ;
		} ;

	/* De-interleave data so SNR can be calculated for each channel. */
	deinterleave_data (output_interleaved, output_serial, frames, channel_count) ;

	for (ch = 0 ; ch < channel_count ; ch++)
	{	snr = calculate_snr (output_serial + ch * frames, frames, 1) ;
		if (snr < target_snr)
		{	printf ("\n\nLine %d: channel %d snr %f should be %f\n", __LINE__, ch, snr, target_snr) ;
			save_oct_float ("output.dat", input_serial, channel_count * frames, output_serial, channel_count * frames) ;
			exit (1) ;
			} ;
		} ;

	puts ("ok") ;

	return ;
} /* callback_test */
Exemplo n.º 4
0
static void
simple_test (int converter, int channel_count, double target_snr)
{	SRC_DATA	src_data ;

	double	freq, snr ;
	int		ch, error, frames ;

	printf ("\t%-22s (%d channel%c) ............. ", "simple_test", channel_count, channel_count > 1 ? 's' : ' ') ;
	fflush (stdout) ;

	memset (input_serial, 0, sizeof (input_serial)) ;
	memset (input_interleaved, 0, sizeof (input_interleaved)) ;
	memset (output_interleaved, 0, sizeof (output_interleaved)) ;
	memset (output_serial, 0, sizeof (output_serial)) ;

	frames = MIN (ARRAY_LEN (input_serial) / channel_count, 1 << 16) ;

	/* Calculate channel_count separate windowed sine waves. */
	for (ch = 0 ; ch < channel_count ; ch++)
	{	freq = (200.0 + 33.333333333 * ch) / 44100.0 ;
		gen_windowed_sines (1, &freq, 1.0, input_serial + ch * frames, frames) ;
		} ;

	/* Interleave the data in preparation for SRC. */
	interleave_data (input_serial, input_interleaved, frames, channel_count) ;

	/* Choose a converstion ratio <= 1.0. */
	src_data.src_ratio = 0.95 ;

	src_data.data_in = input_interleaved ;
	src_data.input_frames = frames ;

	src_data.data_out = output_interleaved ;
	src_data.output_frames = frames ;

	if ((error = src_simple (&src_data, converter, channel_count)))
	{	printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
		exit (1) ;
		} ;

	if (fabs (src_data.output_frames_gen - src_data.src_ratio * src_data.input_frames) > 2)
	{	printf ("\n\nLine %d : bad output data length %ld should be %d.\n", __LINE__,
					src_data.output_frames_gen, (int) floor (src_data.src_ratio * src_data.input_frames)) ;
		printf ("\tsrc_ratio  : %.4f\n", src_data.src_ratio) ;
		printf ("\tinput_len  : %ld\n", src_data.input_frames) ;
		printf ("\toutput_len : %ld\n\n", src_data.output_frames_gen) ;
		exit (1) ;
		} ;

	/* De-interleave data so SNR can be calculated for each channel. */
	deinterleave_data (output_interleaved, output_serial, frames, channel_count) ;

	for (ch = 0 ; ch < channel_count ; ch++)
	{	snr = calculate_snr (output_serial + ch * frames, frames, 1) ;
		if (snr < target_snr)
		{	printf ("\n\nLine %d: channel %d snr %f should be %f\n", __LINE__, ch, snr, target_snr) ;
			save_oct_float ("output.dat", input_serial, channel_count * frames, output_serial, channel_count * frames) ;
			exit (1) ;
			} ;
		} ;

	puts ("ok") ;

	return ;
} /* simple_test */
Exemplo n.º 5
0
static void
process_test (int converter, int channel_count, double target_snr)
{	SRC_STATE	*src_state ;
	SRC_DATA	src_data ;

	double	freq, snr ;
	int		ch, error, frames, current_in, current_out ;

	printf ("\t%-22s (%d channel%c) ............. ", "process_test", channel_count, channel_count > 1 ? 's' : ' ') ;
	fflush (stdout) ;

	memset (input_serial, 0, sizeof (input_serial)) ;
	memset (input_interleaved, 0, sizeof (input_interleaved)) ;
	memset (output_interleaved, 0, sizeof (output_interleaved)) ;
	memset (output_serial, 0, sizeof (output_serial)) ;

	frames = MIN (ARRAY_LEN (input_serial) / channel_count, 1 << 16) ;

	/* Calculate channel_count separate windowed sine waves. */
	for (ch = 0 ; ch < channel_count ; ch++)
	{	freq = (200.0 + 33.333333333 * ch) / 44100.0 ;
		gen_windowed_sines (1, &freq, 1.0, input_serial + ch * frames, frames) ;
		} ;

	/* Interleave the data in preparation for SRC. */
	interleave_data (input_serial, input_interleaved, frames, channel_count) ;

	/* Perform sample rate conversion. */
	if ((src_state = src_new (converter, channel_count, &error)) == NULL)
	{	printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
		exit (1) ;
		} ;

	src_data.end_of_input = 0 ; /* Set this later. */

	/* Choose a converstion ratio < 1.0. */
	src_data.src_ratio = 0.95 ;

	src_data.data_in = input_interleaved ;
	src_data.data_out = output_interleaved ;

	current_in = current_out = 0 ;

	while (1)
	{	src_data.input_frames	= MAX (MIN (BLOCK_LEN, frames - current_in), 0) ;
		src_data.output_frames	= MAX (MIN (BLOCK_LEN, frames - current_out), 0) ;

		if ((error = src_process (src_state, &src_data)))
		{	printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
			exit (1) ;
			} ;

		if (src_data.end_of_input && src_data.output_frames_gen == 0)
			break ;

		current_in	+= src_data.input_frames_used ;
		current_out += src_data.output_frames_gen ;

		src_data.data_in	+= src_data.input_frames_used * channel_count ;
		src_data.data_out	+= src_data.output_frames_gen * channel_count ;

		src_data.end_of_input = (current_in >= frames) ? 1 : 0 ;
		} ;

	src_state = src_delete (src_state) ;

	if (fabs (current_out - src_data.src_ratio * current_in) > 2)
	{	printf ("\n\nLine %d : bad output data length %d should be %d.\n", __LINE__,
					current_out, (int) floor (src_data.src_ratio * current_in)) ;
		printf ("\tsrc_ratio  : %.4f\n", src_data.src_ratio) ;
		printf ("\tinput_len  : %d\n", frames) ;
		printf ("\toutput_len : %d\n\n", current_out) ;
		exit (1) ;
		} ;

	/* De-interleave data so SNR can be calculated for each channel. */
	deinterleave_data (output_interleaved, output_serial, frames, channel_count) ;

	for (ch = 0 ; ch < channel_count ; ch++)
	{	snr = calculate_snr (output_serial + ch * frames, frames, 1) ;
		if (snr < target_snr)
		{	printf ("\n\nLine %d: channel %d snr %f should be %f\n", __LINE__, ch, snr, target_snr) ;
			save_oct_float ("output.dat", input_serial, channel_count * frames, output_serial, channel_count * frames) ;
			exit (1) ;
			} ;
		} ;

	puts ("ok") ;

	return ;
} /* process_test */