23 namespace YM2413Okazaki {
84 { 0, 0, 0, 0, 0, 0, 0, 0, },
85 { 0, 0, 1, 0, 0, 0,-1, 0, },
86 { 0, 1, 2, 1, 0,-1,-2,-1, },
87 { 0, 1, 3, 1, 0,-1,-3,-1, },
88 { 0, 2, 4, 2, 0,-2,-4,-2, },
89 { 0, 2, 5, 2, 0,-2,-5,-2, },
90 { 0, 3, 6, 3, 0,-3,-6,-3, },
91 { 0, 3, 7, 3, 0,-3,-7,-3, },
152 1, 1*2, 2*2, 3*2, 4*2, 5*2, 6*2, 7*2,
153 8*2, 9*2, 10*2, 10*2, 12*2, 12*2, 15*2, 15*2
163 std::array<int, 2 * DBTABLEN> result = {};
166 cstd::pow<5, 3>(10, -
double(i) *
DB_STEP / 20));
180 std::array<unsigned, 1 << EG_BITS> result = {};
181 result[0] = (1 <<
EG_BITS) - 1;
182 constexpr
double l127 = cstd::log<5, 4>(127.0);
184 result[i] = unsigned(
double(1 <<
EG_BITS) - 1 -
185 ((1 <<
EG_BITS) - 1) * cstd::log<5, 4>(
double(i)) / l127);
192 std::array<std::array<uint8_t, 16 * 8>, 4> result = {};
195 constexpr
unsigned klTable[16] = {
196 0, 24, 32, 37, 40, 43, 45, 47, 48, 50, 51, 52, 53, 54, 55, 56
202 for (
auto freq :
xrange(16 * 8u)) {
203 unsigned fnum = freq % 16;
204 unsigned block = freq / 16;
205 int tmp = 2 * klTable[fnum] - 16 * (7 - block);
206 for (
auto KL :
xrange(4)) {
207 unsigned t = (tmp <= 0 || KL == 0) ? 0 : (tmp >> (3 - KL));
209 result[KL][freq] =
t;
219 auto lin2db = [](
double d) {
226 std::array<unsigned, PG_WIDTH> result = {};
228 result[i] = lin2db(cstd::sin<2>(
double(2.0 *
M_PI) * i /
PG_WIDTH));
231 result[
PG_WIDTH / 2 - 1 - i] = result[i];
239 std::array<unsigned, PG_WIDTH> result = {};
255 std::array<std::array<int, 16>, 16> result = {};
256 for (
auto Rks :
xrange(16)) {
258 for (
auto DR :
xrange(1, 16)) {
259 unsigned RM =
std::min(DR + (Rks >> 2), 15);
260 unsigned RL = Rks & 3;
270 std::array<unsigned, 16> result = {};
272 for (
int i = 0; i < 16; ++i) {
273 double x = (i == 15) ? 48.0 : (3.0 * i);
282 static constexpr
int EG2DB(
int d)
286 static constexpr
unsigned TL2EG(
unsigned d)
292 static constexpr
unsigned DB_POS(
double x)
299 static constexpr
unsigned DB_NEG(
double x)
304 static constexpr
bool BIT(
unsigned s,
unsigned b)
313 : AMPM(0), EG(false), AR(0), DR(0), RR(0)
326 AMPM = (data[0] >> 6) & 3;
327 EG = (data[0] >> 5) & 1;
328 setKR ((data[0] >> 4) & 1);
329 setML ((data[0] >> 0) & 15);
330 setKL ((data[2] >> 6) & 3);
331 setTL ((data[2] >> 0) & 63);
332 setWF ((data[3] >> 3) & 1);
333 setFB ((data[3] >> 0) & 7);
334 AR = (data[4] >> 4) & 15;
335 DR = (data[4] >> 0) & 15;
336 setSL ((data[6] >> 4) & 15);
337 RR = (data[6] >> 0) & 15;
342 AMPM = (data[1] >> 6) & 3;
343 EG = (data[1] >> 5) & 1;
344 setKR ((data[1] >> 4) & 1);
345 setML ((data[1] >> 0) & 15);
346 setKL ((data[3] >> 6) & 3);
348 setWF ((data[3] >> 4) & 1);
350 AR = (data[5] >> 4) & 15;
351 DR = (data[5] >> 0) & 15;
352 setSL ((data[7] >> 4) & 15);
353 RR = (data[7] >> 0) & 15;
371 assert(TL2EG(value) < 256);
380 FB = value ? 8 - value : 0;
413 unsigned fnum = freq & 511;
414 unsigned block = freq / 512;
416 unsigned tmp = ((2 * fnum +
pmTable[fnum >> 6][pm]) *
patch.
ML) << block;
428 unsigned rks = freq >>
patch.
KR;
564 volume = TL2EG(value << 2);
596 if (modActAsCarrier) {
633 static constexpr uint8_t inst_data[16 + 3][8] = {
634 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
635 { 0x61,0x61,0x1e,0x17,0xf0,0x7f,0x00,0x17 },
636 { 0x13,0x41,0x16,0x0e,0xfd,0xf4,0x23,0x23 },
637 { 0x03,0x01,0x9a,0x04,0xf3,0xf3,0x13,0xf3 },
638 { 0x11,0x61,0x0e,0x07,0xfa,0x64,0x70,0x17 },
639 { 0x22,0x21,0x1e,0x06,0xf0,0x76,0x00,0x28 },
640 { 0x21,0x22,0x16,0x05,0xf0,0x71,0x00,0x18 },
641 { 0x21,0x61,0x1d,0x07,0x82,0x80,0x17,0x17 },
642 { 0x23,0x21,0x2d,0x16,0x90,0x90,0x00,0x07 },
643 { 0x21,0x21,0x1b,0x06,0x64,0x65,0x10,0x17 },
644 { 0x21,0x21,0x0b,0x1a,0x85,0xa0,0x70,0x07 },
645 { 0x23,0x01,0x83,0x10,0xff,0xb4,0x10,0xf4 },
646 { 0x97,0xc1,0x20,0x07,0xff,0xf4,0x22,0x22 },
647 { 0x61,0x00,0x0c,0x05,0xc2,0xf6,0x40,0x44 },
648 { 0x01,0x01,0x56,0x03,0x94,0xc2,0x03,0x12 },
649 { 0x21,0x01,0x89,0x03,0xf1,0xe4,0xf0,0x23 },
650 { 0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8 },
651 { 0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7 },
652 { 0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55 }
658 for (
const auto& e :
dB2LinTab) std::cout << e <<
' ';
661 for (
const auto& e :
arAdjustTab) std::cout << e <<
' ';
664 for (
auto i :
xrange(4)) {
665 for (
auto j :
xrange(16 * 8)) {
666 std::cout << int(
tllTab[i][j]) <<
' ';
672 for (
const auto& e :
fullSinTable) std::cout << e <<
' ';
674 for (
const auto& e :
halfSinTable) std::cout << e <<
' ';
677 for (
auto i :
xrange(16)) {
678 for (
auto j :
xrange(16)) {
685 for (
const auto& e :
slTab) std::cout << e <<
' ';
689 memset(reg, 0,
sizeof(reg));
691 for (
auto i :
xrange(16 + 3)) {
706 for (
auto& ch : channels) {
709 for (
auto i :
xrange(0x40)) {
716 void YM2413::keyOn_BD()
726 void YM2413::keyOn_HH()
729 Channel& ch7 = channels[7];
730 if (!ch7.mod.slot_on_flag) {
733 ch7.mod.slot_on_flag |= 2;
735 void YM2413::keyOn_SD()
737 Channel& ch7 = channels[7];
738 if (!ch7.car.slot_on_flag) {
741 ch7.car.slot_on_flag |= 2;
743 void YM2413::keyOn_TOM()
745 Channel& ch8 = channels[8];
746 if (!ch8.mod.slot_on_flag) {
749 ch8.mod.slot_on_flag |= 2;
751 void YM2413::keyOn_CYM()
753 Channel& ch8 = channels[8];
754 if (!ch8.car.slot_on_flag) {
757 ch8.car.slot_on_flag |= 2;
761 void YM2413::keyOff_BD()
763 Channel& ch6 = channels[6];
764 if (ch6.car.slot_on_flag) {
766 ch6.mod.slot_on_flag &= ~2;
767 if (!ch6.car.slot_on_flag) {
772 void YM2413::keyOff_HH()
774 Channel& ch7 = channels[7];
775 if (ch7.mod.slot_on_flag) {
777 if (!ch7.mod.slot_on_flag) {
782 void YM2413::keyOff_SD()
784 Channel& ch7 = channels[7];
785 if (ch7.car.slot_on_flag) {
787 if (!ch7.car.slot_on_flag) {
792 void YM2413::keyOff_TOM()
794 Channel& ch8 = channels[8];
795 if (ch8.mod.slot_on_flag) {
797 if (!ch8.mod.slot_on_flag) {
802 void YM2413::keyOff_CYM()
804 Channel& ch8 = channels[8];
805 if (ch8.car.slot_on_flag) {
807 if (!ch8.car.slot_on_flag) {
813 void YM2413::setRhythmFlags(uint8_t old)
815 Channel& ch6 = channels[6];
816 Channel& ch7 = channels[7];
817 Channel& ch8 = channels[8];
820 uint8_t flags = reg[0x0E];
821 if ((flags ^ old) & 0x20) {
824 ch6.setPatch(16, *
this);
825 ch7.setPatch(17, *
this);
826 ch7.mod.setVolume(reg[0x37] >> 4);
827 ch8.setPatch(18, *
this);
828 ch8.mod.setVolume(reg[0x38] >> 4);
831 ch6.setPatch(reg[0x36] >> 4, *
this);
833 ch7.setPatch(reg[0x37] >> 4, *
this);
836 ch8.setPatch(reg[0x38] >> 4, *
this);
842 if (flags & 0x10) keyOn_BD();
else keyOff_BD();
843 if (flags & 0x08) keyOn_SD();
else keyOff_SD();
844 if (flags & 0x04) keyOn_TOM();
else keyOff_TOM();
845 if (flags & 0x02) keyOn_CYM();
else keyOff_CYM();
846 if (flags & 0x01) keyOn_HH();
else keyOff_HH();
849 unsigned freq6 = getFreq(6);
850 ch6.mod.updateAll(freq6,
false);
851 ch6.car.updateAll(freq6,
true);
852 unsigned freq7 = getFreq(7);
853 ch7.mod.updateAll(freq7, isRhythm());
854 ch7.car.updateAll(freq7,
true);
855 unsigned freq8 = getFreq(8);
856 ch8.mod.updateAll(freq8, isRhythm());
857 ch8.car.updateAll(freq8,
true);
860 void YM2413::update_key_status()
862 for (
auto [i, ch] :
enumerate(channels)) {
863 int slot_on = (reg[0x20 + i] & 0x10) ? 1 : 0;
864 ch.mod.slot_on_flag = slot_on;
865 ch.car.slot_on_flag = slot_on;
868 Channel& ch6 = channels[6];
870 ch6.car.slot_on_flag |= (reg[0x0e] & 0x10) ? 2 : 0;
871 Channel& ch7 = channels[7];
873 ch7.car.slot_on_flag |= (reg[0x0e] & 0x08) ? 2 : 0;
874 Channel& ch8 = channels[8];
876 ch8.car.slot_on_flag |= (reg[0x0e] & 0x02) ? 2 : 0;
881 static constexpr
int wave2_8pi(
int e)
929 template<
bool HAS_AM,
bool FIXED_ENV>
934 if constexpr (FIXED_ENV) {
935 unsigned out = fixed_env;
936 if constexpr (HAS_AM) {
952 out = EG2DB(out +
tll);
953 if constexpr (HAS_AM) {
964 out = EG2DB(out +
tll);
965 if constexpr (!HAS_AM) {
972 template<
bool HAS_AM,
bool FIXED_ENV>
975 int phase =
calc_phase(lfo_pm) + wave2_8pi(fm);
976 unsigned egOut = calc_envelope<HAS_AM, FIXED_ENV>(lfo_am, fixed_env);
983 template<
bool HAS_AM,
bool HAS_FB,
bool FIXED_ENV>
986 assert((
patch.
FB != 0) == HAS_FB);
988 unsigned egOut = calc_envelope<HAS_AM, FIXED_ENV>(lfo_am, fixed_env);
989 if constexpr (HAS_FB) {
1002 unsigned egOut = calc_envelope<false, false>(0, 0);
1010 unsigned egOut = calc_envelope<false, false>(0, 0);
1011 return BIT(phase, 7)
1012 ?
dB2LinTab[(noise ? DB_POS(0.0) : DB_POS(15.0)) + egOut]
1013 :
dB2LinTab[(noise ? DB_NEG(0.0) : DB_NEG(15.0)) + egOut];
1019 unsigned egOut = calc_envelope<false, false>(0, 0);
1020 unsigned dbOut = (((BIT(phase7,
PG_BITS - 8) ^
1033 unsigned egOut = calc_envelope<false, false>(0, 0);
1034 unsigned dbOut = (((BIT(phase7,
PG_BITS - 8) ^
1039 ? (noise ? DB_NEG(12.0) : DB_NEG(24.0))
1040 : (noise ? DB_POS(12.0) : DB_POS(24.0));
1049 bool YM2413::isRhythm()
const
1051 return (reg[0x0E] & 0x20) != 0;
1054 unsigned YM2413::getFreq(
unsigned channel)
const
1057 assert(channel < 9);
1058 return reg[0x10 + channel] | ((reg[0x20 + channel] & 0x0F) << 8);
1063 return patches[instrument][carrier];
1066 template<
unsigned FLAGS>
1070 const bool HAS_CAR_PM = (FLAGS & 1) != 0;
1071 const bool HAS_CAR_AM = (FLAGS & 2) != 0;
1072 const bool HAS_MOD_PM = (FLAGS & 4) != 0;
1073 const bool HAS_MOD_AM = (FLAGS & 8) != 0;
1074 const bool HAS_MOD_FB = (FLAGS & 16) != 0;
1075 const bool HAS_CAR_FIXED_ENV = (FLAGS & 32) != 0;
1076 const bool HAS_MOD_FIXED_ENV = (FLAGS & 64) != 0;
1083 unsigned tmp_pm_phase = pm_phase;
1084 unsigned tmp_am_phase = am_phase;
1085 unsigned car_fixed_env = 0;
1086 unsigned mod_fixed_env = 0;
1087 if constexpr (HAS_CAR_FIXED_ENV) {
1090 if constexpr (HAS_MOD_FIXED_ENV) {
1094 unsigned sample = 0;
1096 unsigned lfo_pm = 0;
1097 if constexpr (HAS_CAR_PM || HAS_MOD_PM) {
1103 lfo_pm = (tmp_pm_phase >> 10) & 7;
1106 if constexpr (HAS_CAR_AM || HAS_MOD_AM) {
1114 HAS_MOD_PM ? lfo_pm : 0, lfo_am, mod_fixed_env);
1116 HAS_CAR_PM ? lfo_pm : 0, lfo_am, fm, car_fixed_env);
1118 }
while (sample < num);
1125 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1134 modFixedEnv =
false;
1139 ( carFixedEnv << 5) |
1140 ( modFixedEnv << 6);
1142 case 0: calcChannel< 0>(ch, bufs[i], num);
break;
1143 case 1: calcChannel< 1>(ch, bufs[i], num);
break;
1144 case 2: calcChannel< 2>(ch, bufs[i], num);
break;
1145 case 3: calcChannel< 3>(ch, bufs[i], num);
break;
1146 case 4: calcChannel< 4>(ch, bufs[i], num);
break;
1147 case 5: calcChannel< 5>(ch, bufs[i], num);
break;
1148 case 6: calcChannel< 6>(ch, bufs[i], num);
break;
1149 case 7: calcChannel< 7>(ch, bufs[i], num);
break;
1150 case 8: calcChannel< 8>(ch, bufs[i], num);
break;
1151 case 9: calcChannel< 9>(ch, bufs[i], num);
break;
1152 case 10: calcChannel< 10>(ch, bufs[i], num);
break;
1153 case 11: calcChannel< 11>(ch, bufs[i], num);
break;
1154 case 12: calcChannel< 12>(ch, bufs[i], num);
break;
1155 case 13: calcChannel< 13>(ch, bufs[i], num);
break;
1156 case 14: calcChannel< 14>(ch, bufs[i], num);
break;
1157 case 15: calcChannel< 15>(ch, bufs[i], num);
break;
1158 case 16: calcChannel< 16>(ch, bufs[i], num);
break;
1159 case 17: calcChannel< 17>(ch, bufs[i], num);
break;
1160 case 18: calcChannel< 18>(ch, bufs[i], num);
break;
1161 case 19: calcChannel< 19>(ch, bufs[i], num);
break;
1162 case 20: calcChannel< 20>(ch, bufs[i], num);
break;
1163 case 21: calcChannel< 21>(ch, bufs[i], num);
break;
1164 case 22: calcChannel< 22>(ch, bufs[i], num);
break;
1165 case 23: calcChannel< 23>(ch, bufs[i], num);
break;
1166 case 24: calcChannel< 24>(ch, bufs[i], num);
break;
1167 case 25: calcChannel< 25>(ch, bufs[i], num);
break;
1168 case 26: calcChannel< 26>(ch, bufs[i], num);
break;
1169 case 27: calcChannel< 27>(ch, bufs[i], num);
break;
1170 case 28: calcChannel< 28>(ch, bufs[i], num);
break;
1171 case 29: calcChannel< 29>(ch, bufs[i], num);
break;
1172 case 30: calcChannel< 30>(ch, bufs[i], num);
break;
1173 case 31: calcChannel< 31>(ch, bufs[i], num);
break;
1174 case 32: calcChannel< 32>(ch, bufs[i], num);
break;
1175 case 33: calcChannel< 33>(ch, bufs[i], num);
break;
1176 case 34: calcChannel< 34>(ch, bufs[i], num);
break;
1177 case 35: calcChannel< 35>(ch, bufs[i], num);
break;
1178 case 36: calcChannel< 36>(ch, bufs[i], num);
break;
1179 case 37: calcChannel< 37>(ch, bufs[i], num);
break;
1180 case 38: calcChannel< 38>(ch, bufs[i], num);
break;
1181 case 39: calcChannel< 39>(ch, bufs[i], num);
break;
1182 case 40: calcChannel< 40>(ch, bufs[i], num);
break;
1183 case 41: calcChannel< 41>(ch, bufs[i], num);
break;
1184 case 42: calcChannel< 42>(ch, bufs[i], num);
break;
1185 case 43: calcChannel< 43>(ch, bufs[i], num);
break;
1186 case 44: calcChannel< 44>(ch, bufs[i], num);
break;
1187 case 45: calcChannel< 45>(ch, bufs[i], num);
break;
1188 case 46: calcChannel< 46>(ch, bufs[i], num);
break;
1189 case 47: calcChannel< 47>(ch, bufs[i], num);
break;
1190 case 48: calcChannel< 48>(ch, bufs[i], num);
break;
1191 case 49: calcChannel< 49>(ch, bufs[i], num);
break;
1192 case 50: calcChannel< 50>(ch, bufs[i], num);
break;
1193 case 51: calcChannel< 51>(ch, bufs[i], num);
break;
1194 case 52: calcChannel< 52>(ch, bufs[i], num);
break;
1195 case 53: calcChannel< 53>(ch, bufs[i], num);
break;
1196 case 54: calcChannel< 54>(ch, bufs[i], num);
break;
1197 case 55: calcChannel< 55>(ch, bufs[i], num);
break;
1198 case 56: calcChannel< 56>(ch, bufs[i], num);
break;
1199 case 57: calcChannel< 57>(ch, bufs[i], num);
break;
1200 case 58: calcChannel< 58>(ch, bufs[i], num);
break;
1201 case 59: calcChannel< 59>(ch, bufs[i], num);
break;
1202 case 60: calcChannel< 60>(ch, bufs[i], num);
break;
1203 case 61: calcChannel< 61>(ch, bufs[i], num);
break;
1204 case 62: calcChannel< 62>(ch, bufs[i], num);
break;
1205 case 63: calcChannel< 63>(ch, bufs[i], num);
break;
1206 case 64: calcChannel< 64>(ch, bufs[i], num);
break;
1207 case 65: calcChannel< 65>(ch, bufs[i], num);
break;
1208 case 66: calcChannel< 66>(ch, bufs[i], num);
break;
1209 case 67: calcChannel< 67>(ch, bufs[i], num);
break;
1210 case 68: calcChannel< 68>(ch, bufs[i], num);
break;
1211 case 69: calcChannel< 69>(ch, bufs[i], num);
break;
1212 case 70: calcChannel< 70>(ch, bufs[i], num);
break;
1213 case 71: calcChannel< 71>(ch, bufs[i], num);
break;
1214 case 72: calcChannel< 72>(ch, bufs[i], num);
break;
1215 case 73: calcChannel< 73>(ch, bufs[i], num);
break;
1216 case 74: calcChannel< 74>(ch, bufs[i], num);
break;
1217 case 75: calcChannel< 75>(ch, bufs[i], num);
break;
1218 case 76: calcChannel< 76>(ch, bufs[i], num);
break;
1219 case 77: calcChannel< 77>(ch, bufs[i], num);
break;
1220 case 78: calcChannel< 78>(ch, bufs[i], num);
break;
1221 case 79: calcChannel< 79>(ch, bufs[i], num);
break;
1222 case 80: calcChannel< 80>(ch, bufs[i], num);
break;
1223 case 81: calcChannel< 81>(ch, bufs[i], num);
break;
1224 case 82: calcChannel< 82>(ch, bufs[i], num);
break;
1225 case 83: calcChannel< 83>(ch, bufs[i], num);
break;
1226 case 84: calcChannel< 84>(ch, bufs[i], num);
break;
1227 case 85: calcChannel< 85>(ch, bufs[i], num);
break;
1228 case 86: calcChannel< 86>(ch, bufs[i], num);
break;
1229 case 87: calcChannel< 87>(ch, bufs[i], num);
break;
1230 case 88: calcChannel< 88>(ch, bufs[i], num);
break;
1231 case 89: calcChannel< 89>(ch, bufs[i], num);
break;
1232 case 90: calcChannel< 90>(ch, bufs[i], num);
break;
1233 case 91: calcChannel< 91>(ch, bufs[i], num);
break;
1234 case 92: calcChannel< 92>(ch, bufs[i], num);
break;
1235 case 93: calcChannel< 93>(ch, bufs[i], num);
break;
1236 case 94: calcChannel< 94>(ch, bufs[i], num);
break;
1237 case 95: calcChannel< 95>(ch, bufs[i], num);
break;
1238 case 96: calcChannel< 96>(ch, bufs[i], num);
break;
1239 case 97: calcChannel< 97>(ch, bufs[i], num);
break;
1240 case 98: calcChannel< 98>(ch, bufs[i], num);
break;
1241 case 99: calcChannel< 99>(ch, bufs[i], num);
break;
1242 case 100: calcChannel<100>(ch, bufs[i], num);
break;
1243 case 101: calcChannel<101>(ch, bufs[i], num);
break;
1244 case 102: calcChannel<102>(ch, bufs[i], num);
break;
1245 case 103: calcChannel<103>(ch, bufs[i], num);
break;
1246 case 104: calcChannel<104>(ch, bufs[i], num);
break;
1247 case 105: calcChannel<105>(ch, bufs[i], num);
break;
1248 case 106: calcChannel<106>(ch, bufs[i], num);
break;
1249 case 107: calcChannel<107>(ch, bufs[i], num);
break;
1250 case 108: calcChannel<108>(ch, bufs[i], num);
break;
1251 case 109: calcChannel<109>(ch, bufs[i], num);
break;
1252 case 110: calcChannel<110>(ch, bufs[i], num);
break;
1253 case 111: calcChannel<111>(ch, bufs[i], num);
break;
1254 case 112: calcChannel<112>(ch, bufs[i], num);
break;
1255 case 113: calcChannel<113>(ch, bufs[i], num);
break;
1256 case 114: calcChannel<114>(ch, bufs[i], num);
break;
1257 case 115: calcChannel<115>(ch, bufs[i], num);
break;
1258 case 116: calcChannel<116>(ch, bufs[i], num);
break;
1259 case 117: calcChannel<117>(ch, bufs[i], num);
break;
1260 case 118: calcChannel<118>(ch, bufs[i], num);
break;
1261 case 119: calcChannel<119>(ch, bufs[i], num);
break;
1262 case 120: calcChannel<120>(ch, bufs[i], num);
break;
1263 case 121: calcChannel<121>(ch, bufs[i], num);
break;
1264 case 122: calcChannel<122>(ch, bufs[i], num);
break;
1265 case 123: calcChannel<123>(ch, bufs[i], num);
break;
1266 case 124: calcChannel<124>(ch, bufs[i], num);
break;
1267 case 125: calcChannel<125>(ch, bufs[i], num);
break;
1268 case 126: calcChannel<126>(ch, bufs[i], num);
break;
1269 case 127: calcChannel<127>(ch, bufs[i], num);
break;
1289 unsigned old_noise = noise_seed;
1294 for (
auto sample :
xrange(num)) {
1295 bufs[ 9][sample] += 2 *
1298 false,
false,
false>(0, 0, 0), 0);
1305 for (
auto sample :
xrange(num)) {
1307 bool noise_bit = noise_seed & 1;
1308 if (noise_bit) noise_seed ^= 0x8003020;
1317 for (
auto sample :
xrange(num)) {
1329 noise_seed = old_noise;
1332 for (
auto sample :
xrange(num)) {
1334 bool noise_bit = noise_seed & 1;
1335 if (noise_bit) noise_seed ^= 0x8003020;
1346 for (
auto sample :
xrange(num)) {
1364 registerLatch = value;
1366 writeReg(registerLatch & 0x3f, value);
1375 void YM2413::writeReg(uint8_t r, uint8_t data)
1382 patches[0][0].
AMPM = (data >> 6) & 3;
1383 patches[0][0].
EG = (data >> 5) & 1;
1384 patches[0][0].
setKR ((data >> 4) & 1);
1385 patches[0][0].
setML ((data >> 0) & 15);
1386 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1387 if ((reg[0x30 + i] & 0xF0) == 0) {
1390 unsigned freq = getFreq(i);
1400 patches[0][1].
AMPM = (data >> 6) & 3;
1401 patches[0][1].
EG = (data >> 5) & 1;
1402 patches[0][1].
setKR ((data >> 4) & 1);
1403 patches[0][1].
setML ((data >> 0) & 15);
1404 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1405 if ((reg[0x30 + i] & 0xF0) == 0) {
1406 Channel& ch = channels[i];
1408 unsigned freq = getFreq(i);
1409 ch.car.updatePG (freq);
1410 ch.car.updateRKS(freq);
1418 patches[0][0].
setKL((data >> 6) & 3);
1419 patches[0][0].
setTL((data >> 0) & 63);
1420 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1421 if ((reg[0x30 + i] & 0xF0) == 0) {
1422 Channel& ch = channels[i];
1424 bool actAsCarrier = (i >= 7) && isRhythm();
1425 assert(!actAsCarrier); (void)actAsCarrier;
1426 ch.mod.updateTLL(getFreq(i),
false);
1433 patches[0][1].
setKL((data >> 6) & 3);
1434 patches[0][1].
setWF((data >> 4) & 1);
1435 patches[0][0].
setWF((data >> 3) & 1);
1436 patches[0][0].
setFB((data >> 0) & 7);
1437 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1438 if ((reg[0x30 + i] & 0xF0) == 0) {
1439 Channel& ch = channels[i];
1447 patches[0][0].
AR = (data >> 4) & 15;
1448 patches[0][0].
DR = (data >> 0) & 15;
1449 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1450 if ((reg[0x30 + i] & 0xF0) == 0) {
1451 Channel& ch = channels[i];
1454 if (ch.mod.state ==
ATTACK) {
1455 ch.mod.setEnvelopeState(
ATTACK);
1463 patches[0][1].
AR = (data >> 4) & 15;
1464 patches[0][1].
DR = (data >> 0) & 15;
1465 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1466 if ((reg[0x30 + i] & 0xF0) == 0) {
1467 Channel& ch = channels[i];
1470 if (ch.car.state ==
ATTACK) {
1471 ch.car.setEnvelopeState(
ATTACK);
1479 patches[0][0].
setSL((data >> 4) & 15);
1480 patches[0][0].
RR = (data >> 0) & 15;
1481 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1482 if ((reg[0x30 + i] & 0xF0) == 0) {
1483 Channel& ch = channels[i];
1486 if (ch.mod.state ==
DECAY) {
1487 ch.mod.setEnvelopeState(
DECAY);
1495 patches[0][1].
setSL((data >> 4) & 15);
1496 patches[0][1].
RR = (data >> 0) & 15;
1497 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1498 if ((reg[0x30 + i] & 0xF0) == 0) {
1499 Channel& ch = channels[i];
1502 if (ch.car.state ==
DECAY) {
1503 ch.car.setEnvelopeState(
DECAY);
1510 uint8_t old = reg[r];
1512 setRhythmFlags(old);
1515 case 0x19:
case 0x1A:
case 0x1B:
case 0x1C:
1516 case 0x1D:
case 0x1E:
case 0x1F:
1519 case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
1520 case 0x15:
case 0x16:
case 0x17:
case 0x18: {
1522 unsigned cha = r & 0x0F; assert(cha < 9);
1523 Channel& ch = channels[cha];
1524 bool actAsCarrier = (cha >= 7) && isRhythm();
1525 unsigned freq = getFreq(cha);
1526 ch.mod.updateAll(freq, actAsCarrier);
1527 ch.car.updateAll(freq,
true);
1530 case 0x29:
case 0x2A:
case 0x2B:
case 0x2C:
1531 case 0x2D:
case 0x2E:
case 0x2F:
1534 case 0x20:
case 0x21:
case 0x22:
case 0x23:
case 0x24:
1535 case 0x25:
case 0x26:
case 0x27:
case 0x28: {
1537 unsigned cha = r & 0x0F; assert(cha < 9);
1538 Channel& ch = channels[cha];
1539 bool modActAsCarrier = (cha >= 7) && isRhythm();
1540 ch.setSustain((data >> 5) & 1, modActAsCarrier);
1546 unsigned freq = getFreq(cha);
1547 ch.mod.updateAll(freq, modActAsCarrier);
1548 ch.car.updateAll(freq,
true);
1551 case 0x39:
case 0x3A:
case 0x3B:
case 0x3C:
1552 case 0x3D:
case 0x3E:
case 0x3F:
1555 case 0x30:
case 0x31:
case 0x32:
case 0x33:
case 0x34:
1556 case 0x35:
case 0x36:
case 0x37:
case 0x38: {
1558 unsigned cha = r & 0x0F; assert(cha < 9);
1559 Channel& ch = channels[cha];
1560 if (isRhythm() && (cha >= 6)) {
1566 ch.setPatch(data >> 4, *
this);
1568 ch.car.setVolume(data & 15);
1569 bool actAsCarrier = (cha >= 7) && isRhythm();
1570 unsigned freq = getFreq(cha);
1571 ch.mod.updateAll(freq, actAsCarrier);
1572 ch.car.updateAll(freq,
true);
1587 static constexpr std::initializer_list<enum_string<YM2413Okazaki::EnvelopeState>> envelopeStateInfo = {
1598 namespace YM2413Okazaki {
1605 template<
typename Archive>
1625 template<
typename Archive>
1628 ar.serialize(
"mod",
mod,
1637 template<
typename Archive>
1640 if (ar.versionBelow(version, 2)) ar.beginTag(
"YM2413Core");
1641 ar.serialize(
"registers", reg);
1642 if (ar.versionBelow(version, 2)) ar.endTag(
"YM2413Core");
1646 ar.serialize(
"channels", channels,
1647 "pm_phase", pm_phase,
1648 "am_phase", am_phase,
1649 "noise_seed", noise_seed);
1651 if constexpr (Archive::IS_LOADER) {
1654 for (
auto [i, ch] :
enumerate(channels)) {
1656 unsigned p = ((i >= 6) && isRhythm())
1657 ?
unsigned(16 + (i - 6))
1658 : (reg[0x30 + i] >> 4);
1659 ch.setPatch(p, *
this);
1661 ch.car.setVolume(reg[0x30 + i] & 15);
1662 if (isRhythm() && (i >= 7)) {
1663 ch.mod.setVolume(reg[0x30 + i] >> 4);
1666 bool actAsCarrier = (i >= 7) && isRhythm();
1667 unsigned freq = getFreq(
unsigned(i));
1668 ch.mod.updateAll(freq, actAsCarrier);
1669 ch.car.updateAll(freq,
true);
1670 ch.mod.setEnvelopeState(ch.mod.state);
1671 ch.car.setEnvelopeState(ch.car.state);
1673 update_key_status();
1675 if (ar.versionAtLeast(version, 4)) {
1676 ar.serialize(
"registerLatch", registerLatch);
static constexpr FixedPoint create(int value)
Create new fixed point object from given representation.
constexpr int toInt() const
Returns the integer part (rounded down) of this fixed point number.
Abstract interface for the YM2413 core.
void serialize(Archive &ar, unsigned version)
void setSustain(bool sustain, bool modActAsCarrier)
void setPatch(unsigned num, YM2413 &ym2413)
void reset(YM2413 &ym2413)
void setSL(uint8_t value)
Sets sustain level [0..15].
void setFB(uint8_t value)
Sets the amount of feedback [0..7].
Patch()
Creates an uninitialized Patch object; call initXXX() before use.
void initCarrier(const uint8_t *data)
void setTL(uint8_t value)
Set volume (total level) [0..63].
void initModulator(const uint8_t *data)
void setKL(uint8_t value)
Sets Key scale level [0..3].
void setML(uint8_t value)
Sets the frequency multiplier factor [0..15].
void setWF(uint8_t value)
Set waveform [0..1].
void setKR(uint8_t value)
Sets the Key Scale of Rate (0 or 1).
void serialize(Archive &ar, unsigned version)
void setVolume(unsigned value)
int calc_slot_snare(bool noise)
int calc_slot_mod(unsigned lfo_pm, int lfo_am, unsigned fixed_env)
void setPatch(const Patch &patch)
void updateTLL(unsigned freq, bool actAsCarrier)
void calc_envelope_outline(unsigned &out)
EnvPhaseIndex eg_phase_max
void updatePG(unsigned freq)
void updateRKS(unsigned freq)
const int * dPhaseDRTableRks
void setEnvelopeState(EnvelopeState state)
unsigned calc_envelope(int lfo_am, unsigned fixed_env)
unsigned calc_phase(unsigned lfo_pm)
unsigned calc_fixed_env() const
int calc_slot_hat(unsigned phase7, unsigned phase8, bool noise)
int calc_slot_cym(unsigned phase7, unsigned phase8)
int calc_slot_car(unsigned lfo_pm, int lfo_am, int fm, unsigned fixed_env)
void updateAll(unsigned freq, bool actAsCarrier)
void generateChannels(float *bufs[9+5], unsigned num) override
uint8_t peekReg(uint8_t reg) const override
Read from a YM2413 register (for debug).
void serialize(Archive &ar, unsigned version)
void writePort(bool port, uint8_t value, int offset) override
Write to the YM2413 register/data port.
void pokeReg(uint8_t reg, uint8_t data) override
Write to a YM2413 register (for debug).
float getAmplificationFactor() const override
Returns normalization factor.
void reset() override
Reset this YM2413 core.
Patch & getPatch(unsigned instrument, bool carrier)
constexpr auto enumerate(Iterable &&iterable)
Heavily inspired by Nathan Reed's blog post: Python-Like enumerate() In C++17 http://reedbeta....
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
constexpr EnvPhaseIndex EG_DP_MAX
constexpr uint8_t mlTable[16]
constexpr auto fullSinTable
constexpr int SLOT_AMP_BITS
constexpr int DB2LIN_AMP_BITS
constexpr auto halfSinTable
constexpr unsigned char lfo_am_table[LFO_AM_TAB_ELEMENTS]
constexpr unsigned LFO_AM_TAB_ELEMENTS
constexpr int AM_PG_WIDTH
constexpr signed char pmTable[8][8]
constexpr EnvPhaseIndex EG_DP_INF
constexpr int DP_BASE_BITS
constexpr int AM_DP_WIDTH
constexpr auto arAdjustTab
constexpr unsigned const *const waveform[2]
FixedPoint< EP_FP_BITS > EnvPhaseIndex
constexpr auto dPhaseDrTab
This file implemented 3 utility functions:
SERIALIZE_ENUM(CassettePlayer::State, stateInfo)
REGISTER_POLYMORPHIC_INITIALIZER(Pluggable, CassettePlayer, "CassettePlayer")
constexpr KeyMatrixPosition x
Keyboard bindings.
void fill(ForwardRange &&range, const T &value)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
constexpr auto xrange(T e)