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 | 906 | /* The following line is 1999 ISO Standard C. If your compiler complains, get a better compiler. */ |
| 907 | 907 | double *left, *right ; |
| 908 | 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 | 911 | left = filter->left_calc ; |
| 912 | 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 | 929 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; |
| 930 | 930 | |
| 931 | 931 | if (data_index >= 0) /* Avoid underflow access to filter->buffer. */ |
| 932 | − { /* | |
| 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) ; | |
| 932 | + { assert (data_index >= 0 && data_index + channels - 1 < filter->b_len) ; | |
| 937 | 933 | assert (data_index + channels - 1 < filter->b_end) ; |
| 938 | − ch = channels ; | |
| 939 | − do | |
| 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) ; | |
| 934 | + for (int ch = 0; ch < channels; ch++) | |
| 935 | + left [ch] += icoeff * filter->buffer [data_index + ch] ; | |
| 975 | 936 | } ; |
| 976 | 937 | |
| 977 | 938 | filter_index -= increment ; |
| @@ -993,88 +954,16 @@ calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start · 15 unmodified lines | ||
| 993 | 954 | icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ; |
| 994 | 955 | assert (data_index >= 0 && data_index + channels - 1 < filter->b_len) ; |
| 995 | 956 | assert (data_index + channels - 1 < filter->b_end) ; |
| 996 | − ch = channels ; | |
| 997 | − do | |
| 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) ; | |
| 957 | + for (int ch = 0; ch < channels; ch++) | |
| 958 | + right [ch] += icoeff * filter->buffer [data_index + ch] ; | |
| 1034 | 959 | |
| 1035 | 960 | filter_index -= increment ; |
| 1036 | 961 | data_index = data_index - channels ; |
| 1037 | 962 | } |
| 1038 | 963 | while (filter_index > MAKE_INCREMENT_T (0)) ; |
| 1039 | 964 | |
| 1040 | − ch = channels ; | |
| 1041 | − do | |
| 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) ; | |
| 965 | + for(int ch = 0; ch < channels; ch++) | |
| 966 | + output [ch] = (float) (scale * (left [ch] + right [ch])) ; | |
| 1078 | 967 | |
| 1079 | 968 | return ; |
| 1080 | 969 | } /* calc_output_multi */ |