shithub: libsamplerate

Download patch

ref: 292789aff835d134cd3764194a7f2e2603a3766c
parent: 945b9939d296c939385fbecfc762c4c335f73dfe
author: Peter Hoyes <pahoyes@gmail.com>
date: Tue Oct 24 20:20:34 EDT 2017

src_clone: Test, documentation and export definitions

Signed-off-by: Erik de Castro Lopo <erikd@mega-nerd.com>

--- a/Makefile.am
+++ b/Makefile.am
@@ -81,11 +81,13 @@
 check_PROGRAMS += tests/misc_test tests/termination_test tests/simple_test tests/callback_test \
 	tests/reset_test tests/multi_channel_test tests/snr_bw_test tests/float_short_test \
 	tests/varispeed_test tests/callback_hang_test tests/src-evaluate tests/throughput_test \
-	tests/multichan_throughput_test tests/downsample_test
+	tests/multichan_throughput_test tests/downsample_test tests/clone_test
 TESTS = tests/misc_test tests/termination_test tests/callback_hang_test tests/downsample_test \
-	tests/simple_test tests/callback_test tests/reset_test tests/multi_channel_test \
-	tests/varispeed_test tests/float_short_test tests/snr_bw_test tests/throughput_test
+	tests/simple_test tests/callback_test tests/reset_test tests/clone_test \
+	tests/multi_channel_test tests/varispeed_test tests/float_short_test tests/snr_bw_test \
+	tests/throughput_test
 
+
 #===============================================================================
 
 tests_misc_test_SOURCES = tests/misc_test.c tests/util.c tests/util.h
@@ -123,6 +125,9 @@
 tests_varispeed_test_SOURCES = tests/varispeed_test.c tests/util.c tests/util.h tests/calc_snr.c
 tests_varispeed_test_CFLAGS = $(FFTW3_CFLAGS)
 tests_varispeed_test_LDADD = src/libsamplerate.la $(FFTW3_LIBS)
+
+tests_clone_test_SOURCES = tests/clone_test.c tests/util.c tests/util.h
+tests_clone_test_LDADD = src/libsamplerate.la
 
 # This program is for evaluating other sample rate converters.
 
--- a/Win32/Makefile.mingw.in
+++ b/Win32/Makefile.mingw.in
@@ -106,6 +106,7 @@
      tests/simple_test.exe \
 	 tests/callback_test.exe \
      tests/reset_test.exe \
+     tests/clone_test.exe \
      tests/multi_channel_test.exe \
 	 tests/float_short_test.exe \
      tests/snr_bw_test.exe
@@ -117,6 +118,7 @@
 	tests/simple_test.exe
 	tests/callback_test.exe
 	tests/reset_test.exe
+	tests/clone_test.exe
 	tests/multi_channel_test.exe
 	tests/float_short_test.exe
 	tests/snr_bw_test.exe
@@ -140,6 +142,9 @@
 	$(CC) $(CFLAGS) $+ -o $@
 
 tests/reset_test.exe : tests/reset_test.c tests/util.c libsamplerate.lib
+	$(CC) $(CFLAGS) $+ -o $@
+
+tests/clone_test.exe : tests/clone_test.c tests/util.c libsamplerate.lib
 	$(CC) $(CFLAGS) $+ -o $@
 
 tests/float_short_test.exe : tests/float_short_test.c tests/util.c libsamplerate.lib
--- a/Win32/Makefile.msvc
+++ b/Win32/Makefile.msvc
@@ -51,6 +51,7 @@
     ".\tests\termination_test.exe" \
     ".\tests\simple_test.exe" \
     ".\tests\reset_test.exe" \
+    ".\tests\clone_test.exe" \
     ".\tests\multi_channel_test.exe" \
     ".\tests\snr_bw_test.exe" \
 	".\tests\throughput_test.exe"
@@ -60,6 +61,7 @@
      ".\tests\termination_test.exe"
      ".\tests\simple_test.exe"
      ".\tests\reset_test.exe"
