shithub: libsamplerate

Download patch

ref: e3755e2cef4c44aa630b2949f4489420edcafb4b
parent: 0bbb338f2f518e3dad30329411978b98856a3162
author: Erik de Castro Lopo <erikd@miles>
date: Tue Jun 15 05:11:08 EDT 2004

Modify sndfile-resample to restart conversion if clipping has occurred.

--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2004-06-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-resample.c
+    Modified to restart conversion if clipping has occurred.
+
 2004-06-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
 
     * tests/benchmark.c
--- a/examples/sndfile-resample.c
+++ b/examples/sndfile-resample.c
@@ -32,7 +32,8 @@
 #define	BUFFER_LEN		4096	/*-(1<<16)-*/
 
 static void usage_exit (const char *progname) ;
-static sf_count_t sample_rate_convert (SNDFILE *infile, SNDFILE *outfile, int converter, double src_ratio, int channels) ;
+static sf_count_t sample_rate_convert (SNDFILE *infile, SNDFILE *outfile, int converter, double src_ratio, int channels, double * gain) ;
+static double apply_gain (float * data, long frames, int channels, double max, double gain) ;
 
 int
 main (int argc, char *argv [])
@@ -40,7 +41,7 @@
 	SF_INFO sfinfo ;
 
 	sf_count_t	count ;
-	double		src_ratio = -1.0 ;
+	double		src_ratio = -1.0, gain = 1.0 ;
 	int			new_sample_rate = -1, k, converter, max_speed = SF_FALSE ;
 
 	if (argc == 2 && strcmp (argv [1], "--version") == 0)
@@ -150,7 +151,9 @@
 	printf ("Output file   : %s\n", argv [argc - 1]) ;
 	printf ("Sample Rate   : %d\n", sfinfo.samplerate) ;
 
-	count = sample_rate_convert (infile, outfile, converter, src_ratio, sfinfo.channels) ;
+	do
+		count = sample_rate_convert (infile, outfile, converter, src_ratio, sfinfo.channels, &gain) ;
+	while (count < 0) ;
 
 	printf ("Output Frames : %ld\n\n", (long) count) ;
 
@@ -164,7 +167,7 @@
 */
 
 static sf_count_t
-sample_rate_convert (SNDFILE *infile, SNDFILE *outfile, int converter, double src_ratio, int channels)
+sample_rate_convert (SNDFILE *infile, SNDFILE *outfile, int converter, double src_ratio, int channels, double * gain)
 {	static float input [BUFFER_LEN] ;
 	static float output [BUFFER_LEN] ;
 
@@ -171,6 +174,7 @@
 	SRC_STATE	*src_state ;
 	SRC_DATA	src_data ;
 	int			error ;
+	double		max = 0.0 ;
 	sf_count_t	output_count = 0 ;
 
 	sf_seek (infile, 0, SEEK_SET) ;
@@ -214,6 +218,8 @@
 		if (src_data.end_of_input && src_data.output_frames_gen == 0)
 			break ;
 
+		max = apply_gain (src_data.data_out, src_data.output_frames_gen, channels, max, *gain) ;
+
 		/* Write output. */
 		sf_writef_float (outfile, output, src_data.output_frames_gen) ;
 		output_count += src_data.output_frames_gen ;
@@ -224,9 +230,29 @@
 
 	src_state = src_delete (src_state) ;
 
+	if (max > 1.0)
+	{	*gain = 1.0 / max ;
+		printf ("\nOutput has clipped. Restarting conversion to prevent clipping.\n\n") ;
+		return -1 ;
+		} ;
+
 	return output_count ;
 } /* sample_rate_convert */
 
+static double
+apply_gain (float * data, long frames, int channels, double max, double gain)
+{
+	long k ;
+
+	for (k = 0 ; k < frames * channels ; k++)
+	{	data [k] *= gain ;
+
+		if (fabs (data [k]) > max)
+			max = fabs (data [k]) ;
+		} ;
+
+	return max ;
+} /* apply_gain */
 
 static void
 usage_exit (const char *progname)