23namespace YM2413Okazaki {
26static constexpr int PM_FP_BITS = 8;
29static constexpr int DB_BITS = 8;
30static constexpr int DB_MUTE = 1 << DB_BITS;
31static constexpr int DBTABLEN = 4 * DB_MUTE;
33static constexpr double DB_STEP = 48.0 / DB_MUTE;
34static constexpr double EG_STEP = 0.375;
35static constexpr double TL_STEP = 0.75;
38static constexpr int DP_BITS = 18;
39static constexpr int DP_BASE_BITS = DP_BITS -
PG_BITS;
42static constexpr int EG_BITS = 7;
45static constexpr int DB2LIN_AMP_BITS = 8;
46static constexpr int SLOT_AMP_BITS = DB2LIN_AMP_BITS;
49static constexpr int AM_PG_BITS = 8;
50static constexpr int AM_PG_WIDTH = 1 << AM_PG_BITS;
51static constexpr int AM_DP_BITS = 16;
52static constexpr int AM_DP_WIDTH = 1 << AM_DP_BITS;
53static constexpr int AM_DP_MASK = AM_DP_WIDTH - 1;
70static constexpr unsigned LFO_AM_TAB_ELEMENTS = 210;
77static constexpr std::array pmTable = {
78 std::array<int8_t, 8>{0, 0, 0, 0, 0, 0, 0, 0},
79 std::array<int8_t, 8>{0, 0, 1, 0, 0, 0,-1, 0},
80 std::array<int8_t, 8>{0, 1, 2, 1, 0,-1,-2,-1},
81 std::array<int8_t, 8>{0, 1, 3, 1, 0,-1,-3,-1},
82 std::array<int8_t, 8>{0, 2, 4, 2, 0,-2,-4,-2},
83 std::array<int8_t, 8>{0, 2, 5, 2, 0,-2,-5,-2},
84 std::array<int8_t, 8>{0, 3, 6, 3, 0,-3,-6,-3},
85 std::array<int8_t, 8>{0, 3, 7, 3, 0,-3,-7,-3},
89static constexpr std::array<uint8_t, LFO_AM_TAB_ELEMENTS> lfo_am_table = {
145static constexpr std::array<uint8_t, 16> mlTable = {
146 1, 1*2, 2*2, 3*2, 4*2, 5*2, 6*2, 7*2,
147 8*2, 9*2, 10*2, 10*2, 12*2, 12*2, 15*2, 15*2
156static constexpr auto dB2LinTab = [] {
157 std::array<int, 2 * DBTABLEN> result = {};
158 for (
int i :
xrange(DB_MUTE - 1)) {
159 result[i] = int(
double((1 << DB2LIN_AMP_BITS) - 1) *
160 cstd::pow<5, 3>(10, -
double(i) * DB_STEP / 20));
162 result[DB_MUTE - 1] = 0;
163 for (
auto i :
xrange(DB_MUTE, DBTABLEN)) {
166 for (
auto i :
xrange(DBTABLEN)) {
167 result[i + DBTABLEN] = -result[i];
173static constexpr auto arAdjustTab = [] {
174 std::array<unsigned, 1 << EG_BITS> result = {};
175 result[0] = (1 << EG_BITS) - 1;
176 constexpr double l127 = cstd::log<5, 4>(127.0);
177 for (
int i :
xrange(1, 1 << EG_BITS)) {
178 result[i] = unsigned(
double(1 << EG_BITS) - 1 -
179 ((1 << EG_BITS) - 1) * cstd::log<5, 4>(
double(i)) / l127);
185static constexpr auto tllTab = [] {
186 std::array<std::array<uint8_t, 16 * 8>, 4> result = {};
189 constexpr std::array<int, 16> klTable = {
190 0, 24, 32, 37, 40, 43, 45, 47, 48, 50, 51, 52, 53, 54, 55, 56
196 for (
auto freq :
xrange(16 * 8)) {
197 int fnum = freq % 16;
198 int block = freq / 16;
199 int tmp = 2 * klTable[fnum] - 16 * (7 - block);
200 for (
auto KL :
xrange(4)) {
201 unsigned t = (tmp <= 0 || KL == 0) ? 0 : (tmp >> (3 - KL));
203 result[KL][freq] = narrow<uint8_t>(
t);
212static constexpr auto fullSinTable = [] {
213 auto lin2db = [](
double d) {
217 :
std::min(-
int(20.0 * cstd::log10<5, 2>(d) / DB_STEP), DB_MUTE - 1);
220 std::array<unsigned, PG_WIDTH> result = {};
225 result[
PG_WIDTH / 2 - 1 - i] = result[i];
228 result[
PG_WIDTH / 2 + i] = DBTABLEN + result[i];
232static constexpr auto halfSinTable = [] {
233 std::array<unsigned, PG_WIDTH> result = {};
235 result[i] = fullSinTable[i];
238 result[i] = fullSinTable[0];
242static constexpr std::array<std::span<const unsigned, PG_WIDTH>, 2> waveform = {
243 fullSinTable, halfSinTable
250static constexpr auto dPhaseDrTab = [] {
251 std::array<std::array<int, 16>, 16> result = {};
252 for (
auto Rks :
xrange(16)) {
254 for (
auto DR :
xrange(1, 16)) {
255 int RM =
std::min(DR + (Rks >> 2), 15);
265static constexpr auto slTab = [] {
266 std::array<unsigned, 16> result = {};
268 for (
int i = 0; i < 16; ++i) {
269 double x = (i == 15) ? 48.0 : (3.0 * i);
278static constexpr unsigned EG2DB(
unsigned d)
280 return d * narrow_cast<unsigned>(EG_STEP / DB_STEP);
282static constexpr unsigned TL2EG(
unsigned d)
285 return d * narrow_cast<unsigned>(TL_STEP / EG_STEP);
288static constexpr unsigned DB_POS(
double x)
290 int result = int(x / DB_STEP);
292 assert(result < DB_MUTE);
295static constexpr unsigned DB_NEG(
double x)
297 return DBTABLEN + DB_POS(x);
303static constexpr int BIT(
unsigned s,
unsigned b)
305 return narrow<int>((s >> b) & 1);
312 : WF(waveform[0]), KL(tllTab[0])
323 AMPM = (data[0] >> 6) & 3;
324 EG = (data[0] >> 5) & 1;
325 setKR ((data[0] >> 4) & 1);
326 setML ((data[0] >> 0) & 15);
327 setKL ((data[2] >> 6) & 3);
328 setTL ((data[2] >> 0) & 63);
329 setWF ((data[3] >> 3) & 1);
330 setFB ((data[3] >> 0) & 7);
331 AR = (data[4] >> 4) & 15;
332 DR = (data[4] >> 0) & 15;
333 setSL ((data[6] >> 4) & 15);
334 RR = (data[6] >> 0) & 15;
339 AMPM = (data[1] >> 6) & 3;
340 EG = (data[1] >> 5) & 1;
341 setKR ((data[1] >> 4) & 1);
342 setML ((data[1] >> 0) & 15);
343 setKL ((data[3] >> 6) & 3);
345 setWF ((data[3] >> 4) & 1);
347 AR = (data[5] >> 4) & 15;
348 DR = (data[5] >> 0) & 15;
349 setSL ((data[7] >> 4) & 15);
350 RR = (data[7] >> 0) & 15;
368 TL = narrow<uint8_t>(TL2EG(value));
372 WF = waveform[value];
376 FB = value ? 8 - value : 0;
389 : dPhaseDRTableRks(dPhaseDrTab[0])
415 unsigned fnum = freq & 511;
416 unsigned block = freq / 512;
418 unsigned tmp = ((2 * fnum + pmTable[fnum >> 6][pm]) *
patch.
ML) << block;
419 dP = tmp >> (21 - DP_BITS);
430 unsigned rks = freq >>
patch.
KR;
566 volume = TL2EG(value << 2);
598 if (modActAsCarrier) {
635static constexpr std::array inst_data = {
636 std::array<uint8_t, 8>{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
637 std::array<uint8_t, 8>{ 0x61,0x61,0x1e,0x17,0xf0,0x7f,0x00,0x17 },
638 std::array<uint8_t, 8>{ 0x13,0x41,0x16,0x0e,0xfd,0xf4,0x23,0x23 },
639 std::array<uint8_t, 8>{ 0x03,0x01,0x9a,0x04,0xf3,0xf3,0x13,0xf3 },
640 std::array<uint8_t, 8>{ 0x11,0x61,0x0e,0x07,0xfa,0x64,0x70,0x17 },
641 std::array<uint8_t, 8>{ 0x22,0x21,0x1e,0x06,0xf0,0x76,0x00,0x28 },
642 std::array<uint8_t, 8>{ 0x21,0x22,0x16,0x05,0xf0,0x71,0x00,0x18 },
643 std::array<uint8_t, 8>{ 0x21,0x61,0x1d,0x07,0x82,0x80,0x17,0x17 },
644 std::array<uint8_t, 8>{ 0x23,0x21,0x2d,0x16,0x90,0x90,0x00,0x07 },
645 std::array<uint8_t, 8>{ 0x21,0x21,0x1b,0x06,0x64,0x65,0x10,0x17 },
646 std::array<uint8_t, 8>{ 0x21,0x21,0x0b,0x1a,0x85,0xa0,0x70,0x07 },
647 std::array<uint8_t, 8>{ 0x23,0x01,0x83,0x10,0xff,0xb4,0x10,0xf4 },
648 std::array<uint8_t, 8>{ 0x97,0xc1,0x20,0x07,0xff,0xf4,0x22,0x22 },
649 std::array<uint8_t, 8>{ 0x61,0x00,0x0c,0x05,0xc2,0xf6,0x40,0x44 },
650 std::array<uint8_t, 8>{ 0x01,0x01,0x56,0x03,0x94,0xc2,0x03,0x12 },
651 std::array<uint8_t, 8>{ 0x21,0x01,0x89,0x03,0xf1,0xe4,0xf0,0x23 },
652 std::array<uint8_t, 8>{ 0x07,0x21,0x14,0x00,0xee,0xf8,0xff,0xf8 },
653 std::array<uint8_t, 8>{ 0x01,0x31,0x00,0x00,0xf8,0xf7,0xf8,0xf7 },
654 std::array<uint8_t, 8>{ 0x25,0x11,0x00,0x00,0xf8,0xfa,0xf8,0x55 }
660 for (
const auto&
e : dB2LinTab) std::cout <<
e <<
' ';
663 for (
const auto&
e : arAdjustTab) std::cout <<
e <<
' ';
666 for (
auto i :
xrange(4)) {
667 for (
auto j :
xrange(16 * 8)) {
668 std::cout << int(tllTab[i][j]) <<
' ';
674 for (
const auto&
e : fullSinTable) std::cout <<
e <<
' ';
676 for (
const auto&
e : halfSinTable) std::cout <<
e <<
' ';
679 for (
auto i :
xrange(16)) {
680 for (
auto j :
xrange(16)) {
681 std::cout << dPhaseDrTab[i][j] <<
' ';
687 for (
const auto&
e : slTab) std::cout <<
e <<
' ';
693 for (
auto i :
xrange(16 + 3)) {
694 patches[i][0].initModulator(inst_data[i]);
695 patches[i][1].initCarrier (inst_data[i]);
708 for (
auto& ch : channels) {
711 for (
auto i :
xrange(uint8_t(0x40))) {
718void YM2413::keyOn_BD()
728void YM2413::keyOn_HH()
731 Channel& ch7 = channels[7];
732 if (!ch7.mod.slot_on_flag) {
735 ch7.mod.slot_on_flag |= 2;
737void YM2413::keyOn_SD()
739 Channel& ch7 = channels[7];
740 if (!ch7.car.slot_on_flag) {
743 ch7.car.slot_on_flag |= 2;
745void YM2413::keyOn_TOM()
747 Channel& ch8 = channels[8];
748 if (!ch8.mod.slot_on_flag) {
751 ch8.mod.slot_on_flag |= 2;
753void YM2413::keyOn_CYM()
755 Channel& ch8 = channels[8];
756 if (!ch8.car.slot_on_flag) {
759 ch8.car.slot_on_flag |= 2;
763void YM2413::keyOff_BD()
765 Channel& ch6 = channels[6];
766 if (ch6.car.slot_on_flag) {
767 ch6.car.slot_on_flag &= ~2;
768 ch6.mod.slot_on_flag &= ~2;
769 if (!ch6.car.slot_on_flag) {
774void YM2413::keyOff_HH()
776 Channel& ch7 = channels[7];
777 if (ch7.mod.slot_on_flag) {
778 ch7.mod.slot_on_flag &= ~2;
779 if (!ch7.mod.slot_on_flag) {
784void YM2413::keyOff_SD()
786 Channel& ch7 = channels[7];
787 if (ch7.car.slot_on_flag) {
788 ch7.car.slot_on_flag &= ~2;
789 if (!ch7.car.slot_on_flag) {
794void YM2413::keyOff_TOM()
796 Channel& ch8 = channels[8];
797 if (ch8.mod.slot_on_flag) {
798 ch8.mod.slot_on_flag &= ~2;
799 if (!ch8.mod.slot_on_flag) {
804void YM2413::keyOff_CYM()
806 Channel& ch8 = channels[8];
807 if (ch8.car.slot_on_flag) {
808 ch8.car.slot_on_flag &= ~2;
809 if (!ch8.car.slot_on_flag) {
815void YM2413::setRhythmFlags(uint8_t old)
817 Channel& ch6 = channels[6];
818 Channel& ch7 = channels[7];
819 Channel& ch8 = channels[8];
822 uint8_t flags = reg[0x0E];
823 if ((flags ^ old) & 0x20) {
826 ch6.setPatch(16, *
this);
827 ch7.setPatch(17, *
this);
828 ch7.mod.setVolume(reg[0x37] >> 4);
829 ch8.setPatch(18, *
this);
830 ch8.mod.setVolume(reg[0x38] >> 4);
833 ch6.setPatch(reg[0x36] >> 4, *
this);
835 ch7.setPatch(reg[0x37] >> 4, *
this);
838 ch8.setPatch(reg[0x38] >> 4, *
this);
844 if (flags & 0x10) keyOn_BD();
else keyOff_BD();
845 if (flags & 0x08) keyOn_SD();
else keyOff_SD();
846 if (flags & 0x04) keyOn_TOM();
else keyOff_TOM();
847 if (flags & 0x02) keyOn_CYM();
else keyOff_CYM();
848 if (flags & 0x01) keyOn_HH();
else keyOff_HH();
851 unsigned freq6 = getFreq(6);
852 ch6.mod.updateAll(freq6,
false);
853 ch6.car.updateAll(freq6,
true);
854 unsigned freq7 = getFreq(7);
855 ch7.mod.updateAll(freq7, isRhythm());
856 ch7.car.updateAll(freq7,
true);
857 unsigned freq8 = getFreq(8);
858 ch8.mod.updateAll(freq8, isRhythm());
859 ch8.car.updateAll(freq8,
true);
862void YM2413::update_key_status()
864 for (
auto [i, ch] :
enumerate(channels)) {
865 uint8_t slot_on = (reg[0x20 + i] & 0x10) ? 1 : 0;
866 ch.mod.slot_on_flag = slot_on;
867 ch.car.slot_on_flag = slot_on;
870 Channel& ch6 = channels[6];
871 ch6.mod.slot_on_flag |= uint8_t((reg[0x0e] & 0x10) ? 2 : 0);
872 ch6.car.slot_on_flag |= uint8_t((reg[0x0e] & 0x10) ? 2 : 0);
873 Channel& ch7 = channels[7];
874 ch7.mod.slot_on_flag |= uint8_t((reg[0x0e] & 0x01) ? 2 : 0);
875 ch7.car.slot_on_flag |= uint8_t((reg[0x0e] & 0x08) ? 2 : 0);
876 Channel& ch8 = channels[8];
877 ch8.mod.slot_on_flag |= uint8_t((reg[0x0e] & 0x04) ? 2 : 0);
878 ch8.car.slot_on_flag |= uint8_t((reg[0x0e] & 0x02) ? 2 : 0);
883static constexpr int wave2_8pi(
int e)
885 int shift = SLOT_AMP_BITS -
PG_BITS - 2;
897 return cPhase >> DP_BASE_BITS;
931template<
bool HAS_AM,
bool FIXED_ENV>
936 if constexpr (FIXED_ENV) {
937 unsigned out = fixed_env;
938 if constexpr (HAS_AM) {
948 out = arAdjustTab[out];
954 out = EG2DB(out +
tll);
955 if constexpr (HAS_AM) {
966 out = EG2DB(out +
tll);
967 if constexpr (!HAS_AM) {
974template<
bool HAS_AM,
bool FIXED_ENV>
977 int phase = narrow<int>(
calc_phase(lfo_pm)) + wave2_8pi(fm);
978 unsigned egOut = calc_envelope<HAS_AM, FIXED_ENV>(lfo_am, fixed_env);
985template<
bool HAS_AM,
bool HAS_FB,
bool FIXED_ENV>
988 assert((
patch.
FB != 0) == HAS_FB);
990 unsigned egOut = calc_envelope<HAS_AM, FIXED_ENV>(lfo_am, fixed_env);
991 if constexpr (HAS_FB) {
1004 unsigned egOut = calc_envelope<false, false>(0, 0);
1012 unsigned egOut = calc_envelope<false, false>(0, 0);
1013 return BIT(phase, 7)
1014 ? dB2LinTab[(noise ? DB_POS(0.0) : DB_POS(15.0)) + egOut]
1015 : dB2LinTab[(noise ? DB_NEG(0.0) : DB_NEG(15.0)) + egOut];
1021 unsigned egOut = calc_envelope<false, false>(0, 0);
1022 unsigned dbOut = (((BIT(phase7,
PG_BITS - 8) ^
1029 return dB2LinTab[dbOut + egOut];
1035 unsigned egOut = calc_envelope<false, false>(0, 0);
1036 unsigned dbOut = (((BIT(phase7,
PG_BITS - 8) ^
1041 ? (noise ? DB_NEG(12.0) : DB_NEG(24.0))
1042 : (noise ? DB_POS(12.0) : DB_POS(24.0));
1043 return dB2LinTab[dbOut + egOut];
1048 return 1.0f / (1 << DB2LIN_AMP_BITS);
1051bool YM2413::isRhythm()
const
1053 return (reg[0x0E] & 0x20) != 0;
1056unsigned YM2413::getFreq(
unsigned channel)
const
1059 assert(channel < 9);
1060 return reg[0x10 + channel] | ((reg[0x20 + channel] & 0x0F) << 8);
1065 return patches[instrument][carrier];
1068template<
unsigned FLAGS>
1072 const bool HAS_CAR_PM = (FLAGS & 1) != 0;
1073 const bool HAS_CAR_AM = (FLAGS & 2) != 0;
1074 const bool HAS_MOD_PM = (FLAGS & 4) != 0;
1075 const bool HAS_MOD_AM = (FLAGS & 8) != 0;
1076 const bool HAS_MOD_FB = (FLAGS & 16) != 0;
1077 const bool HAS_CAR_FIXED_ENV = (FLAGS & 32) != 0;
1078 const bool HAS_MOD_FIXED_ENV = (FLAGS & 64) != 0;
1085 unsigned tmp_pm_phase = pm_phase;
1086 unsigned tmp_am_phase = am_phase;
1087 unsigned car_fixed_env = 0;
1088 unsigned mod_fixed_env = 0;
1089 if constexpr (HAS_CAR_FIXED_ENV) {
1092 if constexpr (HAS_MOD_FIXED_ENV) {
1096 for (
auto& b : buf) {
1097 unsigned lfo_pm = 0;
1098 if constexpr (HAS_CAR_PM || HAS_MOD_PM) {
1104 lfo_pm = (tmp_pm_phase >> 10) & 7;
1107 if constexpr (HAS_CAR_AM || HAS_MOD_AM) {
1109 if (tmp_am_phase == (LFO_AM_TAB_ELEMENTS * 64)) {
1112 lfo_am = lfo_am_table[tmp_am_phase / 64];
1115 HAS_MOD_PM ? lfo_pm : 0, lfo_am, mod_fixed_env);
1116 b += narrow_cast<float>(ch.
car.
calc_slot_car<HAS_CAR_AM, HAS_CAR_FIXED_ENV>(
1117 HAS_CAR_PM ? lfo_pm : 0, lfo_am, fm, car_fixed_env));
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;
1278 am_phase = (am_phase + num) % (LFO_AM_TAB_ELEMENTS * 64);
1289 unsigned old_noise = noise_seed;
1294 for (
auto sample :
xrange(num)) {
1295 bufs[ 9][sample] += narrow_cast<float>(
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;
1309 bufs[10][sample] += narrow_cast<float>(
1317 for (
auto sample :
xrange(num)) {
1320 bufs[11][sample] += narrow_cast<float>(
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;
1338 bufs[12][sample] += narrow_cast<float>(
1346 for (
auto sample :
xrange(num)) {
1347 bufs[13][sample] += narrow_cast<float>(
1365 registerLatch = value;
1367 writeReg(registerLatch & 0x3f, value);
1376void YM2413::writeReg(uint8_t r, uint8_t data)
1383 patches[0][0].AMPM = (data >> 6) & 3;
1384 patches[0][0].EG = (data >> 5) & 1;
1385 patches[0][0].setKR ((data >> 4) & 1);
1386 patches[0][0].setML ((data >> 0) & 15);
1387 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1388 if ((reg[0x30 + i] & 0xF0) == 0) {
1391 unsigned freq = getFreq(i);
1401 patches[0][1].AMPM = (data >> 6) & 3;
1402 patches[0][1].EG = (data >> 5) & 1;
1403 patches[0][1].setKR ((data >> 4) & 1);
1404 patches[0][1].setML ((data >> 0) & 15);
1405 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1406 if ((reg[0x30 + i] & 0xF0) == 0) {
1407 Channel& ch = channels[i];
1408 ch.setPatch(0, *
this);
1409 unsigned freq = getFreq(i);
1410 ch.car.updatePG (freq);
1411 ch.car.updateRKS(freq);
1419 patches[0][0].setKL((data >> 6) & 3);
1420 patches[0][0].setTL((data >> 0) & 63);
1421 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1422 if ((reg[0x30 + i] & 0xF0) == 0) {
1423 Channel& ch = channels[i];
1424 ch.setPatch(0, *
this);
1425 bool actAsCarrier = (i >= 7) && isRhythm();
1426 assert(!actAsCarrier); (void)actAsCarrier;
1427 ch.mod.updateTLL(getFreq(i),
false);
1434 patches[0][1].setKL((data >> 6) & 3);
1435 patches[0][1].setWF((data >> 4) & 1);
1436 patches[0][0].setWF((data >> 3) & 1);
1437 patches[0][0].setFB((data >> 0) & 7);
1438 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1439 if ((reg[0x30 + i] & 0xF0) == 0) {
1440 Channel& ch = channels[i];
1441 ch.setPatch(0, *
this);
1448 patches[0][0].AR = (data >> 4) & 15;
1449 patches[0][0].DR = (data >> 0) & 15;
1450 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1451 if ((reg[0x30 + i] & 0xF0) == 0) {
1452 Channel& ch = channels[i];
1453 ch.setPatch(0, *
this);
1455 if (ch.mod.state ==
ATTACK) {
1456 ch.mod.setEnvelopeState(
ATTACK);
1464 patches[0][1].AR = (data >> 4) & 15;
1465 patches[0][1].DR = (data >> 0) & 15;
1466 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1467 if ((reg[0x30 + i] & 0xF0) == 0) {
1468 Channel& ch = channels[i];
1469 ch.setPatch(0, *
this);
1471 if (ch.car.state ==
ATTACK) {
1472 ch.car.setEnvelopeState(
ATTACK);
1480 patches[0][0].setSL((data >> 4) & 15);
1481 patches[0][0].RR = (data >> 0) & 15;
1482 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1483 if ((reg[0x30 + i] & 0xF0) == 0) {
1484 Channel& ch = channels[i];
1485 ch.setPatch(0, *
this);
1487 if (ch.mod.state ==
DECAY) {
1488 ch.mod.setEnvelopeState(
DECAY);
1496 patches[0][1].setSL((data >> 4) & 15);
1497 patches[0][1].RR = (data >> 0) & 15;
1498 for (
auto i :
xrange(isRhythm() ? 6 : 9)) {
1499 if ((reg[0x30 + i] & 0xF0) == 0) {
1500 Channel& ch = channels[i];
1501 ch.setPatch(0, *
this);
1503 if (ch.car.state ==
DECAY) {
1504 ch.car.setEnvelopeState(
DECAY);
1511 uint8_t old = reg[r];
1513 setRhythmFlags(old);
1516 case 0x19:
case 0x1A:
case 0x1B:
case 0x1C:
1517 case 0x1D:
case 0x1E:
case 0x1F:
1520 case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
1521 case 0x15:
case 0x16:
case 0x17:
case 0x18: {
1523 unsigned cha = r & 0x0F; assert(cha < 9);
1524 Channel& ch = channels[cha];
1525 bool actAsCarrier = (cha >= 7) && isRhythm();
1526 unsigned freq = getFreq(cha);
1527 ch.mod.updateAll(freq, actAsCarrier);
1528 ch.car.updateAll(freq,
true);
1531 case 0x29:
case 0x2A:
case 0x2B:
case 0x2C:
1532 case 0x2D:
case 0x2E:
case 0x2F:
1535 case 0x20:
case 0x21:
case 0x22:
case 0x23:
case 0x24:
1536 case 0x25:
case 0x26:
case 0x27:
case 0x28: {
1538 unsigned cha = r & 0x0F; assert(cha < 9);
1539 Channel& ch = channels[cha];
1540 bool modActAsCarrier = (cha >= 7) && isRhythm();
1541 ch.setSustain((data >> 5) & 1, modActAsCarrier);
1547 unsigned freq = getFreq(cha);
1548 ch.mod.updateAll(freq, modActAsCarrier);
1549 ch.car.updateAll(freq,
true);
1552 case 0x39:
case 0x3A:
case 0x3B:
case 0x3C:
1553 case 0x3D:
case 0x3E:
case 0x3F:
1556 case 0x30:
case 0x31:
case 0x32:
case 0x33:
case 0x34:
1557 case 0x35:
case 0x36:
case 0x37:
case 0x38: {
1559 unsigned cha = r & 0x0F; assert(cha < 9);
1560 Channel& ch = channels[cha];
1561 if (isRhythm() && (cha >= 6)) {
1564 ch.mod.setVolume(data >> 4);
1567 ch.setPatch(data >> 4, *
this);
1569 ch.car.setVolume(data & 15);
1570 bool actAsCarrier = (cha >= 7) && isRhythm();
1571 unsigned freq = getFreq(cha);
1572 ch.mod.updateAll(freq, actAsCarrier);
1573 ch.car.updateAll(freq,
true);
1588static constexpr std::initializer_list<enum_string<YM2413Okazaki::EnvelopeState>> envelopeStateInfo = {
1599namespace YM2413Okazaki {
1606template<
typename Archive>
1626template<
typename Archive>
1629 ar.serialize(
"mod",
mod,
1638template<
typename Archive>
1641 if (ar.versionBelow(version, 2)) ar.beginTag(
"YM2413Core");
1642 ar.serialize(
"registers", reg);
1643 if (ar.versionBelow(version, 2)) ar.endTag(
"YM2413Core");
1647 ar.serialize(
"channels", channels,
1648 "pm_phase", pm_phase,
1649 "am_phase", am_phase,
1650 "noise_seed", noise_seed);
1652 if constexpr (Archive::IS_LOADER) {
1653 patches[0][0].initModulator(subspan<8>(reg));
1654 patches[0][1].initCarrier (subspan<8>(reg));
1655 for (
auto [i, ch] :
enumerate(channels)) {
1657 unsigned p = ((i >= 6) && isRhythm())
1658 ?
unsigned(16 + (i - 6))
1659 : (reg[0x30 + i] >> 4);
1660 ch.setPatch(p, *
this);
1662 ch.car.setVolume(reg[0x30 + i] & 15);
1663 if (isRhythm() && (i >= 7)) {
1664 ch.mod.setVolume(reg[0x30 + i] >> 4);
1667 bool actAsCarrier = (i >= 7) && isRhythm();
1668 unsigned freq = getFreq(
unsigned(i));
1669 ch.mod.updateAll(freq, actAsCarrier);
1670 ch.car.updateAll(freq,
true);
1671 ch.mod.setEnvelopeState(ch.mod.state);
1672 ch.car.setEnvelopeState(ch.car.state);
1674 update_key_status();
1676 if (ar.versionAtLeast(version, 4)) {
1677 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 initModulator(std::span< const uint8_t, 8 > data)
std::span< const unsigned, PG_WIDTH > WF
void setTL(uint8_t value)
Set volume (total level) [0..63].
std::span< const uint8_t, 16 *8 > KL
void setKL(uint8_t value)
Sets Key scale level [0..3].
void initCarrier(std::span< const uint8_t, 8 > data)
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)
void setEnvelopeState(EnvelopeState state)
std::array< unsigned, 8 > dPhase
unsigned calc_envelope(int lfo_am, unsigned fixed_env)
unsigned calc_phase(unsigned lfo_pm)
unsigned calc_fixed_env() const
std::span< const int, 16 > dPhaseDRTableRks
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)
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 generateChannels(std::span< float *, 9+5 > bufs, unsigned num) override
Generate the sound output.
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)
FixedPoint< EP_FP_BITS > EnvPhaseIndex
This file implemented 3 utility functions:
SERIALIZE_ENUM(CassettePlayer::State, stateInfo)
REGISTER_POLYMORPHIC_INITIALIZER(Pluggable, CassettePlayer, "CassettePlayer")
constexpr void fill(ForwardRange &&range, const T &value)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
constexpr auto xrange(T e)