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
Unified · Split
| @@ -906,7 +906,7 @@ calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start · 905 unmodified lines | |||
| 906 | /* The following line is 1999 ISO Standard C. If your compiler complains, get a better compiler. */ | 906 | /* The following line is 1999 ISO Standard C. If your compiler complains, get a better compiler. */ |
| 907 | double *left, *right ; | 907 | double *left, *right ; |
| 908 | increment_t filter_index, max_filter_index ; | 908 | increment_t filter_index, max_filter_index ; |
| 909 | int data_index, coeff_count, indx, ch ; | 909 | int data_index, coeff_count, indx ; |
| 910 | 910 | ||
| 911 | left = filter->left_calc ; | 911 | left = filter->left_calc ; |
| 912 | right = filter->right_calc ; | 912 | right = filter->right_calc ; |
| @@ -929,49 +929,10 @@ calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start · 16 unmodified lines | |||
| 929 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; | 929 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; |
| 930 | 930 | ||
| 931 | if (data_index >= 0) /* Avoid underflow access to filter->buffer. */ | 931 | if (data_index >= 0) /* Avoid underflow access to filter->buffer. */ |
| 932 | { /* | 932 | { assert (data_index >= 0 && data_index + channels - 1 < filter->b_len) ; |
| 933 | ** Duff's Device. | ||
| 934 | ** See : http://en.wikipedia.org/wiki/Duff's_device | ||
| 935 | */ | ||
| 936 | assert (data_index >= 0 && data_index + channels - 1 < filter->b_len) ; | ||
| 937 | assert (data_index + channels - 1 < filter->b_end) ; | 933 | assert (data_index + channels - 1 < filter->b_end) ; |
| 938 | ch = channels ; | 934 | for (int ch = 0; ch < channels; ch++) |
| 939 | do | 935 | left [ch] += icoeff * filter->buffer [data_index + ch] ; |
| 940 | { switch (ch % 8) | ||
| 941 | { default : | ||
| 942 | ch -- ; | ||
| 943 | left [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 944 | /* Falls through. */ | ||
| 945 | case 7 : | ||
| 946 | ch -- ; | ||
| 947 | left [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 948 | /* Falls through. */ | ||
| 949 | case 6 : | ||
| 950 | ch -- ; | ||
| 951 | left [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 952 | /* Falls through. */ | ||
| 953 | case 5 : | ||
| 954 | ch -- ; | ||
| 955 | left [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 956 | /* Falls through. */ | ||
| 957 | case 4 : | ||
| 958 | ch -- ; | ||
| 959 | left [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 960 | /* Falls through. */ | ||
| 961 | case 3 : | ||
| 962 | ch -- ; | ||
| 963 | left [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 964 | /* Falls through. */ | ||
| 965 | case 2 : | ||
| 966 | ch -- ; | ||
| 967 | left [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 968 | /* Falls through. */ | ||
| 969 | case 1 : | ||
| 970 | ch -- ; | ||
| 971 | left [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 972 | } ; | ||
| 973 | } | ||
| 974 | while (ch > 0) ; | ||
| 975 | } ; | 936 | } ; |
| 976 | 937 | ||
| 977 | filter_index -= increment ; | 938 | filter_index -= increment ; |
| @@ -993,88 +954,16 @@ calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start · 15 unmodified lines | |||
| 993 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; | 954 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; |
| 994 | assert (data_index >= 0 && data_index + channels - 1 < filter->b_len) ; | 955 | assert (data_index >= 0 && data_index + channels - 1 < filter->b_len) ; |
| 995 | assert (data_index + channels - 1 < filter->b_end) ; | 956 | assert (data_index + channels - 1 < filter->b_end) ; |
| 996 | ch = channels ; | 957 | for (int ch = 0; ch < channels; ch++) |
| 997 | do | 958 | right [ch] += icoeff * filter->buffer [data_index + ch] ; |
| 998 | { | ||
| 999 | switch (ch % 8) | ||
| 1000 | { default : | ||
| 1001 | ch -- ; | ||
| 1002 | right [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 1003 | /* Falls through. */ | ||
| 1004 | case 7 : | ||
| 1005 | ch -- ; | ||
| 1006 | right [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 1007 | /* Falls through. */ | ||
| 1008 | case 6 : | ||
| 1009 | ch -- ; | ||
| 1010 | right [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 1011 | /* Falls through. */ | ||
| 1012 | case 5 : | ||
| 1013 | ch -- ; | ||
| 1014 | right [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 1015 | /* Falls through. */ | ||
| 1016 | case 4 : | ||
| 1017 | ch -- ; | ||
| 1018 | right [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 1019 | /* Falls through. */ | ||
| 1020 | case 3 : | ||
| 1021 | ch -- ; | ||
| 1022 | right [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 1023 | /* Falls through. */ | ||
| 1024 | case 2 : | ||
| 1025 | ch -- ; | ||
| 1026 | right [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 1027 | /* Falls through. */ | ||
| 1028 | case 1 : | ||
| 1029 | ch -- ; | ||
| 1030 | right [ch] += icoeff * filter->buffer [data_index + ch] ; | ||
| 1031 | } ; | ||
| 1032 | } | ||
| 1033 | while (ch > 0) ; | ||
| 1034 | 959 | ||
| 1035 | filter_index -= increment ; | 960 | filter_index -= increment ; |
| 1036 | data_index = data_index - channels ; | 961 | data_index = data_index - channels ; |
| 1037 | } | 962 | } |
| 1038 | while (filter_index > MAKE_INCREMENT_T (0)) ; | 963 | while (filter_index > MAKE_INCREMENT_T (0)) ; |
| 1039 | 964 | ||
| 1040 | ch = channels ; | 965 | for(int ch = 0; ch < channels; ch++) |
| 1041 | do | 966 | output [ch] = (float) (scale * (left [ch] + right [ch])) ; |
| 1042 | { | ||
| 1043 | switch (ch % 8) | ||
| 1044 | { default : | ||
| 1045 | ch -- ; | ||
| 1046 | output [ch] = (float) (scale * (left [ch] + right [ch])) ; | ||
| 1047 | /* Falls through. */ | ||
| 1048 | case 7 : | ||
| 1049 | ch -- ; | ||
| 1050 | output [ch] = (float) (scale * (left [ch] + right [ch])) ; | ||
| 1051 | /* Falls through. */ | ||
| 1052 | case 6 : | ||
| 1053 | ch -- ; | ||
| 1054 | output [ch] = (float) (scale * (left [ch] + right [ch])) ; | ||
| 1055 | /* Falls through. */ | ||
| 1056 | case 5 : | ||
| 1057 | ch -- ; | ||
| 1058 | output [ch] = (float) (scale * (left [ch] + right [ch])) ; | ||
| 1059 | /* Falls through. */ | ||
| 1060 | case 4 : | ||
| 1061 | ch -- ; | ||
| 1062 | output [ch] = (float) (scale * (left [ch] + right [ch])) ; | ||
| 1063 | /* Falls through. */ | ||
| 1064 | case 3 : | ||
| 1065 | ch -- ; | ||
| 1066 | output [ch] = (float) (scale * (left [ch] + right [ch])) ; | ||
| 1067 | /* Falls through. */ | ||
| 1068 | case 2 : | ||
| 1069 | ch -- ; | ||
| 1070 | output [ch] = (float) (scale * (left [ch] + right [ch])) ; | ||
| 1071 | /* Falls through. */ | ||
| 1072 | case 1 : | ||
| 1073 | ch -- ; | ||
| 1074 | output [ch] = (float) (scale * (left [ch] + right [ch])) ; | ||
| 1075 | } ; | ||
| 1076 | } | ||
| 1077 | while (ch > 0) ; | ||
| 1078 | 967 | ||
| 1079 | return ; | 968 | return ; |
| 1080 | } /* calc_output_multi */ | 969 | } /* calc_output_multi */ |