diff options
Diffstat (limited to 'src/nukedopl3.c')
-rw-r--r-- | src/nukedopl3.c | 981 |
1 files changed, 447 insertions, 534 deletions
diff --git a/src/nukedopl3.c b/src/nukedopl3.c index 21877ab..6ae1eb7 100644 --- a/src/nukedopl3.c +++ b/src/nukedopl3.c @@ -1,16 +1,19 @@ /* * Copyright (C) 2013-2016 Alexey Khokholov (Nuke.YKT) * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Lesser General Public License for more details. * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Nuked OPL3 emulator. * Thanks: @@ -31,13 +34,8 @@ #define RSM_FRAC 10 -#if defined(__GNUC__) && __USE_ISOC99 -#define INLINE __attribute__((always_inline)) inline -#else -#define INLINE -#endif +/* Channel types */ -/* Channel types */ enum { ch_2op = 0, ch_4op = 1, @@ -45,18 +43,19 @@ enum { ch_drum = 3 }; -/* Envelope key types */ +/* Envelope key types */ + enum { egk_norm = 0x01, egk_drum = 0x02 }; -/* */ -/* logsin table */ -/* */ +/* + * logsin table + */ -static const Bit16u logsinrom[256] = { +static const Bit16u logsinrom[512] = { 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471, 0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365, 0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd, @@ -88,61 +87,93 @@ static const Bit16u logsinrom[256] = { 0x007, 0x007, 0x006, 0x006, 0x005, 0x005, 0x005, 0x004, 0x004, 0x004, 0x003, 0x003, 0x003, 0x002, 0x002, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000 + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x002, + 0x002, 0x002, 0x002, 0x003, 0x003, 0x003, 0x004, 0x004, + 0x004, 0x005, 0x005, 0x005, 0x006, 0x006, 0x007, 0x007, + 0x007, 0x008, 0x008, 0x009, 0x009, 0x00a, 0x00a, 0x00b, + 0x00c, 0x00c, 0x00d, 0x00d, 0x00e, 0x00f, 0x00f, 0x010, + 0x011, 0x011, 0x012, 0x013, 0x014, 0x014, 0x015, 0x016, + 0x017, 0x017, 0x018, 0x019, 0x01a, 0x01b, 0x01c, 0x01d, + 0x01e, 0x01f, 0x020, 0x021, 0x022, 0x023, 0x024, 0x025, + 0x026, 0x027, 0x028, 0x029, 0x02a, 0x02b, 0x02d, 0x02e, + 0x02f, 0x030, 0x031, 0x033, 0x034, 0x035, 0x037, 0x038, + 0x039, 0x03b, 0x03c, 0x03e, 0x03f, 0x040, 0x042, 0x043, + 0x045, 0x046, 0x048, 0x04a, 0x04b, 0x04d, 0x04e, 0x050, + 0x052, 0x053, 0x055, 0x057, 0x059, 0x05b, 0x05c, 0x05e, + 0x060, 0x062, 0x064, 0x066, 0x068, 0x06a, 0x06c, 0x06e, + 0x070, 0x072, 0x074, 0x076, 0x078, 0x07a, 0x07d, 0x07f, + 0x081, 0x083, 0x086, 0x088, 0x08a, 0x08d, 0x08f, 0x092, + 0x094, 0x097, 0x099, 0x09c, 0x09f, 0x0a1, 0x0a4, 0x0a7, + 0x0a9, 0x0ac, 0x0af, 0x0b2, 0x0b5, 0x0b8, 0x0bb, 0x0be, + 0x0c1, 0x0c4, 0x0c7, 0x0ca, 0x0cd, 0x0d1, 0x0d4, 0x0d7, + 0x0db, 0x0de, 0x0e2, 0x0e5, 0x0e9, 0x0ec, 0x0f0, 0x0f4, + 0x0f8, 0x0fb, 0x0ff, 0x103, 0x107, 0x10b, 0x10f, 0x114, + 0x118, 0x11c, 0x121, 0x125, 0x129, 0x12e, 0x133, 0x137, + 0x13c, 0x141, 0x146, 0x14b, 0x150, 0x155, 0x15b, 0x160, + 0x166, 0x16b, 0x171, 0x177, 0x17c, 0x182, 0x188, 0x18f, + 0x195, 0x19b, 0x1a2, 0x1a9, 0x1b0, 0x1b7, 0x1be, 0x1c5, + 0x1cd, 0x1d4, 0x1dc, 0x1e4, 0x1ec, 0x1f5, 0x1fd, 0x206, + 0x20f, 0x218, 0x222, 0x22c, 0x236, 0x240, 0x24b, 0x256, + 0x261, 0x26d, 0x279, 0x286, 0x293, 0x2a0, 0x2af, 0x2bd, + 0x2cd, 0x2dc, 0x2ed, 0x2ff, 0x311, 0x324, 0x339, 0x34e, + 0x365, 0x37e, 0x398, 0x3b5, 0x3d3, 0x3f5, 0x41a, 0x443, + 0x471, 0x4a6, 0x4e4, 0x52e, 0x58b, 0x607, 0x6c3, 0x859 }; -/* */ -/* exp table */ -/* */ +/* + * exp table + */ static const Bit16u exprom[256] = { - 0x000, 0x003, 0x006, 0x008, 0x00b, 0x00e, 0x011, 0x014, - 0x016, 0x019, 0x01c, 0x01f, 0x022, 0x025, 0x028, 0x02a, - 0x02d, 0x030, 0x033, 0x036, 0x039, 0x03c, 0x03f, 0x042, - 0x045, 0x048, 0x04b, 0x04e, 0x051, 0x054, 0x057, 0x05a, - 0x05d, 0x060, 0x063, 0x066, 0x069, 0x06c, 0x06f, 0x072, - 0x075, 0x078, 0x07b, 0x07e, 0x082, 0x085, 0x088, 0x08b, - 0x08e, 0x091, 0x094, 0x098, 0x09b, 0x09e, 0x0a1, 0x0a4, - 0x0a8, 0x0ab, 0x0ae, 0x0b1, 0x0b5, 0x0b8, 0x0bb, 0x0be, - 0x0c2, 0x0c5, 0x0c8, 0x0cc, 0x0cf, 0x0d2, 0x0d6, 0x0d9, - 0x0dc, 0x0e0, 0x0e3, 0x0e7, 0x0ea, 0x0ed, 0x0f1, 0x0f4, - 0x0f8, 0x0fb, 0x0ff, 0x102, 0x106, 0x109, 0x10c, 0x110, - 0x114, 0x117, 0x11b, 0x11e, 0x122, 0x125, 0x129, 0x12c, - 0x130, 0x134, 0x137, 0x13b, 0x13e, 0x142, 0x146, 0x149, - 0x14d, 0x151, 0x154, 0x158, 0x15c, 0x160, 0x163, 0x167, - 0x16b, 0x16f, 0x172, 0x176, 0x17a, 0x17e, 0x181, 0x185, - 0x189, 0x18d, 0x191, 0x195, 0x199, 0x19c, 0x1a0, 0x1a4, - 0x1a8, 0x1ac, 0x1b0, 0x1b4, 0x1b8, 0x1bc, 0x1c0, 0x1c4, - 0x1c8, 0x1cc, 0x1d0, 0x1d4, 0x1d8, 0x1dc, 0x1e0, 0x1e4, - 0x1e8, 0x1ec, 0x1f0, 0x1f5, 0x1f9, 0x1fd, 0x201, 0x205, - 0x209, 0x20e, 0x212, 0x216, 0x21a, 0x21e, 0x223, 0x227, - 0x22b, 0x230, 0x234, 0x238, 0x23c, 0x241, 0x245, 0x249, - 0x24e, 0x252, 0x257, 0x25b, 0x25f, 0x264, 0x268, 0x26d, - 0x271, 0x276, 0x27a, 0x27f, 0x283, 0x288, 0x28c, 0x291, - 0x295, 0x29a, 0x29e, 0x2a3, 0x2a8, 0x2ac, 0x2b1, 0x2b5, - 0x2ba, 0x2bf, 0x2c4, 0x2c8, 0x2cd, 0x2d2, 0x2d6, 0x2db, - 0x2e0, 0x2e5, 0x2e9, 0x2ee, 0x2f3, 0x2f8, 0x2fd, 0x302, - 0x306, 0x30b, 0x310, 0x315, 0x31a, 0x31f, 0x324, 0x329, - 0x32e, 0x333, 0x338, 0x33d, 0x342, 0x347, 0x34c, 0x351, - 0x356, 0x35b, 0x360, 0x365, 0x36a, 0x370, 0x375, 0x37a, - 0x37f, 0x384, 0x38a, 0x38f, 0x394, 0x399, 0x39f, 0x3a4, - 0x3a9, 0x3ae, 0x3b4, 0x3b9, 0x3bf, 0x3c4, 0x3c9, 0x3cf, - 0x3d4, 0x3da, 0x3df, 0x3e4, 0x3ea, 0x3ef, 0x3f5, 0x3fa + 0xff4, 0xfea, 0xfde, 0xfd4, 0xfc8, 0xfbe, 0xfb4, 0xfa8, + 0xf9e, 0xf92, 0xf88, 0xf7e, 0xf72, 0xf68, 0xf5c, 0xf52, + 0xf48, 0xf3e, 0xf32, 0xf28, 0xf1e, 0xf14, 0xf08, 0xefe, + 0xef4, 0xeea, 0xee0, 0xed4, 0xeca, 0xec0, 0xeb6, 0xeac, + 0xea2, 0xe98, 0xe8e, 0xe84, 0xe7a, 0xe70, 0xe66, 0xe5c, + 0xe52, 0xe48, 0xe3e, 0xe34, 0xe2a, 0xe20, 0xe16, 0xe0c, + 0xe04, 0xdfa, 0xdf0, 0xde6, 0xddc, 0xdd2, 0xdca, 0xdc0, + 0xdb6, 0xdac, 0xda4, 0xd9a, 0xd90, 0xd88, 0xd7e, 0xd74, + 0xd6a, 0xd62, 0xd58, 0xd50, 0xd46, 0xd3c, 0xd34, 0xd2a, + 0xd22, 0xd18, 0xd10, 0xd06, 0xcfe, 0xcf4, 0xcec, 0xce2, + 0xcda, 0xcd0, 0xcc8, 0xcbe, 0xcb6, 0xcae, 0xca4, 0xc9c, + 0xc92, 0xc8a, 0xc82, 0xc78, 0xc70, 0xc68, 0xc60, 0xc56, + 0xc4e, 0xc46, 0xc3c, 0xc34, 0xc2c, 0xc24, 0xc1c, 0xc12, + 0xc0a, 0xc02, 0xbfa, 0xbf2, 0xbea, 0xbe0, 0xbd8, 0xbd0, + 0xbc8, 0xbc0, 0xbb8, 0xbb0, 0xba8, 0xba0, 0xb98, 0xb90, + 0xb88, 0xb80, 0xb78, 0xb70, 0xb68, 0xb60, 0xb58, 0xb50, + 0xb48, 0xb40, 0xb38, 0xb32, 0xb2a, 0xb22, 0xb1a, 0xb12, + 0xb0a, 0xb02, 0xafc, 0xaf4, 0xaec, 0xae4, 0xade, 0xad6, + 0xace, 0xac6, 0xac0, 0xab8, 0xab0, 0xaa8, 0xaa2, 0xa9a, + 0xa92, 0xa8c, 0xa84, 0xa7c, 0xa76, 0xa6e, 0xa68, 0xa60, + 0xa58, 0xa52, 0xa4a, 0xa44, 0xa3c, 0xa36, 0xa2e, 0xa28, + 0xa20, 0xa18, 0xa12, 0xa0c, 0xa04, 0x9fe, 0x9f6, 0x9f0, + 0x9e8, 0x9e2, 0x9da, 0x9d4, 0x9ce, 0x9c6, 0x9c0, 0x9b8, + 0x9b2, 0x9ac, 0x9a4, 0x99e, 0x998, 0x990, 0x98a, 0x984, + 0x97c, 0x976, 0x970, 0x96a, 0x962, 0x95c, 0x956, 0x950, + 0x948, 0x942, 0x93c, 0x936, 0x930, 0x928, 0x922, 0x91c, + 0x916, 0x910, 0x90a, 0x904, 0x8fc, 0x8f6, 0x8f0, 0x8ea, + 0x8e4, 0x8de, 0x8d8, 0x8d2, 0x8cc, 0x8c6, 0x8c0, 0x8ba, + 0x8b4, 0x8ae, 0x8a8, 0x8a2, 0x89c, 0x896, 0x890, 0x88a, + 0x884, 0x87e, 0x878, 0x872, 0x86c, 0x866, 0x860, 0x85a, + 0x854, 0x850, 0x84a, 0x844, 0x83e, 0x838, 0x832, 0x82c, + 0x828, 0x822, 0x81c, 0x816, 0x810, 0x80c, 0x806, 0x800 }; -/* */ -/* freq mult table multiplied by 2 */ -/* */ -/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 12, 12, 15, 15 */ -/* */ +/* + * freq mult table multiplied by 2 + * + * 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 12, 12, 15, 15 + */ static const Bit8u mt[16] = { 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30 }; -/* */ -/* ksl table */ -/* */ +/* + * ksl table + */ static const Bit8u kslrom[16] = { 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 @@ -152,9 +183,9 @@ static const Bit8u kslshift[4] = { 8, 1, 2, 0 }; -/* */ -/* envelope generator constants */ -/* */ +/* + * envelope generator constants + */ static const Bit8u eg_incstep[3][4][8] = { { @@ -185,9 +216,9 @@ static const Bit8s eg_incsh[16] = { 0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, -2 }; -/* */ -/* address decoding */ -/* */ +/* + * address decoding + */ static const Bit8s ad_slot[0x20] = { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1, @@ -198,184 +229,17 @@ static const Bit8u ch_slot[18] = { 0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32 }; -/* */ -/* Envelope generator */ -/* */ - -typedef Bit16s(*envelope_sinfunc)(Bit16u phase, Bit16u envelope); -typedef void(*envelope_genfunc)(opl3_slot *slott); - -#define OPL3_EnvelopeCalcExp_level(level) \ - ((level > 0x1fff) ? 0x1fff : level) - -#define OPL3_EnvelopeCalcExp(level) \ -(Bit16s) (\ - ((exprom[(OPL3_EnvelopeCalcExp_level(level) & 0xff) ^ 0xff] | 0x400) << 1) >> \ - (OPL3_EnvelopeCalcExp_level(level) >> 8) \ -) /* -static INLINE Bit16s OPL3_EnvelopeCalcExp(Bit32u level) -{ - if (level > 0x1fff) - { - level = 0x1fff; - } - return (Bit16s)((exprom[(level & 0xff) ^ 0xff] | 0x400) << 1) >> (level >> 8); -}*/ - -static INLINE Bit16s OPL3_EnvelopeCalcSin0(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - Bit16u neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = ~0; - } - if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; -} - -static INLINE Bit16s OPL3_EnvelopeCalcSin1(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static INLINE Bit16s OPL3_EnvelopeCalcSin2(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static INLINE Bit16s OPL3_EnvelopeCalcSin3(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x100) - { - out = 0x1000; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static INLINE Bit16s OPL3_EnvelopeCalcSin4(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - Bit16u neg = 0; - phase &= 0x3ff; - if ((phase & 0x300) == 0x100) - { - neg = ~0; - } - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x80) - { - out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; - } - else - { - out = logsinrom[(phase << 1) & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; -} - -static INLINE Bit16s OPL3_EnvelopeCalcSin5(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x80) - { - out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; - } - else - { - out = logsinrom[(phase << 1) & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static INLINE Bit16s OPL3_EnvelopeCalcSin6(Bit16u phase, Bit16u envelope) -{ - Bit16u neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = ~0; - } - return OPL3_EnvelopeCalcExp(envelope << 3) ^ neg; -} - -static INLINE Bit16s OPL3_EnvelopeCalcSin7(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - Bit16u neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = ~0; - phase = (phase & 0x1ff) ^ 0x1ff; - } - out = phase << 3; - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; -} + * Envelope generator + */ -static const envelope_sinfunc envelope_sin[8] = { - OPL3_EnvelopeCalcSin0, - OPL3_EnvelopeCalcSin1, - OPL3_EnvelopeCalcSin2, - OPL3_EnvelopeCalcSin3, - OPL3_EnvelopeCalcSin4, - OPL3_EnvelopeCalcSin5, - OPL3_EnvelopeCalcSin6, - OPL3_EnvelopeCalcSin7 -}; +static void OPL3_EnvelopeGenOff(opl3_slot *slot); +static void OPL3_EnvelopeGenAttack(opl3_slot *slot); +static void OPL3_EnvelopeGenDecay(opl3_slot *slot); +static void OPL3_EnvelopeGenSustain(opl3_slot *slot); +static void OPL3_EnvelopeGenRelease(opl3_slot *slot); -static INLINE void OPL3_EnvelopeGenOff(opl3_slot *slot); -static INLINE void OPL3_EnvelopeGenAttack(opl3_slot *slot); -static INLINE void OPL3_EnvelopeGenDecay(opl3_slot *slot); -static INLINE void OPL3_EnvelopeGenSustain(opl3_slot *slot); -static INLINE void OPL3_EnvelopeGenRelease(opl3_slot *slot); +typedef void(*envelope_genfunc)(opl3_slot *slot); envelope_genfunc envelope_gen[5] = { OPL3_EnvelopeGenOff, @@ -394,7 +258,7 @@ enum envelope_gen_num envelope_gen_num_release = 4 }; -static INLINE Bit8u OPL3_EnvelopeCalcRate(opl3_slot *slot, Bit8u reg_rate) +static Bit8u OPL3_EnvelopeCalcRate(opl3_slot *slot, Bit8u reg_rate) { Bit8u rate; if (reg_rate == 0x00) @@ -410,7 +274,7 @@ static INLINE Bit8u OPL3_EnvelopeCalcRate(opl3_slot *slot, Bit8u reg_rate) return rate; } -static INLINE void OPL3_EnvelopeUpdateKSL(opl3_slot *slot) +static void OPL3_EnvelopeUpdateKSL(opl3_slot *slot) { Bit16s ksl = (kslrom[slot->channel->f_num >> 6] << 2) - ((0x08 - slot->channel->block) << 5); @@ -421,7 +285,7 @@ static INLINE void OPL3_EnvelopeUpdateKSL(opl3_slot *slot) slot->eg_ksl = (Bit8u)ksl; } -static INLINE void OPL3_EnvelopeUpdateRate(opl3_slot *slot) +static void OPL3_EnvelopeUpdateRate(opl3_slot *slot) { switch (slot->eg_gen) { @@ -439,12 +303,12 @@ static INLINE void OPL3_EnvelopeUpdateRate(opl3_slot *slot) } } -static INLINE void OPL3_EnvelopeGenOff(opl3_slot *slot) +static void OPL3_EnvelopeGenOff(opl3_slot *slot) { slot->eg_rout = 0x1ff; } -static INLINE void OPL3_EnvelopeGenAttack(opl3_slot *slot) +static void OPL3_EnvelopeGenAttack(opl3_slot *slot) { if (slot->eg_rout == 0x00) { @@ -459,7 +323,7 @@ static INLINE void OPL3_EnvelopeGenAttack(opl3_slot *slot) } } -static INLINE void OPL3_EnvelopeGenDecay(opl3_slot *slot) +static void OPL3_EnvelopeGenDecay(opl3_slot *slot) { if (slot->eg_rout >= slot->reg_sl << 4) { @@ -470,7 +334,7 @@ static INLINE void OPL3_EnvelopeGenDecay(opl3_slot *slot) slot->eg_rout += slot->eg_inc; } -static INLINE void OPL3_EnvelopeGenSustain(opl3_slot *slot) +static void OPL3_EnvelopeGenSustain(opl3_slot *slot) { if (!slot->reg_type) { @@ -478,7 +342,7 @@ static INLINE void OPL3_EnvelopeGenSustain(opl3_slot *slot) } } -static INLINE void OPL3_EnvelopeGenRelease(opl3_slot *slot) +static void OPL3_EnvelopeGenRelease(opl3_slot *slot) { if (slot->eg_rout >= 0x1ff) { @@ -490,7 +354,7 @@ static INLINE void OPL3_EnvelopeGenRelease(opl3_slot *slot) slot->eg_rout += slot->eg_inc; } -static INLINE void OPL3_EnvelopeCalc(opl3_slot *slot) +static void OPL3_EnvelopeCalc(opl3_slot *slot) { Bit8u rate_h, rate_l; Bit8u inc = 0; @@ -512,10 +376,16 @@ static INLINE void OPL3_EnvelopeCalc(opl3_slot *slot) slot->eg_inc = inc; slot->eg_out = slot->eg_rout + (slot->reg_tl << 2) + (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem; + if (slot->eg_out > 0x1ff) /* TODO: Remove this if possible */ + { + slot->eg_out = 0x1ff; + } + slot->eg_out <<= 3; + envelope_gen[slot->eg_gen](slot); } -static INLINE void OPL3_EnvelopeKeyOn(opl3_slot *slot, Bit8u type) +static void OPL3_EnvelopeKeyOn(opl3_slot *slot, Bit8u type) { if (!slot->key) { @@ -532,7 +402,7 @@ static INLINE void OPL3_EnvelopeKeyOn(opl3_slot *slot, Bit8u type) slot->key |= type; } -static INLINE void OPL3_EnvelopeKeyOff(opl3_slot *slot, Bit8u type) +static void OPL3_EnvelopeKeyOff(opl3_slot *slot, Bit8u type) { if (slot->key) { @@ -545,11 +415,11 @@ static INLINE void OPL3_EnvelopeKeyOff(opl3_slot *slot, Bit8u type) } } -/* */ -/* Phase Generator */ -/* */ +/* + * Phase Generator + */ -static INLINE void OPL3_PhaseGenerate(opl3_slot *slot) +static void OPL3_PhaseGenerate(opl3_slot *slot) { Bit16u f_num; Bit32u basefreq; @@ -583,11 +453,11 @@ static INLINE void OPL3_PhaseGenerate(opl3_slot *slot) slot->pg_phase += (basefreq * mt[slot->reg_mult]) >> 1; } -/* */ -/* Noise Generator */ -/* */ +/* + * Noise Generator + */ -static INLINE void OPL3_NoiseGenerate(opl3_chip *chip) +static void OPL3_NoiseGenerate(opl3_chip *chip) { if (chip->noise & 0x01) { @@ -596,11 +466,11 @@ static INLINE void OPL3_NoiseGenerate(opl3_chip *chip) chip->noise >>= 1; } -/* */ -/* Slot */ -/* */ +/* + * Slot + */ -static INLINE void OPL3_SlotWrite20(opl3_slot *slot, Bit8u data) +static void OPL3_SlotWrite20(opl3_slot *slot, Bit8u data) { if ((data >> 7) & 0x01) { @@ -617,21 +487,21 @@ static INLINE void OPL3_SlotWrite20(opl3_slot *slot, Bit8u data) OPL3_EnvelopeUpdateRate(slot); } -static INLINE void OPL3_SlotWrite40(opl3_slot *slot, Bit8u data) +static void OPL3_SlotWrite40(opl3_slot *slot, Bit8u data) { slot->reg_ksl = (data >> 6) & 0x03; slot->reg_tl = data & 0x3f; OPL3_EnvelopeUpdateKSL(slot); } -static INLINE void OPL3_SlotWrite60(opl3_slot *slot, Bit8u data) +static void OPL3_SlotWrite60(opl3_slot *slot, Bit8u data) { slot->reg_ar = (data >> 4) & 0x0f; slot->reg_dr = data & 0x0f; OPL3_EnvelopeUpdateRate(slot); } -static INLINE void OPL3_SlotWrite80(opl3_slot *slot, Bit8u data) +static void OPL3_SlotWrite80(opl3_slot *slot, Bit8u data) { slot->reg_sl = (data >> 4) & 0x0f; if (slot->reg_sl == 0x0f) @@ -642,46 +512,101 @@ static INLINE void OPL3_SlotWrite80(opl3_slot *slot, Bit8u data) OPL3_EnvelopeUpdateRate(slot); } -static INLINE void OPL3_SlotWriteE0(opl3_slot *slot, Bit8u data) +static void OPL3_SlotWriteE0(opl3_slot *slot, Bit8u data) { slot->reg_wf = data & 0x07; if (slot->chip->newm == 0x00) { slot->reg_wf &= 0x03; } -} -#define OPL3_SlotGeneratePhase(slot, phase) \ - { \ - (slot)->out = envelope_sin[slot->reg_wf]((phase), (slot)->eg_out); \ + switch (slot->reg_wf) + { + case 1: + case 4: + case 5: + slot->maskzero = 0x200; + break; + case 3: + slot->maskzero = 0x100; + break; + default: + slot->maskzero = 0; + break; } -/* -static INLINE void OPL3_SlotGeneratePhase(opl3_slot *slot, Bit16u phase) + + switch (slot->reg_wf) + { + case 4: + slot->signpos = (31-8); /* sigext of (phase & 0x100) */ + break; + case 0: + case 6: + case 7: + slot->signpos = (31-9); /* sigext of (phase & 0x200) */ + break; + default: + slot->signpos = (31-16); /* set "neg" to zero */ + break; + } + + switch (slot->reg_wf) + { + case 4: + case 5: + slot->phaseshift = 1; + break; + case 6: + slot->phaseshift = 16; /* set phase to zero and flag for non-sin wave */ + break; + case 7: + slot->phaseshift = 32; /* no shift (work by mod 32), but flag for non-sin wave */ + break; + default: + slot->phaseshift = 0; + break; + } +} + +static void OPL3_SlotGeneratePhase(opl3_slot *slot, Bit16u phase) { - slot->out = envelope_sin[slot->reg_wf](phase, slot->eg_out); -}*/ + Bit32u neg, level; + Bit8u phaseshift; -#define OPL3_SlotGenerate(slot) \ - {\ - OPL3_SlotGeneratePhase((slot), (Bit16u)((slot)->pg_phase >> 9) + *(slot)->mod);\ + /* Fast paths for mute segments */ + if (phase & slot->maskzero) + { + slot->out = 0; + return; } -/* -static INLINE void OPL3_SlotGenerate(opl3_slot *slot) + + neg = (Bit32s)((Bit32u)phase << slot->signpos) >> 31; + phaseshift = slot->phaseshift; + level = slot->eg_out; + + phase <<= phaseshift; + if (phaseshift <= 1) + { + level += logsinrom[phase & 0x1ff]; + } + else + { + level += ((phase ^ neg) & 0x3ff) << 3; + } + slot->out = exprom[level & 0xff] >> (level >> 8) ^ neg; +} + +static void OPL3_SlotGenerate(opl3_slot *slot) { OPL3_SlotGeneratePhase(slot, (Bit16u)(slot->pg_phase >> 9) + *slot->mod); -}*/ - -#define OPL3_SlotGenerateZM(slot) \ -{\ - OPL3_SlotGeneratePhase((slot), (Bit16u)((slot)->pg_phase >> 9));\ } -/* -static INLINE void OPL3_SlotGenerateZM(opl3_slot *slot) + +static void OPL3_SlotGenerateZM(opl3_slot *slot) { OPL3_SlotGeneratePhase(slot, (Bit16u)(slot->pg_phase >> 9)); -}*/ +} -static INLINE void OPL3_SlotCalcFB(opl3_slot *slot) +static void OPL3_SlotCalcFB(opl3_slot *slot) { if (slot->channel->fb != 0x00) { @@ -694,107 +619,13 @@ static INLINE void OPL3_SlotCalcFB(opl3_slot *slot) slot->prout = slot->out; } -/* */ -/* Channel */ -/* */ +/* + * Channel + */ -/* static void OPL3_ChannelSetupAlg(opl3_channel *channel); */ -static INLINE void OPL3_ChannelSetupAlg(opl3_channel *channel) -{ - if (channel->chtype == ch_drum) - { - switch (channel->alg & 0x01) - { - case 0x00: - channel->chipslots[0]->mod = &channel->chipslots[0]->fbmod; - channel->chipslots[1]->mod = &channel->chipslots[0]->out; - break; - case 0x01: - channel->chipslots[0]->mod = &channel->chipslots[0]->fbmod; - channel->chipslots[1]->mod = &channel->chip->zeromod; - break; - } - return; - } - if (channel->alg & 0x08) - { - return; - } - if (channel->alg & 0x04) - { - channel->pair->out[0] = &channel->chip->zeromod; - channel->pair->out[1] = &channel->chip->zeromod; - channel->pair->out[2] = &channel->chip->zeromod; - channel->pair->out[3] = &channel->chip->zeromod; - switch (channel->alg & 0x03) - { - case 0x00: - channel->pair->chipslots[0]->mod = &channel->pair->chipslots[0]->fbmod; - channel->pair->chipslots[1]->mod = &channel->pair->chipslots[0]->out; - channel->chipslots[0]->mod = &channel->pair->chipslots[1]->out; - channel->chipslots[1]->mod = &channel->chipslots[0]->out; - channel->out[0] = &channel->chipslots[1]->out; - channel->out[1] = &channel->chip->zeromod; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x01: - channel->pair->chipslots[0]->mod = &channel->pair->chipslots[0]->fbmod; - channel->pair->chipslots[1]->mod = &channel->pair->chipslots[0]->out; - channel->chipslots[0]->mod = &channel->chip->zeromod; - channel->chipslots[1]->mod = &channel->chipslots[0]->out; - channel->out[0] = &channel->pair->chipslots[1]->out; - channel->out[1] = &channel->chipslots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x02: - channel->pair->chipslots[0]->mod = &channel->pair->chipslots[0]->fbmod; - channel->pair->chipslots[1]->mod = &channel->chip->zeromod; - channel->chipslots[0]->mod = &channel->pair->chipslots[1]->out; - channel->chipslots[1]->mod = &channel->chipslots[0]->out; - channel->out[0] = &channel->pair->chipslots[0]->out; - channel->out[1] = &channel->chipslots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x03: - channel->pair->chipslots[0]->mod = &channel->pair->chipslots[0]->fbmod; - channel->pair->chipslots[1]->mod = &channel->chip->zeromod; - channel->chipslots[0]->mod = &channel->pair->chipslots[1]->out; - channel->chipslots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->pair->chipslots[0]->out; - channel->out[1] = &channel->chipslots[0]->out; - channel->out[2] = &channel->chipslots[1]->out; - channel->out[3] = &channel->chip->zeromod; - break; - } - } - else - { - switch (channel->alg & 0x01) - { - case 0x00: - channel->chipslots[0]->mod = &channel->chipslots[0]->fbmod; - channel->chipslots[1]->mod = &channel->chipslots[0]->out; - channel->out[0] = &channel->chipslots[1]->out; - channel->out[1] = &channel->chip->zeromod; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x01: - channel->chipslots[0]->mod = &channel->chipslots[0]->fbmod; - channel->chipslots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->chipslots[0]->out; - channel->out[1] = &channel->chipslots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - } - } -} +static void OPL3_ChannelSetupAlg(opl3_channel *channel); -static INLINE void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) +static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) { opl3_channel *channel6; opl3_channel *channel7; @@ -807,69 +638,69 @@ static INLINE void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) channel6 = &chip->channel[6]; channel7 = &chip->channel[7]; channel8 = &chip->channel[8]; - channel6->out[0] = &channel6->chipslots[1]->out; - channel6->out[1] = &channel6->chipslots[1]->out; + channel6->out[0] = &channel6->slots[1]->out; + channel6->out[1] = &channel6->slots[1]->out; channel6->out[2] = &chip->zeromod; channel6->out[3] = &chip->zeromod; - channel7->out[0] = &channel7->chipslots[0]->out; - channel7->out[1] = &channel7->chipslots[0]->out; - channel7->out[2] = &channel7->chipslots[1]->out; - channel7->out[3] = &channel7->chipslots[1]->out; - channel8->out[0] = &channel8->chipslots[0]->out; - channel8->out[1] = &channel8->chipslots[0]->out; - channel8->out[2] = &channel8->chipslots[1]->out; - channel8->out[3] = &channel8->chipslots[1]->out; + channel7->out[0] = &channel7->slots[0]->out; + channel7->out[1] = &channel7->slots[0]->out; + channel7->out[2] = &channel7->slots[1]->out; + channel7->out[3] = &channel7->slots[1]->out; + channel8->out[0] = &channel8->slots[0]->out; + channel8->out[1] = &channel8->slots[0]->out; + channel8->out[2] = &channel8->slots[1]->out; + channel8->out[3] = &channel8->slots[1]->out; for (chnum = 6; chnum < 9; chnum++) { chip->channel[chnum].chtype = ch_drum; } OPL3_ChannelSetupAlg(channel6); - /* hh */ + /*hh*/ if (chip->rhy & 0x01) { - OPL3_EnvelopeKeyOn(channel7->chipslots[0], egk_drum); + OPL3_EnvelopeKeyOn(channel7->slots[0], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel7->chipslots[0], egk_drum); + OPL3_EnvelopeKeyOff(channel7->slots[0], egk_drum); } - /* tc */ + /*tc*/ if (chip->rhy & 0x02) { - OPL3_EnvelopeKeyOn(channel8->chipslots[1], egk_drum); + OPL3_EnvelopeKeyOn(channel8->slots[1], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel8->chipslots[1], egk_drum); + OPL3_EnvelopeKeyOff(channel8->slots[1], egk_drum); } - /* tom */ + /*tom*/ if (chip->rhy & 0x04) { - OPL3_EnvelopeKeyOn(channel8->chipslots[0], egk_drum); + OPL3_EnvelopeKeyOn(channel8->slots[0], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel8->chipslots[0], egk_drum); + OPL3_EnvelopeKeyOff(channel8->slots[0], egk_drum); } - /* sd */ + /*sd*/ if (chip->rhy & 0x08) { - OPL3_EnvelopeKeyOn(channel7->chipslots[1], egk_drum); + OPL3_EnvelopeKeyOn(channel7->slots[1], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel7->chipslots[1], egk_drum); + OPL3_EnvelopeKeyOff(channel7->slots[1], egk_drum); } - /* bd */ + /*bd*/ if (chip->rhy & 0x10) { - OPL3_EnvelopeKeyOn(channel6->chipslots[0], egk_drum); - OPL3_EnvelopeKeyOn(channel6->chipslots[1], egk_drum); + OPL3_EnvelopeKeyOn(channel6->slots[0], egk_drum); + OPL3_EnvelopeKeyOn(channel6->slots[1], egk_drum); } else { - OPL3_EnvelopeKeyOff(channel6->chipslots[0], egk_drum); - OPL3_EnvelopeKeyOff(channel6->chipslots[1], egk_drum); + OPL3_EnvelopeKeyOff(channel6->slots[0], egk_drum); + OPL3_EnvelopeKeyOff(channel6->slots[1], egk_drum); } } else @@ -878,13 +709,13 @@ static INLINE void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) { chip->channel[chnum].chtype = ch_2op; OPL3_ChannelSetupAlg(&chip->channel[chnum]); - OPL3_EnvelopeKeyOff(chip->channel[chnum].chipslots[0], egk_drum); - OPL3_EnvelopeKeyOff(chip->channel[chnum].chipslots[1], egk_drum); + OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[0], egk_drum); + OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[1], egk_drum); } } } -static INLINE void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data) +static void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data) { if (channel->chip->newm && channel->chtype == ch_4op2) { @@ -893,22 +724,22 @@ static INLINE void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data) channel->f_num = (channel->f_num & 0x300) | data; channel->ksv = (channel->block << 1) | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - OPL3_EnvelopeUpdateKSL(channel->chipslots[0]); - OPL3_EnvelopeUpdateKSL(channel->chipslots[1]); - OPL3_EnvelopeUpdateRate(channel->chipslots[0]); - OPL3_EnvelopeUpdateRate(channel->chipslots[1]); + OPL3_EnvelopeUpdateKSL(channel->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->slots[1]); + OPL3_EnvelopeUpdateRate(channel->slots[0]); + OPL3_EnvelopeUpdateRate(channel->slots[1]); if (channel->chip->newm && channel->chtype == ch_4op) { channel->pair->f_num = channel->f_num; channel->pair->ksv = channel->ksv; - OPL3_EnvelopeUpdateKSL(channel->pair->chipslots[0]); - OPL3_EnvelopeUpdateKSL(channel->pair->chipslots[1]); - OPL3_EnvelopeUpdateRate(channel->pair->chipslots[0]); - OPL3_EnvelopeUpdateRate(channel->pair->chipslots[1]); + OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[0]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[1]); } } -static INLINE void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data) +static void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data) { if (channel->chip->newm && channel->chtype == ch_4op2) { @@ -918,23 +749,118 @@ static INLINE void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data) channel->block = (data >> 2) & 0x07; channel->ksv = (channel->block << 1) | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - OPL3_EnvelopeUpdateKSL(channel->chipslots[0]); - OPL3_EnvelopeUpdateKSL(channel->chipslots[1]); - OPL3_EnvelopeUpdateRate(channel->chipslots[0]); - OPL3_EnvelopeUpdateRate(channel->chipslots[1]); + OPL3_EnvelopeUpdateKSL(channel->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->slots[1]); + OPL3_EnvelopeUpdateRate(channel->slots[0]); + OPL3_EnvelopeUpdateRate(channel->slots[1]); if (channel->chip->newm && channel->chtype == ch_4op) { channel->pair->f_num = channel->f_num; channel->pair->block = channel->block; channel->pair->ksv = channel->ksv; - OPL3_EnvelopeUpdateKSL(channel->pair->chipslots[0]); - OPL3_EnvelopeUpdateKSL(channel->pair->chipslots[1]); - OPL3_EnvelopeUpdateRate(channel->pair->chipslots[0]); - OPL3_EnvelopeUpdateRate(channel->pair->chipslots[1]); + OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[0]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[1]); + } +} + +static void OPL3_ChannelSetupAlg(opl3_channel *channel) +{ + if (channel->chtype == ch_drum) + { + switch (channel->alg & 0x01) + { + case 0x00: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->slots[0]->out; + break; + case 0x01: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->chip->zeromod; + break; + } + return; + } + if (channel->alg & 0x08) + { + return; + } + if (channel->alg & 0x04) + { + channel->pair->out[0] = &channel->chip->zeromod; + channel->pair->out[1] = &channel->chip->zeromod; + channel->pair->out[2] = &channel->chip->zeromod; + channel->pair->out[3] = &channel->chip->zeromod; + switch (channel->alg & 0x03) + { + case 0x00: + channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; + channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; + channel->slots[0]->mod = &channel->pair->slots[1]->out; + channel->slots[1]->mod = &channel->slots[0]->out; + channel->out[0] = &channel->slots[1]->out; + channel->out[1] = &channel->chip->zeromod; + channel->out[2] = &channel->chip->zeromod; + channel->out[3] = &channel->chip->zeromod; + break; + case 0x01: + channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; + channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; + channel->slots[0]->mod = &channel->chip->zeromod; + channel->slots[1]->mod = &channel->slots[0]->out; + channel->out[0] = &channel->pair->slots[1]->out; + channel->out[1] = &channel->slots[1]->out; + channel->out[2] = &channel->chip->zeromod; + channel->out[3] = &channel->chip->zeromod; + break; + case 0x02: + channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; + channel->pair->slots[1]->mod = &channel->chip->zeromod; + channel->slots[0]->mod = &channel->pair->slots[1]->out; + channel->slots[1]->mod = &channel->slots[0]->out; + channel->out[0] = &channel->pair->slots[0]->out; + channel->out[1] = &channel->slots[1]->out; + channel->out[2] = &channel->chip->zeromod; + channel->out[3] = &channel->chip->zeromod; + break; + case 0x03: + channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; + channel->pair->slots[1]->mod = &channel->chip->zeromod; + channel->slots[0]->mod = &channel->pair->slots[1]->out; + channel->slots[1]->mod = &channel->chip->zeromod; + channel->out[0] = &channel->pair->slots[0]->out; + channel->out[1] = &channel->slots[0]->out; + channel->out[2] = &channel->slots[1]->out; + channel->out[3] = &channel->chip->zeromod; + break; + } + } + else + { + switch (channel->alg & 0x01) + { + case 0x00: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->slots[0]->out; + channel->out[0] = &channel->slots[1]->out; + channel->out[1] = &channel->chip->zeromod; + channel->out[2] = &channel->chip->zeromod; + channel->out[3] = &channel->chip->zeromod; + break; + case 0x01: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->chip->zeromod; + channel->out[0] = &channel->slots[0]->out; + channel->out[1] = &channel->slots[1]->out; + channel->out[2] = &channel->chip->zeromod; + channel->out[3] = &channel->chip->zeromod; + break; + } } } -static INLINE void OPL3_ChannelWriteC0(opl3_channel *channel, Bit8u data) +static void OPL3_ChannelWriteC0(opl3_channel *channel, Bit8u data) { channel->fb = (data & 0x0e) >> 1; channel->con = data & 0x01; @@ -973,55 +899,55 @@ static INLINE void OPL3_ChannelWriteC0(opl3_channel *channel, Bit8u data) } } -static INLINE void OPL3_ChannelKeyOn(opl3_channel *channel) +static void OPL3_ChannelKeyOn(opl3_channel *channel) { if (channel->chip->newm) { if (channel->chtype == ch_4op) { - OPL3_EnvelopeKeyOn(channel->chipslots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->chipslots[1], egk_norm); - OPL3_EnvelopeKeyOn(channel->pair->chipslots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->pair->chipslots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->pair->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->pair->slots[1], egk_norm); } else if (channel->chtype == ch_2op || channel->chtype == ch_drum) { - OPL3_EnvelopeKeyOn(channel->chipslots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->chipslots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); } } else { - OPL3_EnvelopeKeyOn(channel->chipslots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->chipslots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); } } -static INLINE void OPL3_ChannelKeyOff(opl3_channel *channel) +static void OPL3_ChannelKeyOff(opl3_channel *channel) { if (channel->chip->newm) { if (channel->chtype == ch_4op) { - OPL3_EnvelopeKeyOff(channel->chipslots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->chipslots[1], egk_norm); - OPL3_EnvelopeKeyOff(channel->pair->chipslots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->pair->chipslots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->pair->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->pair->slots[1], egk_norm); } else if (channel->chtype == ch_2op || channel->chtype == ch_drum) { - OPL3_EnvelopeKeyOff(channel->chipslots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->chipslots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); } } else { - OPL3_EnvelopeKeyOff(channel->chipslots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->chipslots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); } } -static INLINE void OPL3_ChannelSet4Op(opl3_chip *chip, Bit8u data) +static void OPL3_ChannelSet4Op(opl3_chip *chip, Bit8u data) { Bit8u bit; Bit8u chnum; @@ -1045,7 +971,6 @@ static INLINE void OPL3_ChannelSet4Op(opl3_chip *chip, Bit8u data) } } -/* static Bit16s OPL3_ClipSample(Bit32s sample) { if (sample > 32767) @@ -1057,12 +982,9 @@ static Bit16s OPL3_ClipSample(Bit32s sample) sample = -32768; } return (Bit16s)sample; -}*/ - -#define OPL3_ClipSample(sample) \ - (Bit16s)( ((sample) > 32767) ? 32767 : ( ((sample) < -32768) ? -32768 : (sample)) ) +} -static INLINE void OPL3_GenerateRhythm1(opl3_chip *chip) +static void OPL3_GenerateRhythm1(opl3_chip *chip) { opl3_channel *channel6; opl3_channel *channel7; @@ -1075,22 +997,22 @@ static INLINE void OPL3_GenerateRhythm1(opl3_chip *chip) channel6 = &chip->channel[6]; channel7 = &chip->channel[7]; channel8 = &chip->channel[8]; - OPL3_SlotGenerate(channel6->chipslots[0]); - phase14 = (channel7->chipslots[0]->pg_phase >> 9) & 0x3ff; - phase17 = (channel8->chipslots[1]->pg_phase >> 9) & 0x3ff; + OPL3_SlotGenerate(channel6->slots[0]); + phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; + phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; phase = 0x00; - /* hh tc phase bit */ + /*hh tc phase bit*/ phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; - /* hh */ + /*hh*/ phase = (phasebit << 9) | (0x34 << ((phasebit ^ (chip->noise & 0x01)) << 1)); - OPL3_SlotGeneratePhase(channel7->chipslots[0], phase); - /* tt */ - OPL3_SlotGenerateZM(channel8->chipslots[0]); + OPL3_SlotGeneratePhase(channel7->slots[0], phase); + /*tt*/ + OPL3_SlotGenerateZM(channel8->slots[0]); } -static INLINE void OPL3_GenerateRhythm2(opl3_chip *chip) +static void OPL3_GenerateRhythm2(opl3_chip *chip) { opl3_channel *channel6; opl3_channel *channel7; @@ -1103,22 +1025,22 @@ static INLINE void OPL3_GenerateRhythm2(opl3_chip *chip) channel6 = &chip->channel[6]; channel7 = &chip->channel[7]; channel8 = &chip->channel[8]; - OPL3_SlotGenerate(channel6->chipslots[1]); - phase14 = (channel7->chipslots[0]->pg_phase >> 9) & 0x3ff; - phase17 = (channel8->chipslots[1]->pg_phase >> 9) & 0x3ff; + OPL3_SlotGenerate(channel6->slots[1]); + phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; + phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; phase = 0x00; - /* hh tc phase bit */ + /*hh tc phase bit*/ phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; - /* sd */ + /*sd*/ phase = (0x100 << ((phase14 >> 8) & 0x01)) ^ ((chip->noise & 0x01) << 8); - OPL3_SlotGeneratePhase(channel7->chipslots[1], phase); - /* tc */ + OPL3_SlotGeneratePhase(channel7->slots[1], phase); + /*tc*/ phase = 0x100 | (phasebit << 9); - OPL3_SlotGeneratePhase(channel8->chipslots[1], phase); + OPL3_SlotGeneratePhase(channel8->slots[1], phase); } -static INLINE void OPL3_GenerateREAL(opl3_chip *chip, Bit16s *buf) +void OPL3_Generate(opl3_chip *chip, Bit16s *buf) { Bit8u ii; Bit8u jj; @@ -1128,17 +1050,17 @@ static INLINE void OPL3_GenerateREAL(opl3_chip *chip, Bit16s *buf) for (ii = 0; ii < 12; ii++) { - OPL3_SlotCalcFB(&chip->slot[ii]); - OPL3_PhaseGenerate(&chip->slot[ii]); - OPL3_EnvelopeCalc(&chip->slot[ii]); - OPL3_SlotGenerate(&chip->slot[ii]); + OPL3_SlotCalcFB(&chip->chipslot[ii]); + OPL3_PhaseGenerate(&chip->chipslot[ii]); + OPL3_EnvelopeCalc(&chip->chipslot[ii]); + OPL3_SlotGenerate(&chip->chipslot[ii]); } for (ii = 12; ii < 15; ii++) { - OPL3_SlotCalcFB(&chip->slot[ii]); - OPL3_PhaseGenerate(&chip->slot[ii]); - OPL3_EnvelopeCalc(&chip->slot[ii]); + OPL3_SlotCalcFB(&chip->chipslot[ii]); + OPL3_PhaseGenerate(&chip->chipslot[ii]); + OPL3_EnvelopeCalc(&chip->chipslot[ii]); } if (chip->rhy & 0x20) @@ -1147,9 +1069,9 @@ static INLINE void OPL3_GenerateREAL(opl3_chip *chip, Bit16s *buf) } else { - OPL3_SlotGenerate(&chip->slot[12]); - OPL3_SlotGenerate(&chip->slot[13]); - OPL3_SlotGenerate(&chip->slot[14]); + OPL3_SlotGenerate(&chip->chipslot[12]); + OPL3_SlotGenerate(&chip->chipslot[13]); + OPL3_SlotGenerate(&chip->chipslot[14]); } chip->mixbuff[0] = 0; @@ -1165,9 +1087,9 @@ static INLINE void OPL3_GenerateREAL(opl3_chip *chip, Bit16s *buf) for (ii = 15; ii < 18; ii++) { - OPL3_SlotCalcFB(&chip->slot[ii]); - OPL3_PhaseGenerate(&chip->slot[ii]); - OPL3_EnvelopeCalc(&chip->slot[ii]); + OPL3_SlotCalcFB(&chip->chipslot[ii]); + OPL3_PhaseGenerate(&chip->chipslot[ii]); + OPL3_EnvelopeCalc(&chip->chipslot[ii]); } if (chip->rhy & 0x20) @@ -1176,19 +1098,19 @@ static INLINE void OPL3_GenerateREAL(opl3_chip *chip, Bit16s *buf) } else { - OPL3_SlotGenerate(&chip->slot[15]); - OPL3_SlotGenerate(&chip->slot[16]); - OPL3_SlotGenerate(&chip->slot[17]); + OPL3_SlotGenerate(&chip->chipslot[15]); + OPL3_SlotGenerate(&chip->chipslot[16]); + OPL3_SlotGenerate(&chip->chipslot[17]); } buf[0] = OPL3_ClipSample(chip->mixbuff[0]); for (ii = 18; ii < 33; ii++) { - OPL3_SlotCalcFB(&chip->slot[ii]); - OPL3_PhaseGenerate(&chip->slot[ii]); - OPL3_EnvelopeCalc(&chip->slot[ii]); - OPL3_SlotGenerate(&chip->slot[ii]); + OPL3_SlotCalcFB(&chip->chipslot[ii]); + OPL3_PhaseGenerate(&chip->chipslot[ii]); + OPL3_EnvelopeCalc(&chip->chipslot[ii]); + OPL3_SlotGenerate(&chip->chipslot[ii]); } chip->mixbuff[1] = 0; @@ -1204,10 +1126,10 @@ static INLINE void OPL3_GenerateREAL(opl3_chip *chip, Bit16s *buf) for (ii = 33; ii < 36; ii++) { - OPL3_SlotCalcFB(&chip->slot[ii]); - OPL3_PhaseGenerate(&chip->slot[ii]); - OPL3_EnvelopeCalc(&chip->slot[ii]); - OPL3_SlotGenerate(&chip->slot[ii]); + OPL3_SlotCalcFB(&chip->chipslot[ii]); + OPL3_PhaseGenerate(&chip->chipslot[ii]); + OPL3_EnvelopeCalc(&chip->chipslot[ii]); + OPL3_SlotGenerate(&chip->chipslot[ii]); } OPL3_NoiseGenerate(chip); @@ -1246,13 +1168,13 @@ static INLINE void OPL3_GenerateREAL(opl3_chip *chip, Bit16s *buf) chip->writebuf_samplecnt++; } -static INLINE void OPL3_GenerateResampledREAL(opl3_chip *chip, Bit16s *buf) +void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf) { while (chip->samplecnt >= chip->rateratio) { chip->oldsamples[0] = chip->samples[0]; chip->oldsamples[1] = chip->samples[1]; - OPL3_GenerateREAL(chip, chip->samples); + OPL3_Generate(chip, chip->samples); chip->samplecnt -= chip->rateratio; } buf[0] = (Bit16s)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt) @@ -1262,16 +1184,6 @@ static INLINE void OPL3_GenerateResampledREAL(opl3_chip *chip, Bit16s *buf) chip->samplecnt += 1 << RSM_FRAC; } -void OPL3_Generate(opl3_chip *chip, Bit16s *buf) -{ - OPL3_GenerateREAL(chip, buf); -} - -void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf) -{ - OPL3_GenerateResampledREAL(chip, buf); -} - void OPL3_Reset(opl3_chip *chip, Bit32u samplerate) { Bit8u slotnum; @@ -1280,19 +1192,20 @@ void OPL3_Reset(opl3_chip *chip, Bit32u samplerate) memset(chip, 0, sizeof(opl3_chip)); for (slotnum = 0; slotnum < 36; slotnum++) { - chip->slot[slotnum].chip = chip; - chip->slot[slotnum].mod = &chip->zeromod; - chip->slot[slotnum].eg_rout = 0x1ff; - chip->slot[slotnum].eg_out = 0x1ff; - chip->slot[slotnum].eg_gen = envelope_gen_num_off; - chip->slot[slotnum].trem = (Bit8u*)&chip->zeromod; + chip->chipslot[slotnum].chip = chip; + chip->chipslot[slotnum].mod = &chip->zeromod; + chip->chipslot[slotnum].eg_rout = 0x1ff; + chip->chipslot[slotnum].eg_out = 0x1ff << 3; + chip->chipslot[slotnum].eg_gen = envelope_gen_num_off; + chip->chipslot[slotnum].trem = (Bit8u*)&chip->zeromod; + chip->chipslot[slotnum].signpos = (31-9); /* for wf=0 need use sigext of (phase & 0x200) */ } for (channum = 0; channum < 18; channum++) { - chip->channel[channum].chipslots[0] = &chip->slot[ch_slot[channum]]; - chip->channel[channum].chipslots[1] = &chip->slot[ch_slot[channum] + 3]; - chip->slot[ch_slot[channum]].channel = &chip->channel[channum]; - chip->slot[ch_slot[channum] + 3].channel = &chip->channel[channum]; + chip->channel[channum].slots[0] = &chip->chipslot[ch_slot[channum]]; + chip->channel[channum].slots[1] = &chip->chipslot[ch_slot[channum] + 3]; + chip->chipslot[ch_slot[channum]].channel = &chip->channel[channum]; + chip->chipslot[ch_slot[channum] + 3].channel = &chip->channel[channum]; if ((channum % 9) < 3) { chip->channel[channum].pair = &chip->channel[channum + 3]; @@ -1350,35 +1263,35 @@ void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v) case 0x30: if (ad_slot[regm & 0x1f] >= 0) { - OPL3_SlotWrite20(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + OPL3_SlotWrite20(&chip->chipslot[18 * high + ad_slot[regm & 0x1f]], v); } break; case 0x40: case 0x50: if (ad_slot[regm & 0x1f] >= 0) { - OPL3_SlotWrite40(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + OPL3_SlotWrite40(&chip->chipslot[18 * high + ad_slot[regm & 0x1f]], v); } break; case 0x60: case 0x70: if (ad_slot[regm & 0x1f] >= 0) { - OPL3_SlotWrite60(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + OPL3_SlotWrite60(&chip->chipslot[18 * high + ad_slot[regm & 0x1f]], v); } break; case 0x80: case 0x90: if (ad_slot[regm & 0x1f] >= 0) { - OPL3_SlotWrite80(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + OPL3_SlotWrite80(&chip->chipslot[18 * high + ad_slot[regm & 0x1f]], v); } break; case 0xe0: case 0xf0: if (ad_slot[regm & 0x1f] >= 0) { - OPL3_SlotWriteE0(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + OPL3_SlotWriteE0(&chip->chipslot[18 * high + ad_slot[regm & 0x1f]], v); } break; case 0xa0: @@ -1450,7 +1363,7 @@ void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples) for(i = 0; i < numsamples; i++) { - OPL3_GenerateResampledREAL(chip, sndptr); + OPL3_GenerateResampled(chip, sndptr); sndptr += 2; } } @@ -1467,7 +1380,7 @@ void OPL3_GenerateStreamMix(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples) for(i = 0; i < numsamples; i++) { - OPL3_GenerateResampledREAL(chip, sample); + OPL3_GenerateResampled(chip, sample); mix[0] = sndptr[0] + sample[0]; mix[1] = sndptr[1] + sample[1]; sndptr[0] = OPL3_CLAMP(mix[0], INT16_MIN, INT16_MAX); |