+     ".\tests\clone_test.exe"
      ".\tests\multi_channel_test.exe"
      ".\tests\snr_bw_test.exe"
 	 ".\tests\throughput_test.exe"
@@ -116,6 +118,10 @@
 ".\tests\reset_test.exe" : ".\tests\reset_test.c" ".\tests\util.obj"
     $(CPP) $(CFLAGS) /Fo".\tests\reset_test.obj" /c ".\tests\reset_test.c"
     $(LINK32) $(PROG_LINK_FLAGS) /out:".\tests\reset_test.exe" ".\tests\reset_test.obj" ".\tests\util.obj" libsamplerate-0.lib
+
+".\tests\clone_test.exe" : ".\tests\clone_test.c" ".\tests\util.obj"
+    $(CPP) $(CFLAGS) /Fo".\tests\clone_test.obj" /c ".\tests\clone_test.c"
+    $(LINK32) $(PROG_LINK_FLAGS) /out:".\tests\clone_test.exe" ".\tests\clone_test.obj" ".\tests\util.obj" libsamplerate-0.lib
 
 ".\tests\multi_channel_test.exe" : ".\tests\multi_channel_test.c" ".\tests\util.obj" ".\tests\calc_snr.obj"
     $(CPP) $(CFLAGS) /Fo".\tests\multi_channel_test.obj" /c ".\tests\multi_channel_test.c"
--- a/Win32/libsamplerate-0.def
+++ b/Win32/libsamplerate-0.def
@@ -11,6 +11,7 @@
 src_process				@20
 src_reset				@21
 src_set_ratio			@22
+src_clone				@23
 
 src_error				@30
 src_strerror			@31
--- a/doc/api_full.html
+++ b/doc/api_full.html
@@ -164,6 +164,24 @@
 separate, unrelated pieces of audio.
 </P>
 
+<A NAME="Clone"></A>
+<H3><BR>Clone</H3>
+<PRE>
+      SRC_STATE* src_clone (SRC_STATE *state, int *error) ;
+</PRE>
+<P>
+The <B>src_clone</B> function creates a copy of the internal state of the sample
+rate converter object. The output of the next call to <B>src_process</B> will be
+identical for both the original and cloned state (given the same <B>SRC_DATA</B>
+input). This could be used to later resume sample rate conversion at a specific
+location in a stream with the same state, which may be useful in real-time
+applications.
+</P>
+<P>
+If an error occurs the function returns a NULL pointer and fills in the
+error value pointed to by the <B>error</B> pointer supplied by the caller.
+</P>
+
 <A NAME="SetRatio"></A>
 <H3><BR>Set Ratio</H3>
 <PRE>
--- a/src/Version_script.in
+++ b/src/Version_script.in
@@ -37,3 +37,9 @@
 		src_float_to_int_array ;
 		src_get_channels ;
 } @PACKAGE@.so.0.0;
