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 */