shithub: libsamplerate

Download patch

ref: ee04582dff89592efbd9b2051f061ffc7f63e8cc
parent: 30547e240fa54cff470ad152e01e749a466603bf
author: Alexander Grund <alexander.grund@tu-dresden.de>
date: Tue Aug 27 05:14:10 EDT 2019

Replace buggy implementationg of Duffs device by regular loop

Duffs device would have required to put the `switch` outside the loop
However using a regular loop modern-ish compilers produce faster code
resulting in up to 2x speedup

--- a/src/src_sinc.c
+++ b/src/src_sinc.c
@@ -906,7 +906,7 @@
 	/* The following line is 1999 ISO Standard C. If your compiler complains, get a better compiler. */
 	double		*left, *right ;
 	increment_t	filter_index, max_filter_index ;
-	int			data_index, coeff_count, indx, ch ;
+	int			data_index, coeff_count, indx ;
 
 	left = filter->left_calc ;
 	right = filter->right_calc ;
@@ -929,49 +929,10 @@
 		icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
 
 		if (data_index >= 0) /* Avoid underflow access to filter->buffer. */
-		{	/*
-			**	Duff's Device.
-			**	See : http://en.wikipedia.org/wiki/Duff's_device
-			*/
-			assert (data_index >= 0 && data_index + channels - 1 < filter->b_len) ;
+		{	assert (data_index >= 0 && data_index + channels - 1 < filter->b_len) ;
 			assert (data_index + channels - 1 < filter->b_end) ;
-			ch = channels ;
-			do
-			{	switch (ch % 8)
-				{	default :
-						ch -- ;
-						left [ch] += icoeff * filter->buffer [data_index + ch] ;
-						/* Falls through. */
-					case 7 :
-						ch -- ;
-						left [ch] += icoeff * filter->buffer [data_index + ch] ;
-						/* Falls through. */
-					case 6 :
-						ch -- ;
-						left [ch] += icoeff * filter->buffer [data_index + ch] ;
-						/* Falls through. */
-					case 5 :
-						ch -- ;
-						left [ch] += icoeff * filter->buffer [data_index + ch] ;
-						/* Falls through. */
-					case 4 :
-						ch -- ;
-						left [ch] += icoeff * filter->buffer [data_index + ch] ;
-						/* Falls through. */
-					case 3 :
-						ch -- ;
-						left [ch] += icoeff * filter->buffer [data_index + ch] ;
-						/* Falls through. */
-					case 2 :
-						ch -- ;
-						left [ch] += icoeff * filter->buffer [data_index + ch] ;
-						/* Falls through. */
-					case 1 :
-						ch -- ;
-						left [ch] += icoeff * filter->buffer [data_index + ch] ;
-					} ;
-				}
-			while (ch > 0) ;
+			for (int ch = 0; ch < channels; ch++)
+				left [ch] += icoeff * filter->buffer [data_index + ch] ;
 			} ;
 
 		filter_index -= increment ;
@@ -993,44 +954,8 @@
 		icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
 		assert (data_index >= 0 && data_index + channels - 1 < filter->b_len) ;
 		assert (data_index + channels - 1 < filter->b_end) ;
-		ch = channels ;
-		do
-		{
-			switch (ch % 8)
-			{	default :
-					ch -- ;
-					right [ch] += icoeff * filter->buffer [data_index + ch] ;
-					/* Falls through. */
-				case 7 :
-					ch -- ;
-					right [ch] += icoeff * filter->buffer [data_index + ch] ;
-					/* Falls through. */
-				case 6 :
-					ch -- ;
-					right [ch] += icoeff * filter->buffer [data_index + ch] ;
-					/* Falls through. */
-				case 5 :
-					ch -- ;
-					right [ch] += icoeff * filter->buffer [data_index + ch] ;
-					/* Falls through. */
-				case 4 :
-					ch -- ;
-					right [ch] += icoeff * filter->buffer [data_index + ch] ;
-					/* Falls through. */
-				case 3 :
-					ch -- ;
-					right [ch] += icoeff * filter->buffer [data_index + ch] ;
-					/* Falls through. */
-				case 2 :
-					ch -- ;
-					right [ch] += icoeff * filter->buffer [data_index + ch] ;
-					/* Falls through. */
-				case 1 :
-					ch -- ;
-					right [ch] += icoeff * filter->buffer [data_index + ch] ;
-				} ;
-			}
-		while (ch > 0) ;
+		for (int ch = 0; ch < channels; ch++)
+			right [ch] += icoeff * filter->buffer [data_index + ch] ;
 
 		filter_index -= increment ;
 		data_index = data_index - channels ;
@@ -1037,44 +962,8 @@
 		}
 	while (filter_index > MAKE_INCREMENT_T (0)) ;
 
-	ch = channels ;
-	do
-	{
-		switch (ch % 8)
-		{	default :
-				ch -- ;
-				output [ch] = (float) (scale * (left [ch] + right [ch])) ;
-				/* Falls through. */
-			case 7 :
-				ch -- ;
-				output [ch] = (float) (scale * (left [ch] + right [ch])) ;
-				/* Falls through. */
-			case 6 :
-				ch -- ;
-				output [ch] = (float) (scale * (left [ch] + right [ch])) ;
-				/* Falls through. */
-			case 5 :
-				ch -- ;
-				output [ch] = (float) (scale * (left [ch] + right [ch])) ;
-				/* Falls through. */
-			case 4 :
-				ch -- ;
-				output [ch] = (float) (scale * (left [ch] + right [ch])) ;
-				/* Falls through. */
-			case 3 :
-				ch -- ;
-				output [ch] = (float) (scale * (left [ch] + right [ch])) ;
-				/* Falls through. */
-			case 2 :
-				ch -- ;
-				output [ch] = (float) (scale * (left [ch] + right [ch])) ;
-				/* Falls through. */
-			case 1 :
-				ch -- ;
-				output [ch] = (float) (scale * (left [ch] + right [ch])) ;
-			} ;
-		}
-	while (ch > 0) ;
+	for(int ch = 0; ch < channels; ch++)
+		output [ch] = (float) (scale * (left [ch] + right [ch])) ;
 
 	return ;
 } /* calc_output_multi */