| @@ -921,7 +921,7 @@ float tMBPulse_tick(tMBPulse* const osc) · 920 unmodified lines |
| 921 | 921 | |
| 922 | 922 | int j, k; |
| 923 | 923 | float freq, syncin; |
| 924 | | − float a, b, db, p, t, w, dw, x, z; |
| 924 | + float a, b, db, p, tw, tb, w, dw, x, z; |
| 925 | 925 | |
| 926 | 926 | syncin = c->syncin; |
| 927 | 927 | freq = c->freq; |
| @@ -937,11 +937,21 @@ float tMBPulse_tick(tMBPulse* const osc) · 9 unmodified lines |
| 937 | 937 | p = 0.0f; |
| 938 | 938 | |
| 939 | 939 | w = freq / leaf->sampleRate; |
| 940 | | − if (w < 1e-5f) w = 1e-5f; |
| 941 | | − if (w > 0.5f) w = 0.5f; |
| 942 | 940 | b = 0.5f * (1.0f + c->waveform ); |
| 943 | | − if (b < w) b = w; |
| 944 | | − if (b > 1.0f - w) b = 1.0f - w; |
| 941 | + if (w >= 0) |
| 942 | + { |
| 943 | + if (w < 1e-5f) w = 1e-5f; |
| 944 | + if (w > 0.5f) w = 0.5f; |
| 945 | + if (b < w) b = w; |
| 946 | + if (b > 1.0f - w) b = 1.0f - w; |
| 947 | + } |
| 948 | + else |
| 949 | + { |
| 950 | + if (w > -1e-5f) w = -1e-5f; |
| 951 | + if (w < -0.5f) w = -0.5f; |
| 952 | + if (b < -w) b = -w; |
| 953 | + if (b > 1.0f + w) b = 1.0f + w; |
| 954 | + } |
| 945 | 955 | /* for variable-width rectangular wave, we could do DC compensation with: |
| 946 | 956 | * x = 1.0f - b; |
| 947 | 957 | * but that doesn't work well with highly modulated hard sync. Instead, |
| @@ -957,14 +967,32 @@ float tMBPulse_tick(tMBPulse* const osc) · 9 unmodified lines |
| 957 | 967 | // a = 0.2 + 0.8 * vco->_port [FILT]; |
| 958 | 968 | a = 0.5f; // when a = 1, LPfilter is disabled |
| 959 | 969 | |
| 960 | | − t = freq / leaf->sampleRate; |
| 961 | | − if (t < 1e-5f) t = 1e-5f; |
| 962 | | − if (t > 0.5f) t = 0.5f; |
| 963 | | − dw = (t - w) ; |
| 964 | | − t = 0.5f * (1.0f + c->waveform ); |
| 965 | | − if (t < w) t = w; |
| 966 | | − if (t > 1.0f - w) t = 1.0f - w; |
| 967 | | − db = (t - b) ; |
| 970 | + tw = freq / leaf->sampleRate; |
| 971 | + if (tw >= 0) |
| 972 | + { |
| 973 | + if (tw < 1e-5f) tw = 1e-5f; |
| 974 | + if (tw > 0.5f) tw = 0.5f; |
| 975 | + } |
| 976 | + else |
| 977 | + { |
| 978 | + if (tw > -1e-5f) tw = -1e-5f; |
| 979 | + if (tw < -0.5f) tw = -0.5f; |
| 980 | + } |
| 981 | + |
| 982 | + tb = 0.5f * (1.0f + c->waveform); |
| 983 | + if (w >= 0) |
| 984 | + { |
| 985 | + if (tb < w) tb = w; |
| 986 | + if (tb > 1.0f - w) tb = 1.0f - w; |
| 987 | + } |
| 988 | + else |
| 989 | + { |
| 990 | + if (tb < -w) tb = -w; |
| 991 | + if (tb > 1.0f + w) tb = 1.0f + w; |
| 992 | + } |
| 993 | + |
| 994 | + dw = (tw - w); |
| 995 | + db = (tb - b); |
| 968 | 996 | |
| 969 | 997 | w += dw; |
| 970 | 998 | b += db; |
| @@ -974,81 +1002,174 @@ float tMBPulse_tick(tMBPulse* const osc) · 3 unmodified lines |
| 974 | 1002 | // |
| 975 | 1003 | float eof_offset = (syncin - 1e-20f) * w; |
| 976 | 1004 | float p_at_reset = p - eof_offset; |
| 977 | | − p = eof_offset; |
| 1005 | + |
| 1006 | + if (w > 0) p = eof_offset; |
| 1007 | + else p = 1.0f - eof_offset; |
| 978 | 1008 | |
| 979 | 1009 | /* place any DDs that may have occurred in subsample before reset */ |
| 980 | 1010 | if (!k) { |
| 981 | | − if (p_at_reset >= b) { |
| 982 | | − place_step_dd(c->_f, j, p_at_reset - b + eof_offset, w, -1.0f); |
| 983 | | − k = 1; |
| 984 | | − x = -0.5f; |
| 1011 | + if (w > 0) |
| 1012 | + { |
| 1013 | + if (p_at_reset >= b) { |
| 1014 | + place_step_dd(c->_f, j, p_at_reset - b + eof_offset, w, -1.0f); |
| 1015 | + k = 1; |
| 1016 | + x = -0.5f; |
| 1017 | + } |
| 1018 | + if (p_at_reset >= 1.0f) { |
| 1019 | + p_at_reset -= 1.0f; |
| 1020 | + place_step_dd(c->_f, j, p_at_reset + eof_offset, w, 1.0f); |
| 1021 | + k = 0; |
| 1022 | + x = 0.5f; |
| 1023 | + } |
| 985 | 1024 | } |
| 986 | | − if (p_at_reset >= 1.0f) { |
| 987 | | − p_at_reset -= 1.0f; |
| 988 | | − place_step_dd(c->_f, j, p_at_reset + eof_offset, w, 1.0f); |
| 989 | | − k = 0; |
| 990 | | − x = 0.5f; |
| 1025 | + else |
| 1026 | + { |
| 1027 | + if (p_at_reset < 0.0f) { |
| 1028 | + p_at_reset += 1.0f; |
| 1029 | + place_step_dd(c->_f, j, 1.0f - p_at_reset - eof_offset, -w, -1.0f); |
| 1030 | + k = 1; |
| 1031 | + x = -0.5f; |
| 1032 | + } |
| 1033 | + if (k && p_at_reset < b) { |
| 1034 | + place_step_dd(c->_f, j, b - p_at_reset - eof_offset, -w, 1.0f); |
| 1035 | + k = 0; |
| 1036 | + x = 0.5f; |
| 1037 | + } |
| 991 | 1038 | } |
| 992 | 1039 | } else { |
| 993 | | − if (p_at_reset >= 1.0f) { |
| 994 | | − p_at_reset -= 1.0f; |
| 995 | | − place_step_dd(c->_f, j, p_at_reset + eof_offset, w, 1.0f); |
| 1040 | + if (w > 0) |
| 1041 | + { |
| 1042 | + if (p_at_reset >= 1.0f) { |
| 1043 | + p_at_reset -= 1.0f; |
| 1044 | + place_step_dd(c->_f, j, p_at_reset + eof_offset, w, 1.0f); |
| 1045 | + k = 0; |
| 1046 | + x = 0.5f; |
| 1047 | + } |
| 1048 | + if (!k && p_at_reset >= b) { |
| 1049 | + place_step_dd(c->_f, j, p_at_reset - b + eof_offset, w, -1.0f); |
| 1050 | + k = 1; |
| 1051 | + x = -0.5f; |
| 1052 | + } |
| 1053 | + } |
| 1054 | + else |
| 1055 | + { |
| 1056 | + if (p_at_reset < b) { |
| 1057 | + place_step_dd(c->_f, j, b - p_at_reset - eof_offset, -w, 1.0f); |
| 1058 | + k = 0; |
| 1059 | + x = 0.5f; |
| 1060 | + } |
| 1061 | + if (p_at_reset < 0.0f) { |
| 1062 | + p_at_reset += 1.0f; |
| 1063 | + place_step_dd(c->_f, j, 1.0f - p_at_reset - eof_offset, -w, -1.0f); |
| 1064 | + k = 1; |
| 1065 | + x = -0.5f; |
| 1066 | + } |
| 1067 | + } |
| 1068 | + } |
| 1069 | + |
| 1070 | + /* now place reset DD */ |
| 1071 | + if (w > 0) |
| 1072 | + { |
| 1073 | + if (k) { |
| 1074 | + place_step_dd(c->_f, j, p, w, 1.0f); |
| 996 | 1075 | k = 0; |
| 997 | 1076 | x = 0.5f; |
| 998 | 1077 | } |
| 999 | | − if (!k && p_at_reset >= b) { |
| 1000 | | − place_step_dd(c->_f, j, p_at_reset - b + eof_offset, w, -1.0f); |
| 1078 | + if (p >= b) { |
| 1079 | + place_step_dd(c->_f, j, p - b, w, -1.0f); |
| 1001 | 1080 | k = 1; |
| 1002 | 1081 | x = -0.5f; |
| 1003 | 1082 | } |
| 1004 | 1083 | } |
| 1005 | | − |
| 1006 | | − /* now place reset DD */ |
| 1007 | | − if (k) { |
| 1008 | | − place_step_dd(c->_f, j, p, w, 1.0f); |
| 1009 | | − k = 0; |
| 1010 | | − x = 0.5f; |
| 1011 | | − } |
| 1012 | | − if (p >= b) { |
| 1013 | | − place_step_dd(c->_f, j, p - b, w, -1.0f); |
| 1014 | | − k = 1; |
| 1015 | | − x = -0.5f; |
| 1084 | + else |
| 1085 | + { |
| 1086 | + if (!k) { |
| 1087 | + place_step_dd(c->_f, j, 1.0f - p, -w, -1.0f); |
| 1088 | + k = 1; |
| 1089 | + x = -0.5f; |
| 1090 | + } |
| 1091 | + if (p < b) { |
| 1092 | + place_step_dd(c->_f, j, b - p, -w, 1.0f); |
| 1093 | + k = 0; |
| 1094 | + x = 0.5f; |
| 1095 | + } |
| 1016 | 1096 | } |
| 1017 | 1097 | |
| 1018 | 1098 | c->syncout = syncin; /* best we can do is pass on upstream sync */ |
| 1019 | 1099 | |
| 1020 | 1100 | } else if (!k) { /* normal operation, signal currently high */ |
| 1021 | 1101 | |
| 1022 | | − if (p >= b) { |
| 1023 | | − place_step_dd(c->_f, j, p - b, w, -1.0f); |
| 1024 | | − k = 1; |
| 1025 | | − x = -0.5f; |
| 1102 | + if (w > 0) |
| 1103 | + { |
| 1104 | + if (p >= b) { |
| 1105 | + place_step_dd(c->_f, j, p - b, w, -1.0f); |
| 1106 | + k = 1; |
| 1107 | + x = -0.5f; |
| 1108 | + } |
| 1109 | + if (p >= 1.0f) { |
| 1110 | + p -= 1.0f; |
| 1111 | + c->syncout = p / w + 1e-20f; |
| 1112 | + place_step_dd(c->_f, j, p, w, 1.0f); |
| 1113 | + k = 0; |
| 1114 | + x = 0.5f; |
| 1115 | + } else { |
| 1116 | + c->syncout = 0.0f; |
| 1117 | + } |
| 1026 | 1118 | } |
| 1027 | | − if (p >= 1.0f) { |
| 1028 | | − p -= 1.0f; |
| 1029 | | − c->syncout = p / w + 1e-20f; |
| 1030 | | − place_step_dd(c->_f, j, p, w, 1.0f); |
| 1031 | | − k = 0; |
| 1032 | | − x = 0.5f; |
| 1033 | | − } else { |
| 1034 | | − c->syncout = 0.0f; |
| 1119 | + else |
| 1120 | + { |
| 1121 | + if (p < 0.0f) { |
| 1122 | + p += 1.0f; |
| 1123 | + c->syncout = p / -w + 1e-20f; |
| 1124 | + place_step_dd(c->_f, j, 1.0f - p, -w, -1.0f); |
| 1125 | + k = 1; |
| 1126 | + x = -0.5f; |
| 1127 | + } else { |
| 1128 | + c->syncout = 0.0f; |
| 1129 | + } |
| 1130 | + if (k && p < b) { |
| 1131 | + place_step_dd(c->_f, j, b - p, -w, 1.0f); |
| 1132 | + k = 0; |
| 1133 | + x = 0.5f; |
| 1134 | + } |
| 1035 | 1135 | } |
| 1036 | 1136 | |
| 1037 | 1137 | } else { /* normal operation, signal currently low */ |
| 1038 | 1138 | |
| 1039 | | − if (p >= 1.0f) { |
| 1040 | | − p -= 1.0f; |
| 1041 | | − c->syncout = p / w + 1e-20f; |
| 1042 | | − place_step_dd(c->_f, j, p, w, 1.0f); |
| 1043 | | − k = 0; |
| 1044 | | − x = 0.5f; |
| 1045 | | − } else { |
| 1046 | | − c->syncout = 0.0f; |
| 1139 | + if (w > 0) |
| 1140 | + { |
| 1141 | + if (p >= 1.0f) { |
| 1142 | + p -= 1.0f; |
| 1143 | + c->syncout = p / w + 1e-20f; |
| 1144 | + place_step_dd(c->_f, j, p, w, 1.0f); |
| 1145 | + k = 0; |
| 1146 | + x = 0.5f; |
| 1147 | + } else { |
| 1148 | + c->syncout = 0.0f; |
| 1149 | + } |
| 1150 | + if (!k && p >= b) { |
| 1151 | + place_step_dd(c->_f, j, p - b, w, -1.0f); |
| 1152 | + k = 1; |
| 1153 | + x = -0.5f; |
| 1154 | + } |
| 1047 | 1155 | } |
| 1048 | | − if (!k && p >= b) { |
| 1049 | | − place_step_dd(c->_f, j, p - b, w, -1.0f); |
| 1050 | | − k = 1; |
| 1051 | | − x = -0.5f; |
| 1156 | + else |
| 1157 | + { |
| 1158 | + if (p < b) { |
| 1159 | + place_step_dd(c->_f, j, b - p, -w, 1.0f); |
| 1160 | + k = 0; |
| 1161 | + x = 0.5f; |
| 1162 | + } |
| 1163 | + if (p < 0.0f) { |
| 1164 | + p += 1.0f; |
| 1165 | + c->syncout = p / -w + 1e-20f; |
| 1166 | + place_step_dd(c->_f, j, 1.0f - p, -w, -1.0f); |
| 1167 | + k = 1; |
| 1168 | + x = -0.5f; |
| 1169 | + } else { |
| 1170 | + c->syncout = 0.0f; |
| 1171 | + } |
| 1172 | + |
| 1052 | 1173 | } |
| 1053 | 1174 | } |
| 1054 | 1175 | c->_f[j + DD_SAMPLE_DELAY] += x; |
| @@ -1134,7 +1255,7 @@ float tMBTriangle_tick(tMBTriangle* const osc) · 79 unmodified lines |
| 1134 | 1255 | |
| 1135 | 1256 | int j, k; |
| 1136 | 1257 | float freq, syncin; |
| 1137 | | − float a, b, b1, db, p, t, w, dw, x, z; |
| 1258 | + float a, b, b1, db, p, tw, tb, w, dw, x, z; |
| 1138 | 1259 | |
| 1139 | 1260 | syncin = c->syncin; |
| 1140 | 1261 | freq = c->freq; |
| @@ -1149,11 +1270,22 @@ float tMBTriangle_tick(tMBTriangle* const osc) · 8 unmodified lines |
| 1149 | 1270 | // w = (exp2ap (freq[1] + vco->_port[OCTN] + vco->_port[TUNE] + expm[1] * vco->_port[EXPG] + 8.03136) |
| 1150 | 1271 | // + 1e3 * linm[1] * vco->_port[LING]) / SAMPLERATE; |
| 1151 | 1272 | w = freq / leaf->sampleRate; |
| 1152 | | − if (w < 1e-5f) w = 1e-5f; |
| 1153 | | − if (w > 0.5f) w = 0.5f; |
| 1154 | 1273 | b = 0.5f * (1.0f + c->waveform); |
| 1155 | | − if (b < w) b = w; |
| 1156 | | − if (b > 1.0f - w) b = 1.0f - w; |
| 1274 | + if (w >= 0) |
| 1275 | + { |
| 1276 | + if (w < 1e-5f) w = 1e-5f; |
| 1277 | + if (w > 0.5f) w = 0.5f; |
| 1278 | + if (b < w) b = w; |
| 1279 | + if (b > 1.0f - w) b = 1.0f - w; |
| 1280 | + } |
| 1281 | + else |
| 1282 | + { |
| 1283 | + if (w > -1e-5f) w = -1e-5f; |
| 1284 | + if (w < -0.5f) w = -0.5f; |
| 1285 | + if (b < -w) b = -w; |
| 1286 | + if (b > 1.0f + w) b = 1.0f + w; |
| 1287 | + } |
| 1288 | + |
| 1157 | 1289 | p = 0.5f * b; |
| 1158 | 1290 | /* if we valued alias-free startup over low startup time, we could do: |
| 1159 | 1291 | * p -= w; |
| @@ -1165,24 +1297,32 @@ float tMBTriangle_tick(tMBTriangle* const osc) · 5 unmodified lines |
| 1165 | 1297 | // a = 0.2 + 0.8 * vco->_port [FILT]; |
| 1166 | 1298 | a = 0.5f; // when a = 1, LPfilter is disabled |
| 1167 | 1299 | |
| 1168 | | − t = freq / leaf->sampleRate; |
| 1300 | + tw = freq / leaf->sampleRate; |
| 1301 | + if (tw >= 0) |
| 1302 | + { |
| 1303 | + if (tw < 1e-5f) tw = 1e-5f; |
| 1304 | + if (tw > 0.5f) tw = 0.5f; |
| 1305 | + } |
| 1306 | + else |
| 1307 | + { |
| 1308 | + if (tw > -1e-5f) tw = -1e-5f; |
| 1309 | + if (tw < -0.5f) tw = -0.5f; |
| 1310 | + } |
| 1169 | 1311 | |
| 1170 | | − if (t >= 0) |
| 1312 | + tb = 0.5f * (1.0f + c->waveform); |
| 1313 | + if (w >= 0) |
| 1171 | 1314 | { |
| 1172 | | − if (t < 1e-5f) t = 1e-5f; |
| 1173 | | − if (t > 0.5f) t = 0.5f; |
| 1315 | + if (tb < w) tb = w; |
| 1316 | + if (tb > 1.0f - w) tb = 1.0f - w; |
| 1174 | 1317 | } |
| 1175 | 1318 | else |
| 1176 | 1319 | { |
| 1177 | | − if (t > -1e-5f) t = -1e-5f; |
| 1178 | | − if (t < -0.5f) t = -0.5f; |
| 1320 | + if (tb < -w) tb = -w; |
| 1321 | + if (tb > 1.0f + w) tb = 1.0f + w; |
| 1179 | 1322 | } |
| 1180 | 1323 | |
| 1181 | | − dw = (t - w); |
| 1182 | | − t = 0.5f * (1.0f + c->waveform ); |
| 1183 | | − if (t < w) t = w; |
| 1184 | | − if (t > 1.0f - w) t = 1.0f - w; |
| 1185 | | − db = (t - b); |
| 1324 | + dw = (tw - w); |
| 1325 | + db = (tb - b); |
| 1186 | 1326 | |
| 1187 | 1327 | w += dw; |
| 1188 | 1328 | b += db; |
| @@ -1193,84 +1333,178 @@ float tMBTriangle_tick(tMBTriangle* const osc) · 4 unmodified lines |
| 1193 | 1333 | |
| 1194 | 1334 | float eof_offset = (syncin - 1e-20f) * w; |
| 1195 | 1335 | float p_at_reset = p - eof_offset; |
| 1196 | | − p = eof_offset; |
| 1336 | + |
| 1337 | + if (w > 0) p = eof_offset; |
| 1338 | + else p = 1.0f - eof_offset; |
| 1197 | 1339 | // |
| 1198 | 1340 | /* place any DDs that may have occurred in subsample before reset */ |
| 1341 | + |
| 1199 | 1342 | if (!k) { |
| 1200 | 1343 | x = -0.5f + p_at_reset / b; |
| 1201 | | − if (p_at_reset >= b) { |
| 1202 | | − x = 0.5f - (p_at_reset - b) / b1; |
| 1203 | | − place_slope_dd(c->_f, j, p_at_reset - b + eof_offset, w, -1.0f / b1 - 1.0f / b); |
| 1204 | | − k = 1; |
| 1344 | + if (w > 0) |
| 1345 | + { |
| 1346 | + if (p_at_reset >= b) { |
| 1347 | + x = 0.5f - (p_at_reset - b) / b1; |
| 1348 | + place_slope_dd(c->_f, j, p_at_reset - b + eof_offset, w, -1.0f / b1 - 1.0f / b); |
| 1349 | + k = 1; |
| 1350 | + } |
| 1351 | + if (p_at_reset >= 1.0f) { |
| 1352 | + p_at_reset -= 1.0f; |
| 1353 | + x = -0.5f + p_at_reset / b; |
| 1354 | + place_slope_dd(c->_f, j, p_at_reset + eof_offset, w, 1.0f / b + 1.0f / b1); |
| 1355 | + k = 0; |
| 1356 | + } |
| 1205 | 1357 | } |
| 1206 | | − if (p_at_reset >= 1.0f) { |
| 1207 | | − p_at_reset -= 1.0f; |
| 1208 | | − x = -0.5f + p_at_reset / b; |
| 1209 | | − place_slope_dd(c->_f, j, p_at_reset + eof_offset, w, 1.0f / b + 1.0f / b1); |
| 1210 | | − k = 0; |
| 1358 | + else |
| 1359 | + { |
| 1360 | + if (p_at_reset < 0.0f) { |
| 1361 | + p_at_reset += 1.0f; |
| 1362 | + x = 0.5f - (p_at_reset - b) / b1; |
| 1363 | + place_slope_dd(c->_f, j, 1.0f - p_at_reset - eof_offset, -w, 1.0f / b + 1.0f / b1); |
| 1364 | + k = 1; |
| 1365 | + } |
| 1366 | + if (k && p_at_reset < b) { |
| 1367 | + x = -0.5f + p_at_reset / b; |
| 1368 | + place_slope_dd(c->_f, j, b - p_at_reset - eof_offset, -w, -1.0f / b1 - 1.0f / b); |
| 1369 | + k = 0; |
| 1370 | + } |
| 1211 | 1371 | } |
| 1212 | 1372 | } else { |
| 1213 | 1373 | x = 0.5f - (p_at_reset - b) / b1; |
| 1214 | | − if (p_at_reset >= 1.0f) { |
| 1215 | | − p_at_reset -= 1.0f; |
| 1216 | | − x = -0.5f + p_at_reset / b; |
| 1217 | | − place_slope_dd(c->_f, j, p_at_reset + eof_offset, w, 1.0f / b + 1.0f / b1); |
| 1218 | | − k = 0; |
| 1374 | + if (w > 0) |
| 1375 | + { |
| 1376 | + if (p_at_reset >= 1.0f) { |
| 1377 | + p_at_reset -= 1.0f; |
| 1378 | + x = -0.5f + p_at_reset / b; |
| 1379 | + place_slope_dd(c->_f, j, p_at_reset + eof_offset, w, 1.0f / b + 1.0f / b1); |
| 1380 | + k = 0; |
| 1381 | + } |
| 1382 | + if (!k && p_at_reset >= b) { |
| 1383 | + x = 0.5f - (p_at_reset - b) / b1; |
| 1384 | + place_slope_dd(c->_f, j, p_at_reset - b + eof_offset, w, -1.0f / b1 - 1.0f / b); |
| 1385 | + k = 1; |
| 1386 | + } |
| 1219 | 1387 | } |
| 1220 | | − if (!k && p_at_reset >= b) { |
| 1221 | | − x = 0.5f - (p_at_reset - b) / b1; |
| 1222 | | − place_slope_dd(c->_f, j, p_at_reset - b + eof_offset, w, -1.0f / b1 - 1.0f / b); |
| 1223 | | − k = 1; |
| 1388 | + else |
| 1389 | + { |
| 1390 | + if (p_at_reset < b) { |
| 1391 | + x = -0.5f + p_at_reset / b; |
| 1392 | + place_slope_dd(c->_f, j, b - p_at_reset - eof_offset, -w, -1.0f / b1 - 1.0f / b); |
| 1393 | + k = 0; |
| 1394 | + } |
| 1395 | + if (p_at_reset < 0.0f) { |
| 1396 | + p_at_reset += 1.0f; |
| 1397 | + x = 0.5f - (p_at_reset - b) / b1; |
| 1398 | + place_slope_dd(c->_f, j, 1.0f - p_at_reset - eof_offset, -w, 1.0f / b + 1.0f / b1); |
| 1399 | + k = 1; |
| 1400 | + } |
| 1224 | 1401 | } |
| 1225 | 1402 | } |
| 1226 | 1403 | |
| 1227 | 1404 | /* now place reset DDs */ |
| 1228 | | − if (k) |
| 1229 | | − place_slope_dd(c->_f, j, p, w, 1.0f / b + 1.0f / b1); |
| 1230 | | − place_step_dd(c->_f, j, p, w, -0.5f - x); |
| 1231 | | − x = -0.5f + p / b; |
| 1232 | | − k = 0; |
| 1233 | | − if (p >= b) { |
| 1405 | + if (w > 0) |
| 1406 | + { |
| 1407 | + if (k) |
| 1408 | + place_slope_dd(c->_f, j, p, w, 1.0f / b + 1.0f / b1); |
| 1409 | + place_step_dd(c->_f, j, p, w, -0.5f - x); |
| 1410 | + x = -0.5f + p / b; |
| 1411 | + k = 0; |
| 1412 | + if (p >= b) { |
| 1413 | + x = 0.5f - (p - b) / b1; |
| 1414 | + place_slope_dd(c->_f, j, p - b, w, -1.0f / b1 - 1.0f / b); |
| 1415 | + k = 1; |
| 1416 | + } |
| 1417 | + } |
| 1418 | + else |
| 1419 | + { |
| 1420 | + if (!k) |
| 1421 | + place_slope_dd(c->_f, j, 1.0f - p, -w, 1.0f / b + 1.0f / b1); |
| 1422 | + place_step_dd(c->_f, j, 1.0f - p, -w, -0.5f - x); |
| 1234 | 1423 | x = 0.5f - (p - b) / b1; |
| 1235 | | − place_slope_dd(c->_f, j, p - b, w, -1.0f / b1 - 1.0f / b); |
| 1236 | 1424 | k = 1; |
| 1425 | + if (p < b) { |
| 1426 | + x = -0.5f + p / b; |
| 1427 | + place_slope_dd(c->_f, j, b - p, -w, -1.0f / b1 - 1.0f / b); |
| 1428 | + k = 0; |
| 1429 | + } |
| 1237 | 1430 | } |
| 1431 | + |
| 1238 | 1432 | c->syncout = syncin; /* best we can do is pass on upstream sync */ |
| 1239 | 1433 | |
| 1240 | 1434 | } else if (!k) { /* normal operation, slope currently up */ |
| 1241 | 1435 | |
| 1242 | 1436 | x = -0.5f + p / b; |
| 1243 | | − if (p >= b) { |
| 1244 | | − x = 0.5f - (p - b) / b1; |
| 1245 | | − place_slope_dd(c->_f, j, p - b, w, -1.0f / b1 - 1.0f / b); |
| 1246 | | − k = 1; |
| 1437 | + if (w > 0) |
| 1438 | + { |
| 1439 | + if (p >= b) { |
| 1440 | + x = 0.5f - (p - b) / b1; |
| 1441 | + place_slope_dd(c->_f, j, p - b, w, -1.0f / b1 - 1.0f / b); |
| 1442 | + k = 1; |
| 1443 | + } |
| 1444 | + if (p >= 1.0f) { |
| 1445 | + p -= 1.0f; |
| 1446 | + c->syncout = p / w + 1e-20f; |
| 1447 | + x = -0.5f + p / b; |
| 1448 | + place_slope_dd(c->_f, j, p, w, 1.0f / b + 1.0f / b1); |
| 1449 | + k = 0; |
| 1450 | + } else { |
| 1451 | + c->syncout = 0.0f; |
| 1452 | + } |
| 1247 | 1453 | } |
| 1248 | | − if (p >= 1.0f) { |
| 1249 | | − p -= 1.0f; |
| 1250 | | − c->syncout = p / w + 1e-20f; |
| 1251 | | − x = -0.5f + p / b; |
| 1252 | | − place_slope_dd(c->_f, j, p, w, 1.0f / b + 1.0f / b1); |
| 1253 | | − k = 0; |
| 1254 | | − } else { |
| 1255 | | − c->syncout = 0.0f; |
| 1454 | + else |
| 1455 | + { |
| 1456 | + if (p < 0.0f) { |
| 1457 | + p += 1.0f; |
| 1458 | + c->syncout = p / -w + 1e-20f; |
| 1459 | + x = 0.5f - (p - b) / b1; |
| 1460 | + place_slope_dd(c->_f, j, 1.0f - p, -w, 1.0f / b + 1.0f / b1); |
| 1461 | + k = 1; |
| 1462 | + } else { |
| 1463 | + c->syncout = 0.0f; |
| 1464 | + } |
| 1465 | + if (k && p < b) { |
| 1466 | + x = -0.5f + p / b; |
| 1467 | + place_slope_dd(c->_f, j, b - p, -w, -1.0f / b1 - 1.0f / b); |
| 1468 | + k = 0; |
| 1469 | + } |
| 1256 | 1470 | } |
| 1257 | 1471 | |
| 1258 | 1472 | } else { /* normal operation, slope currently down */ |
| 1259 | 1473 | |
| 1260 | 1474 | x = 0.5f - (p - b) / b1; |
| 1261 | | − if (p >= 1.0f) { |
| 1262 | | − p -= 1.0f; |
| 1263 | | − c->syncout = p / w + 1e-20f; |
| 1264 | | − x = -0.5f + p / b; |
| 1265 | | − place_slope_dd(c->_f, j, p, w, 1.0f / b + 1.0f / b1); |
| 1266 | | − k = 0; |
| 1267 | | − } else { |
| 1268 | | − c->syncout = 0.0f; |
| 1475 | + if (w > 0) |
| 1476 | + { |
| 1477 | + if (p >= 1.0f) { |
| 1478 | + p -= 1.0f; |
| 1479 | + c->syncout = p / w + 1e-20f; |
| 1480 | + x = -0.5f + p / b; |
| 1481 | + place_slope_dd(c->_f, j, p, w, 1.0f / b + 1.0f / b1); |
| 1482 | + k = 0; |
| 1483 | + } else { |
| 1484 | + c->syncout = 0.0f; |
| 1485 | + } |
| 1486 | + if (!k && p >= b) { |
| 1487 | + x = 0.5f - (p - b) / b1; |
| 1488 | + place_slope_dd(c->_f, j, p - b, w, -1.0f / b1 - 1.0f / b); |
| 1489 | + k = 1; |
| 1490 | + } |
| 1269 | 1491 | } |
| 1270 | | − if (!k && p >= b) { |
| 1271 | | − x = 0.5f - (p - b) / b1; |
| 1272 | | − place_slope_dd(c->_f, j, p - b, w, -1.0f / b1 - 1.0f / b); |
| 1273 | | − k = 1; |
| 1492 | + else |
| 1493 | + { |
| 1494 | + if (p < b) { |
| 1495 | + x = -0.5f + p / b; |
| 1496 | + place_slope_dd(c->_f, j, b - p, -w, -1.0f / b1 - 1.0f / b); |
| 1497 | + k = 0; |
| 1498 | + } |
| 1499 | + if (p < 0.0f) { |
| 1500 | + p += 1.0f; |
| 1501 | + c->syncout = p / -w + 1e-20f; |
| 1502 | + x = 0.5f - (p - b) / b1; |
| 1503 | + place_slope_dd(c->_f, j, 1.0f - p, -w, 1.0f / b + 1.0f / b1); |
| 1504 | + k = 1; |
| 1505 | + } else { |
| 1506 | + c->syncout = 0.0f; |
| 1507 | + } |
| 1274 | 1508 | } |
| 1275 | 1509 | } |
| 1276 | 1510 | c->_f[j + DD_SAMPLE_DELAY] += x; |
| @@ -1409,16 +1643,25 @@ float tMBSaw_tick(tMBSaw* const osc) · 132 unmodified lines |
| 1409 | 1643 | |
| 1410 | 1644 | float eof_offset = (syncin - 1e-20f) * w; |
| 1411 | 1645 | float p_at_reset = p - eof_offset; |
| 1412 | | − p = eof_offset; |
| 1646 | + |
| 1647 | + if (w > 0) p = eof_offset; |
| 1648 | + else p = 1.0f - eof_offset; |
| 1413 | 1649 | |
| 1414 | 1650 | /* place any DD that may have occurred in subsample before reset */ |
| 1415 | 1651 | if (p_at_reset >= 1.0f) { |
| 1416 | 1652 | p_at_reset -= 1.0f; |
| 1417 | 1653 | place_step_dd(c->_f, j, p_at_reset + eof_offset, w, 1.0f); |
| 1418 | 1654 | } |
| 1655 | + if (p_at_reset < 0.0f) { |
| 1656 | + p_at_reset += 1.0f; |
| 1657 | + place_step_dd(c->_f, j, 1.0f - p_at_reset - eof_offset, -w, -1.0f); |
| 1658 | + } |
| 1419 | 1659 | |
| 1420 | 1660 | /* now place reset DD */ |
| 1421 | | − place_step_dd(c->_f, j, p, w, p_at_reset); |
| 1661 | + if (w > 0) |
| 1662 | + place_step_dd(c->_f, j, p, w, p_at_reset); |
| 1663 | + else |
| 1664 | + place_step_dd(c->_f, j, 1.0f - p, -w, -p_at_reset); |
| 1422 | 1665 | |
| 1423 | 1666 | c->syncout = syncin; /* best we can do is pass on upstream sync */ |
| 1424 | 1667 | |
| @@ -1430,7 +1673,7 @@ float tMBSaw_tick(tMBSaw* const osc) · 5 unmodified lines |
| 1430 | 1673 | |
| 1431 | 1674 | } else if (p < 0.0f) { |
| 1432 | 1675 | p += 1.0f; |
| 1433 | | − c->syncout = p / w + 1e-20f; |
| 1676 | + c->syncout = p / -w + 1e-20f; |
| 1434 | 1677 | place_step_dd(c->_f, j, 1.0f - p, -w, -1.0f); |
| 1435 | 1678 | } |
| 1436 | 1679 | else { |