ref: 292789aff835d134cd3764194a7f2e2603a3766c
parent: 945b9939d296c939385fbecfc762c4c335f73dfe
author: Peter Hoyes <[email protected]>
date: Tue Oct 24 20:20:34 EDT 2017
src_clone: Test, documentation and export definitions Signed-off-by: Erik de Castro Lopo <[email protected]>
--- 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 ;
} @[email protected];
+
+@[email protected]
+{
+ global:
+ src_clone ;
+} @[email protected];
--- /dev/null
+++ b/tests/clone_test.c
@@ -1,0 +1,125 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <[email protected]>
+** 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 */