+
+@PACKAGE@.so.0.2
+{
+	global:
+		src_clone ;
+} @PACKAGE@.so.0.1;
--- /dev/null
+++ b/tests/clone_test.c
@@ -1,0 +1,125 @@
+/*
+** Copyright (c) 2002-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 <samplerate.h>
+
+#include "util.h"
+
+#define	BUFFER_LEN		(1 << 16)
+#define NUM_CHANNELS 	2
+#define FRAMES_PER_PASS (BUFFER_LEN >> 1)
+
+static void
+clone_test (int converter)
+{	static float input_serial [BUFFER_LEN * NUM_CHANNELS], input_interleaved [BUFFER_LEN * NUM_CHANNELS] ;
+	static float output [BUFFER_LEN * NUM_CHANNELS], output_cloned [BUFFER_LEN * NUM_CHANNELS] ;
+	double sine_freq ;
+
+	SRC_STATE* src_state ;
+	SRC_STATE* src_state_cloned ;
+	SRC_DATA src_data, src_data_cloned ;
+
+	int error, frame, ch, index ;
+
+	printf ("        clone_test     (%-28s) ....... ", src_get_name (converter)) ;
+	fflush (stdout) ;
+
+	memset (input_serial, 0, sizeof (input_serial)) ;
+	memset (input_interleaved, 0, sizeof (input_interleaved)) ;
+	memset (output, 0, sizeof (output)) ;
+	memset (output_cloned, 0, sizeof (output_cloned)) ;
+
+	/* Fill input buffer with an n-channel interleaved sine wave */
+	sine_freq = 0.0111 ;
+	gen_windowed_sines (1, &sine_freq, 1.0, input_serial, BUFFER_LEN) ;
+	gen_windowed_sines (1, &sine_freq, 1.0, input_serial + BUFFER_LEN, BUFFER_LEN) ;
+	interleave_data (input_serial, input_interleaved, BUFFER_LEN, NUM_CHANNELS) ;
+
+	if ((src_state = src_new (converter, NUM_CHANNELS, &error)) == NULL)
+	{	printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
+		exit (1) ;
+		} ;
+
+	/* Perform initial pass using first half of buffer so that src_state has non-trivial state */
+	src_data.src_ratio = 1.1 ;
+	src_data.input_frames = FRAMES_PER_PASS ;
+	src_data.output_frames = FRAMES_PER_PASS ;
+	src_data.data_in = input_interleaved ;
+	src_data.data_out = output ;
+	src_data.output_frames_gen = 0 ;
+
+	if ((error = src_process (src_state, &src_data)))
+	{	printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+		printf ("  src_data.input_frames  : %ld\n", src_data.input_frames) ;
+		printf ("  src_data.output_frames : %ld\n\n", src_data.output_frames) ;
+		exit (1) ;
+		} ;
+
+	/* Clone handle */
+	if ((src_state_cloned = src_clone (src_state, &error)) == NULL)
+	{	printf ("\n\nLine %d : src_clone() failed : %s\n\n", __LINE__, src_strerror (error)) ;
+		exit (1) ;
+		} ;
+
+	/* Process second half of buffer with both handles */
+	src_data.data_in = input_interleaved + FRAMES_PER_PASS ;
+
+	src_data_cloned = src_data ;
+	src_data_cloned.data_out = output_cloned ;
+
+	if ((error = src_process (src_state, &src_data)))
+	{	printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+		printf ("  src_data.input_frames  : %ld\n", src_data.input_frames) ;
+		printf ("  src_data.output_frames : %ld\n\n", src_data.output_frames) ;
+		exit (1) ;
+		} ;
+
+	if ((error = src_process (src_state_cloned, &src_data_cloned)))
+	{	printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+		printf ("  src_data.input_frames  : %ld\n", src_data.input_frames) ;
+		printf ("  src_data.output_frames : %ld\n\n", src_data.output_frames) ;
+		exit (1) ;
+		} ;
+
+	/* Check that both handles generated the same number of output frames */
+	if (src_data.output_frames_gen != src_data_cloned.output_frames_gen)
+	{	printf ("\n\nLine %d : cloned output_frames_gen (%ld) != original (%ld)\n\n", __LINE__,
+				src_data_cloned.output_frames_gen, src_data.output_frames_gen) ;
+		exit (1) ;
+		} ;
+
+	for (ch = 0 ; ch < NUM_CHANNELS ; ch++)
+	{	for (frame = 0 ; frame < src_data.output_frames_gen ; frame++)
+		{	index = ch * NUM_CHANNELS + ch ;
+			if (output [index] != output_cloned [index])
+			{	printf ("\n\nLine %d : cloned data does not equal original data at channel %d, frame %d\n\n",
+						__LINE__, ch, frame) ;
+				exit (1) ;
+				} ;
+			} ;
+		} ;
+
+	src_state = src_delete (src_state) ;
+	src_state_cloned = src_delete (src_state_cloned) ;
+
+	puts ("ok") ;
+} /* clone_test */
+
+int
+main (void)
+{
+	clone_test (SRC_ZERO_ORDER_HOLD) ;
+	clone_test (SRC_LINEAR) ;
+	clone_test (SRC_SINC_FASTEST) ;
+
+	return 0 ;
+} /* main */