20 #ifndef RESID_FILTER_H
21 #define RESID_FILTER_H
23 #include "resid-config.h"
317 enum { value =
summer_offset<i - 1>::value + ((2 + i - 1) << 16) };
330 enum { value =
mixer_offset<i - 1>::value + ((i - 1) << 16) };
351 void enable_filter(
bool enable);
352 void adjust_filter_bias(
double dac_bias);
353 void set_chip_model(chip_model model);
354 void set_voice_mask(reg4 mask);
356 void clock(
int voice1,
int voice2,
int voice3);
357 void clock(cycle_count delta_t,
int voice1,
int voice2,
int voice3);
361 void writeFC_LO(reg8);
362 void writeFC_HI(reg8);
363 void writeRES_FILT(reg8);
364 void writeMODE_VOL(reg8);
367 void input(
short sample);
417 int Vddt_Vw_2, Vw_bias;
423 chip_model sid_model;
437 unsigned short opamp_rev[1 << 16];
440 unsigned short gain[16][1 << 16];
443 unsigned short f0_dac[1 << 11];
446 int solve_gain(
int* opamp,
int n,
int vi_t,
int& x,
model_filter_t& mf);
447 int solve_integrate_6581(
int dt,
int vi_t,
int& x,
int& vc,
model_filter_t& mf);
450 static unsigned short vcr_kVg[1 << 16];
451 static unsigned short vcr_n_Ids_term[1 << 16];
465 #if RESID_INLINING || defined(RESID_FILTER_CC)
471 void Filter::clock(
int voice1,
int voice2,
int voice3)
473 model_filter_t& f = model_filter[sid_model];
475 v1 = (voice1*f.voice_scale_s14 >> 18) + f.voice_DC;
476 v2 = (voice2*f.voice_scale_s14 >> 18) + f.voice_DC;
477 v3 = (voice3*f.voice_scale_s14 >> 18) + f.voice_DC;
545 Vi = ve + v3 + v2 + v1;
551 if (sid_model == 0) {
553 Vlp = solve_integrate_6581(1, Vbp, Vlp_x, Vlp_vc, f);
554 Vbp = solve_integrate_6581(1, Vhp, Vbp_x, Vbp_vc, f);
555 Vhp = f.summer[offset + f.gain[_8_div_Q][Vbp] + Vlp + Vi];
563 int dVbp = w0*(Vhp >> 4) >> 16;
564 int dVlp = w0*(Vbp >> 4) >> 16;
567 Vhp = (Vbp*_1024_div_Q >> 10) - Vlp - Vi;
575 void Filter::clock(cycle_count delta_t,
int voice1,
int voice2,
int voice3)
577 model_filter_t& f = model_filter[sid_model];
579 v1 = (voice1*f.voice_scale_s14 >> 18) + f.voice_DC;
580 v2 = (voice2*f.voice_scale_s14 >> 18) + f.voice_DC;
581 v3 = (voice3*f.voice_scale_s14 >> 18) + f.voice_DC;
587 if (unlikely(!enabled)) {
598 offset = summer_offset<0>::value;
602 offset = summer_offset<1>::value;
606 offset = summer_offset<1>::value;
610 offset = summer_offset<2>::value;
614 offset = summer_offset<1>::value;
618 offset = summer_offset<2>::value;
622 offset = summer_offset<2>::value;
626 offset = summer_offset<3>::value;
630 offset = summer_offset<1>::value;
634 offset = summer_offset<2>::value;
638 offset = summer_offset<2>::value;
642 offset = summer_offset<3>::value;
646 offset = summer_offset<2>::value;
650 offset = summer_offset<3>::value;
654 offset = summer_offset<3>::value;
657 Vi = ve + v3 + v2 + v1;
658 offset = summer_offset<4>::value;
664 cycle_count delta_t_flt = 3;
666 if (sid_model == 0) {
669 if (unlikely(delta_t < delta_t_flt)) {
670 delta_t_flt = delta_t;
674 Vlp = solve_integrate_6581(delta_t_flt, Vbp, Vlp_x, Vlp_vc, f);
675 Vbp = solve_integrate_6581(delta_t_flt, Vhp, Vbp_x, Vbp_vc, f);
676 Vhp = f.summer[offset + f.gain[_8_div_Q][Vbp] + Vlp + Vi];
678 delta_t -= delta_t_flt;
684 if (delta_t < delta_t_flt) {
685 delta_t_flt = delta_t;
693 int w0_delta_t = w0*delta_t_flt >> 2;
695 int dVbp = w0_delta_t*(Vhp >> 4) >> 14;
696 int dVlp = w0_delta_t*(Vbp >> 4) >> 14;
699 Vhp = (Vbp*_1024_div_Q >> 10) - Vlp - Vi;
701 delta_t -= delta_t_flt;
711 void Filter::input(
short sample)
722 model_filter_t& f = model_filter[sid_model];
723 ve = (sample*f.voice_scale_s14*3 >> 14) + f.mixer[0];
731 short Filter::output()
733 model_filter_t& f = model_filter[sid_model];
758 switch (mix & 0x7f) {
761 offset = mixer_offset<0>::value;
765 offset = mixer_offset<1>::value;
769 offset = mixer_offset<1>::value;
773 offset = mixer_offset<2>::value;
777 offset = mixer_offset<1>::value;
781 offset = mixer_offset<2>::value;
785 offset = mixer_offset<2>::value;
789 offset = mixer_offset<3>::value;
793 offset = mixer_offset<1>::value;
797 offset = mixer_offset<2>::value;
801 offset = mixer_offset<2>::value;
805 offset = mixer_offset<3>::value;
809 offset = mixer_offset<2>::value;
813 offset = mixer_offset<3>::value;
817 offset = mixer_offset<3>::value;
820 Vi = ve + v3 + v2 + v1;
821 offset = mixer_offset<4>::value;
825 offset = mixer_offset<1>::value;
829 offset = mixer_offset<2>::value;
833 offset = mixer_offset<2>::value;
837 offset = mixer_offset<3>::value;
841 offset = mixer_offset<2>::value;
845 offset = mixer_offset<3>::value;
849 offset = mixer_offset<3>::value;
852 Vi = Vlp + v3 + v2 + v1;
853 offset = mixer_offset<4>::value;
857 offset = mixer_offset<2>::value;
861 offset = mixer_offset<3>::value;
865 offset = mixer_offset<3>::value;
868 Vi = Vlp + ve + v2 + v1;
869 offset = mixer_offset<4>::value;
873 offset = mixer_offset<3>::value;
876 Vi = Vlp + ve + v3 + v1;
877 offset = mixer_offset<4>::value;
880 Vi = Vlp + ve + v3 + v2;
881 offset = mixer_offset<4>::value;
884 Vi = Vlp + ve + v3 + v2 + v1;
885 offset = mixer_offset<5>::value;
889 offset = mixer_offset<1>::value;
893 offset = mixer_offset<2>::value;
897 offset = mixer_offset<2>::value;
901 offset = mixer_offset<3>::value;
905 offset = mixer_offset<2>::value;
909 offset = mixer_offset<3>::value;
913 offset = mixer_offset<3>::value;
916 Vi = Vbp + v3 + v2 + v1;
917 offset = mixer_offset<4>::value;
921 offset = mixer_offset<2>::value;
925 offset = mixer_offset<3>::value;
929 offset = mixer_offset<3>::value;
932 Vi = Vbp + ve + v2 + v1;
933 offset = mixer_offset<4>::value;
937 offset = mixer_offset<3>::value;
940 Vi = Vbp + ve + v3 + v1;
941 offset = mixer_offset<4>::value;
944 Vi = Vbp + ve + v3 + v2;
945 offset = mixer_offset<4>::value;
948 Vi = Vbp + ve + v3 + v2 + v1;
949 offset = mixer_offset<5>::value;
953 offset = mixer_offset<2>::value;
957 offset = mixer_offset<3>::value;
961 offset = mixer_offset<3>::value;
964 Vi = Vbp + Vlp + v2 + v1;
965 offset = mixer_offset<4>::value;
969 offset = mixer_offset<3>::value;
972 Vi = Vbp + Vlp + v3 + v1;
973 offset = mixer_offset<4>::value;
976 Vi = Vbp + Vlp + v3 + v2;
977 offset = mixer_offset<4>::value;
980 Vi = Vbp + Vlp + v3 + v2 + v1;
981 offset = mixer_offset<5>::value;
985 offset = mixer_offset<3>::value;
988 Vi = Vbp + Vlp + ve + v1;
989 offset = mixer_offset<4>::value;
992 Vi = Vbp + Vlp + ve + v2;
993 offset = mixer_offset<4>::value;
996 Vi = Vbp + Vlp + ve + v2 + v1;
997 offset = mixer_offset<5>::value;
1000 Vi = Vbp + Vlp + ve + v3;
1001 offset = mixer_offset<4>::value;
1004 Vi = Vbp + Vlp + ve + v3 + v1;
1005 offset = mixer_offset<5>::value;
1008 Vi = Vbp + Vlp + ve + v3 + v2;
1009 offset = mixer_offset<5>::value;
1012 Vi = Vbp + Vlp + ve + v3 + v2 + v1;
1013 offset = mixer_offset<6>::value;
1017 offset = mixer_offset<1>::value;
1021 offset = mixer_offset<2>::value;
1025 offset = mixer_offset<2>::value;
1029 offset = mixer_offset<3>::value;
1033 offset = mixer_offset<2>::value;
1037 offset = mixer_offset<3>::value;
1041 offset = mixer_offset<3>::value;
1044 Vi = Vhp + v3 + v2 + v1;
1045 offset = mixer_offset<4>::value;
1049 offset = mixer_offset<2>::value;
1053 offset = mixer_offset<3>::value;
1057 offset = mixer_offset<3>::value;
1060 Vi = Vhp + ve + v2 + v1;
1061 offset = mixer_offset<4>::value;
1065 offset = mixer_offset<3>::value;
1068 Vi = Vhp + ve + v3 + v1;
1069 offset = mixer_offset<4>::value;
1072 Vi = Vhp + ve + v3 + v2;
1073 offset = mixer_offset<4>::value;
1076 Vi = Vhp + ve + v3 + v2 + v1;
1077 offset = mixer_offset<5>::value;
1081 offset = mixer_offset<2>::value;
1084 Vi = Vhp + Vlp + v1;
1085 offset = mixer_offset<3>::value;
1088 Vi = Vhp + Vlp + v2;
1089 offset = mixer_offset<3>::value;
1092 Vi = Vhp + Vlp + v2 + v1;
1093 offset = mixer_offset<4>::value;
1096 Vi = Vhp + Vlp + v3;
1097 offset = mixer_offset<3>::value;
1100 Vi = Vhp + Vlp + v3 + v1;
1101 offset = mixer_offset<4>::value;
1104 Vi = Vhp + Vlp + v3 + v2;
1105 offset = mixer_offset<4>::value;
1108 Vi = Vhp + Vlp + v3 + v2 + v1;
1109 offset = mixer_offset<5>::value;
1112 Vi = Vhp + Vlp + ve;
1113 offset = mixer_offset<3>::value;
1116 Vi = Vhp + Vlp + ve + v1;
1117 offset = mixer_offset<4>::value;
1120 Vi = Vhp + Vlp + ve + v2;
1121 offset = mixer_offset<4>::value;
1124 Vi = Vhp + Vlp + ve + v2 + v1;
1125 offset = mixer_offset<5>::value;
1128 Vi = Vhp + Vlp + ve + v3;
1129 offset = mixer_offset<4>::value;
1132 Vi = Vhp + Vlp + ve + v3 + v1;
1133 offset = mixer_offset<5>::value;
1136 Vi = Vhp + Vlp + ve + v3 + v2;
1137 offset = mixer_offset<5>::value;
1140 Vi = Vhp + Vlp + ve + v3 + v2 + v1;
1141 offset = mixer_offset<6>::value;
1145 offset = mixer_offset<2>::value;
1148 Vi = Vhp + Vbp + v1;
1149 offset = mixer_offset<3>::value;
1152 Vi = Vhp + Vbp + v2;
1153 offset = mixer_offset<3>::value;
1156 Vi = Vhp + Vbp + v2 + v1;
1157 offset = mixer_offset<4>::value;
1160 Vi = Vhp + Vbp + v3;
1161 offset = mixer_offset<3>::value;
1164 Vi = Vhp + Vbp + v3 + v1;
1165 offset = mixer_offset<4>::value;
1168 Vi = Vhp + Vbp + v3 + v2;
1169 offset = mixer_offset<4>::value;
1172 Vi = Vhp + Vbp + v3 + v2 + v1;
1173 offset = mixer_offset<5>::value;
1176 Vi = Vhp + Vbp + ve;
1177 offset = mixer_offset<3>::value;
1180 Vi = Vhp + Vbp + ve + v1;
1181 offset = mixer_offset<4>::value;
1184 Vi = Vhp + Vbp + ve + v2;
1185 offset = mixer_offset<4>::value;
1188 Vi = Vhp + Vbp + ve + v2 + v1;
1189 offset = mixer_offset<5>::value;
1192 Vi = Vhp + Vbp + ve + v3;
1193 offset = mixer_offset<4>::value;
1196 Vi = Vhp + Vbp + ve + v3 + v1;
1197 offset = mixer_offset<5>::value;
1200 Vi = Vhp + Vbp + ve + v3 + v2;
1201 offset = mixer_offset<5>::value;
1204 Vi = Vhp + Vbp + ve + v3 + v2 + v1;
1205 offset = mixer_offset<6>::value;
1208 Vi = Vhp + Vbp + Vlp;
1209 offset = mixer_offset<3>::value;
1212 Vi = Vhp + Vbp + Vlp + v1;
1213 offset = mixer_offset<4>::value;
1216 Vi = Vhp + Vbp + Vlp + v2;
1217 offset = mixer_offset<4>::value;
1220 Vi = Vhp + Vbp + Vlp + v2 + v1;
1221 offset = mixer_offset<5>::value;
1224 Vi = Vhp + Vbp + Vlp + v3;
1225 offset = mixer_offset<4>::value;
1228 Vi = Vhp + Vbp + Vlp + v3 + v1;
1229 offset = mixer_offset<5>::value;
1232 Vi = Vhp + Vbp + Vlp + v3 + v2;
1233 offset = mixer_offset<5>::value;
1236 Vi = Vhp + Vbp + Vlp + v3 + v2 + v1;
1237 offset = mixer_offset<6>::value;
1240 Vi = Vhp + Vbp + Vlp + ve;
1241 offset = mixer_offset<4>::value;
1244 Vi = Vhp + Vbp + Vlp + ve + v1;
1245 offset = mixer_offset<5>::value;
1248 Vi = Vhp + Vbp + Vlp + ve + v2;
1249 offset = mixer_offset<5>::value;
1252 Vi = Vhp + Vbp + Vlp + ve + v2 + v1;
1253 offset = mixer_offset<6>::value;
1256 Vi = Vhp + Vbp + Vlp + ve + v3;
1257 offset = mixer_offset<5>::value;
1260 Vi = Vhp + Vbp + Vlp + ve + v3 + v1;
1261 offset = mixer_offset<6>::value;
1264 Vi = Vhp + Vbp + Vlp + ve + v3 + v2;
1265 offset = mixer_offset<6>::value;
1268 Vi = Vhp + Vbp + Vlp + ve + v3 + v2 + v1;
1269 offset = mixer_offset<7>::value;
1274 if (sid_model == 0) {
1275 return (
short)(f.gain[vol][f.mixer[offset + Vi]] - (1 << 15));
1281 int tmp = Vi*(int)vol >> 4;
1282 if (tmp < -32768) tmp = -32768;
1283 if (tmp > 32767) tmp = 32767;
1284 return (
short)tmp; }
1327 int Filter::solve_gain(
int* opamp,
int n,
int vi,
int& x, model_filter_t& mf)
1336 int ak = mf.ak, bk = mf.bk;
1338 int a = n + (1 << 7);
1341 if (b_vi < 0) b_vi = 0;
1342 int c = n*int(
unsigned(b_vi)*
unsigned(b_vi) >> 12);
1348 int vx_dvx = opamp[x];
1349 int vx = vx_dvx & 0xffff;
1350 int dvx = vx_dvx >> 16;
1355 int vo = vx + (x << 1) - (1 << 16);
1356 if (vo >= (1 << 16)) {
1363 if (b_vx < 0) b_vx = 0;
1365 if (b_vo < 0) b_vo = 0;
1367 int f = a*int(
unsigned(b_vx)*
unsigned(b_vx) >> 12) - c - int(
unsigned(b_vo)*
unsigned(b_vo) >> 5);
1369 int df = (b_vo*(dvx + (1 << 11)) - a*(b_vx*dvx >> 7)) >> 15;
1374 if (unlikely(x == xk)) {
1389 if (unlikely(x <= ak) || unlikely(x >= bk)) {
1392 if (unlikely(x == ak)) {
1521 int Filter::solve_integrate_6581(
int dt,
int vi,
int& vx,
int& vc,
1529 int kVddt = mf.kVddt;
1532 unsigned int Vgst = kVddt - vx;
1533 unsigned int Vgdt = kVddt - vi;
1534 unsigned int Vgdt_2 = Vgdt*Vgdt;
1537 int n_I_snake = mf.n_snake*(int(Vgst*Vgst - Vgdt_2) >> 15);
1541 int kVg = vcr_kVg[(Vddt_Vw_2 + (Vgdt_2 >> 1)) >> 16];
1545 if (Vgs < 0) Vgs = 0;
1547 if (Vgd < 0) Vgd = 0;
1550 int n_I_vcr = (vcr_n_Ids_term[Vgs] - vcr_n_Ids_term[Vgd]) << 15;
1553 vc -= (n_I_snake + n_I_vcr)*dt;
1566 vx = mf.opamp_rev[(vc >> 15) + (1 << 15)];
1569 return vx + (vc >> 14);
1572 #endif // RESID_INLINING || defined(RESID_FILTER_CC)
1576 #endif // not RESID_FILTER_H