diff options
author | Wohlstand <admin@wohlnet.ru> | 2020-09-13 15:58:37 +0300 |
---|---|---|
committer | Wohlstand <admin@wohlnet.ru> | 2020-09-13 15:58:37 +0300 |
commit | 7f66550168af30e03b7762ba9ce6a9d56f578064 (patch) | |
tree | 37e436127c4701902b63ec2d360797d16aeedda8 /src/adlmidi_midiplay.cpp | |
parent | e6806ad8a4ce1c91530e031b1aac1d89c68b9481 (diff) | |
download | libADLMIDI-7f66550168af30e03b7762ba9ce6a9d56f578064.tar.gz libADLMIDI-7f66550168af30e03b7762ba9ce6a9d56f578064.tar.bz2 libADLMIDI-7f66550168af30e03b7762ba9ce6a9d56f578064.zip |
Move all frequency computation code from a MIDIPlay into the Synth
Diffstat (limited to 'src/adlmidi_midiplay.cpp')
-rw-r--r-- | src/adlmidi_midiplay.cpp | 621 |
1 files changed, 6 insertions, 615 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 572e7da..8a6751d 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -29,585 +29,9 @@ // Minimum life time of percussion notes static const double s_drum_note_min_time = 0.03; - - - -/*************************************************************** - * Standard frequency formula * - * *************************************************************/ - -static inline double s_commonFreq(double note, double bend) -{ - return BEND_COEFFICIENT * std::exp(0.057762265 * (note + bend)); -} - - - - -/*************************************************************** - * DMX frequency model * - * *************************************************************/ - -// DMX volumes table -static const int_fast32_t s_dmx_freq_table[] = -{ - 0x0133, 0x0133, 0x0134, 0x0134, 0x0135, 0x0136, 0x0136, 0x0137, - 0x0137, 0x0138, 0x0138, 0x0139, 0x0139, 0x013A, 0x013B, 0x013B, - 0x013C, 0x013C, 0x013D, 0x013D, 0x013E, 0x013F, 0x013F, 0x0140, - 0x0140, 0x0141, 0x0142, 0x0142, 0x0143, 0x0143, 0x0144, 0x0144, - - 0x0145, 0x0146, 0x0146, 0x0147, 0x0147, 0x0148, 0x0149, 0x0149, - 0x014A, 0x014A, 0x014B, 0x014C, 0x014C, 0x014D, 0x014D, 0x014E, - 0x014F, 0x014F, 0x0150, 0x0150, 0x0151, 0x0152, 0x0152, 0x0153, - 0x0153, 0x0154, 0x0155, 0x0155, 0x0156, 0x0157, 0x0157, 0x0158, - - 0x0158, 0x0159, 0x015A, 0x015A, 0x015B, 0x015B, 0x015C, 0x015D, - 0x015D, 0x015E, 0x015F, 0x015F, 0x0160, 0x0161, 0x0161, 0x0162, - 0x0162, 0x0163, 0x0164, 0x0164, 0x0165, 0x0166, 0x0166, 0x0167, - 0x0168, 0x0168, 0x0169, 0x016A, 0x016A, 0x016B, 0x016C, 0x016C, - - 0x016D, 0x016E, 0x016E, 0x016F, 0x0170, 0x0170, 0x0171, 0x0172, - 0x0172, 0x0173, 0x0174, 0x0174, 0x0175, 0x0176, 0x0176, 0x0177, - 0x0178, 0x0178, 0x0179, 0x017A, 0x017A, 0x017B, 0x017C, 0x017C, - 0x017D, 0x017E, 0x017E, 0x017F, 0x0180, 0x0181, 0x0181, 0x0182, - - 0x0183, 0x0183, 0x0184, 0x0185, 0x0185, 0x0186, 0x0187, 0x0188, - 0x0188, 0x0189, 0x018A, 0x018A, 0x018B, 0x018C, 0x018D, 0x018D, - 0x018E, 0x018F, 0x018F, 0x0190, 0x0191, 0x0192, 0x0192, 0x0193, - 0x0194, 0x0194, 0x0195, 0x0196, 0x0197, 0x0197, 0x0198, 0x0199, - - 0x019A, 0x019A, 0x019B, 0x019C, 0x019D, 0x019D, 0x019E, 0x019F, - 0x01A0, 0x01A0, 0x01A1, 0x01A2, 0x01A3, 0x01A3, 0x01A4, 0x01A5, - 0x01A6, 0x01A6, 0x01A7, 0x01A8, 0x01A9, 0x01A9, 0x01AA, 0x01AB, - 0x01AC, 0x01AD, 0x01AD, 0x01AE, 0x01AF, 0x01B0, 0x01B0, 0x01B1, - - 0x01B2, 0x01B3, 0x01B4, 0x01B4, 0x01B5, 0x01B6, 0x01B7, 0x01B8, - 0x01B8, 0x01B9, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BD, 0x01BE, - 0x01BF, 0x01C0, 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, - 0x01C5, 0x01C6, 0x01C7, 0x01C8, 0x01C9, 0x01C9, 0x01CA, 0x01CB, - - 0x01CC, 0x01CD, 0x01CE, 0x01CE, 0x01CF, 0x01D0, 0x01D1, 0x01D2, - 0x01D3, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01D7, 0x01D8, 0x01D8, - 0x01D9, 0x01DA, 0x01DB, 0x01DC, 0x01DD, 0x01DE, 0x01DE, 0x01DF, - 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E4, 0x01E5, 0x01E5, 0x01E6, - - 0x01E7, 0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x01EC, 0x01ED, 0x01ED, - 0x01EE, 0x01EF, 0x01F0, 0x01F1, 0x01F2, 0x01F3, 0x01F4, 0x01F5, - 0x01F6, 0x01F6, 0x01F7, 0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC, - 0x01FD, 0x01FE, 0x01FF, - - 0x0200, 0x0201, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205, 0x0206, - 0x0207, 0x0208, 0x0209, 0x020A, 0x020B, 0x020C, 0x020D, 0x020E, - 0x020F, 0x0210, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214, 0x0215, - 0x0216, 0x0217, 0x0218, 0x0219, 0x021A, 0x021B, 0x021C, 0x021D, - - 0x021E, 0x021F, 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, - 0x0226, 0x0227, 0x0228, 0x0229, 0x022A, 0x022B, 0x022C, 0x022D, - 0x022E, 0x022F, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, 0x0235, - 0x0236, 0x0237, 0x0238, 0x0239, 0x023A, 0x023B, 0x023C, 0x023D, - - 0x023E, 0x023F, 0x0240, 0x0241, 0x0242, 0x0244, 0x0245, 0x0246, - 0x0247, 0x0248, 0x0249, 0x024A, 0x024B, 0x024C, 0x024D, 0x024E, - 0x024F, 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0256, 0x0257, - 0x0258, 0x0259, 0x025A, 0x025B, 0x025C, 0x025D, 0x025E, 0x025F, - - 0x0260, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267, 0x0268, - 0x0269, 0x026A, 0x026C, 0x026D, 0x026E, 0x026F, 0x0270, 0x0271, - 0x0272, 0x0273, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, 0x027A, - 0x027B, 0x027D, 0x027E, 0x027F, 0x0280, 0x0281, 0x0282, 0x0284, - - 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x028B, 0x028C, 0x028D, - 0x028E, 0x028F, 0x0290, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, - 0x0298, 0x0299, 0x029A, 0x029B, 0x029C, 0x029E, 0x029F, 0x02A0, - 0x02A1, 0x02A2, 0x02A4, 0x02A5, 0x02A6, 0x02A7, 0x02A9, 0x02AA, - - 0x02AB, 0x02AC, 0x02AE, 0x02AF, 0x02B0, 0x02B1, 0x02B2, 0x02B4, - 0x02B5, 0x02B6, 0x02B7, 0x02B9, 0x02BA, 0x02BB, 0x02BD, 0x02BE, - 0x02BF, 0x02C0, 0x02C2, 0x02C3, 0x02C4, 0x02C5, 0x02C7, 0x02C8, - 0x02C9, 0x02CB, 0x02CC, 0x02CD, 0x02CE, 0x02D0, 0x02D1, 0x02D2, - - 0x02D4, 0x02D5, 0x02D6, 0x02D8, 0x02D9, 0x02DA, 0x02DC, 0x02DD, - 0x02DE, 0x02E0, 0x02E1, 0x02E2, 0x02E4, 0x02E5, 0x02E6, 0x02E8, - 0x02E9, 0x02EA, 0x02EC, 0x02ED, 0x02EE, 0x02F0, 0x02F1, 0x02F2, - 0x02F4, 0x02F5, 0x02F6, 0x02F8, 0x02F9, 0x02FB, 0x02FC, 0x02FD, - - 0x02FF, 0x0300, 0x0302, 0x0303, 0x0304, 0x0306, 0x0307, 0x0309, - 0x030A, 0x030B, 0x030D, 0x030E, 0x0310, 0x0311, 0x0312, 0x0314, - 0x0315, 0x0317, 0x0318, 0x031A, 0x031B, 0x031C, 0x031E, 0x031F, - 0x0321, 0x0322, 0x0324, 0x0325, 0x0327, 0x0328, 0x0329, 0x032B, - - 0x032C, 0x032E, 0x032F, 0x0331, 0x0332, 0x0334, 0x0335, 0x0337, - 0x0338, 0x033A, 0x033B, 0x033D, 0x033E, 0x0340, 0x0341, 0x0343, - 0x0344, 0x0346, 0x0347, 0x0349, 0x034A, 0x034C, 0x034D, 0x034F, - 0x0350, 0x0352, 0x0353, 0x0355, 0x0357, 0x0358, 0x035A, 0x035B, - - 0x035D, 0x035E, 0x0360, 0x0361, 0x0363, 0x0365, 0x0366, 0x0368, - 0x0369, 0x036B, 0x036C, 0x036E, 0x0370, 0x0371, 0x0373, 0x0374, - 0x0376, 0x0378, 0x0379, 0x037B, 0x037C, 0x037E, 0x0380, 0x0381, - 0x0383, 0x0384, 0x0386, 0x0388, 0x0389, 0x038B, 0x038D, 0x038E, - - 0x0390, 0x0392, 0x0393, 0x0395, 0x0397, 0x0398, 0x039A, 0x039C, - 0x039D, 0x039F, 0x03A1, 0x03A2, 0x03A4, 0x03A6, 0x03A7, 0x03A9, - 0x03AB, 0x03AC, 0x03AE, 0x03B0, 0x03B1, 0x03B3, 0x03B5, 0x03B7, - 0x03B8, 0x03BA, 0x03BC, 0x03BD, 0x03BF, 0x03C1, 0x03C3, 0x03C4, - - 0x03C6, 0x03C8, 0x03CA, 0x03CB, 0x03CD, 0x03CF, 0x03D1, 0x03D2, - 0x03D4, 0x03D6, 0x03D8, 0x03DA, 0x03DB, 0x03DD, 0x03DF, 0x03E1, - 0x03E3, 0x03E4, 0x03E6, 0x03E8, 0x03EA, 0x03EC, 0x03ED, 0x03EF, - 0x03F1, 0x03F3, 0x03F5, 0x03F6, 0x03F8, 0x03FA, 0x03FC, 0x03FE, - - 0x036C -}; - -static inline double s_dmxFreq(double note, double bend) -{ - uint_fast32_t noteI = (uint_fast32_t)(note + 0.5); - int_fast32_t bendI = 0; - int_fast32_t outHz = 0.0; - double bendDec = bend - (int)bend; - - noteI += (int)bend; - - bendI = (int_fast32_t)((bendDec * 128.0) / 2.0) + 128; - bendI = bendI >> 1; - - int_fast32_t oct = 0; - int_fast32_t freqIndex = (noteI << 5) + bendI; - - if(freqIndex < 0) - freqIndex = 0; - else if(freqIndex >= 284) - { - freqIndex -= 284; - oct = freqIndex / 384; - freqIndex = (freqIndex % 384) + 284; - } - - outHz = s_dmx_freq_table[freqIndex]; - - while(oct > 1) - { - outHz *= 2; - oct -= 1; - } - - return (double)outHz; -} - - - - -/*************************************************************** - * Apogee Sound System frequency model * - ***************************************************************/ - -static const int_fast32_t s_apogee_freq_table[31 + 1][12] = -{ - { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x241, 0x263, 0x287 }, - { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x242, 0x264, 0x288 }, - { 0x158, 0x16c, 0x182, 0x199, 0x1b1, 0x1cb, 0x1e6, 0x203, 0x221, 0x243, 0x265, 0x289 }, - { 0x158, 0x16c, 0x183, 0x19a, 0x1b2, 0x1cc, 0x1e7, 0x204, 0x222, 0x244, 0x266, 0x28a }, - { 0x159, 0x16d, 0x183, 0x19a, 0x1b3, 0x1cd, 0x1e8, 0x205, 0x223, 0x245, 0x267, 0x28b }, - { 0x15a, 0x16e, 0x184, 0x19b, 0x1b3, 0x1ce, 0x1e9, 0x206, 0x224, 0x246, 0x268, 0x28c }, - { 0x15a, 0x16e, 0x185, 0x19c, 0x1b4, 0x1ce, 0x1ea, 0x207, 0x225, 0x247, 0x269, 0x28e }, - { 0x15b, 0x16f, 0x185, 0x19d, 0x1b5, 0x1cf, 0x1eb, 0x208, 0x226, 0x248, 0x26a, 0x28f }, - { 0x15b, 0x170, 0x186, 0x19d, 0x1b6, 0x1d0, 0x1ec, 0x209, 0x227, 0x249, 0x26b, 0x290 }, - { 0x15c, 0x170, 0x187, 0x19e, 0x1b7, 0x1d1, 0x1ec, 0x20a, 0x228, 0x24a, 0x26d, 0x291 }, - { 0x15d, 0x171, 0x188, 0x19f, 0x1b7, 0x1d2, 0x1ed, 0x20b, 0x229, 0x24b, 0x26e, 0x292 }, - { 0x15d, 0x172, 0x188, 0x1a0, 0x1b8, 0x1d3, 0x1ee, 0x20c, 0x22a, 0x24c, 0x26f, 0x293 }, - { 0x15e, 0x172, 0x189, 0x1a0, 0x1b9, 0x1d4, 0x1ef, 0x20d, 0x22b, 0x24d, 0x270, 0x295 }, - { 0x15f, 0x173, 0x18a, 0x1a1, 0x1ba, 0x1d4, 0x1f0, 0x20e, 0x22c, 0x24e, 0x271, 0x296 }, - { 0x15f, 0x174, 0x18a, 0x1a2, 0x1bb, 0x1d5, 0x1f1, 0x20f, 0x22d, 0x24f, 0x272, 0x297 }, - { 0x160, 0x174, 0x18b, 0x1a3, 0x1bb, 0x1d6, 0x1f2, 0x210, 0x22e, 0x250, 0x273, 0x298 }, - { 0x161, 0x175, 0x18c, 0x1a3, 0x1bc, 0x1d7, 0x1f3, 0x211, 0x22f, 0x251, 0x274, 0x299 }, - { 0x161, 0x176, 0x18c, 0x1a4, 0x1bd, 0x1d8, 0x1f4, 0x212, 0x230, 0x252, 0x276, 0x29b }, - { 0x162, 0x176, 0x18d, 0x1a5, 0x1be, 0x1d9, 0x1f5, 0x212, 0x231, 0x254, 0x277, 0x29c }, - { 0x162, 0x177, 0x18e, 0x1a6, 0x1bf, 0x1d9, 0x1f5, 0x213, 0x232, 0x255, 0x278, 0x29d }, - { 0x163, 0x178, 0x18f, 0x1a6, 0x1bf, 0x1da, 0x1f6, 0x214, 0x233, 0x256, 0x279, 0x29e }, - { 0x164, 0x179, 0x18f, 0x1a7, 0x1c0, 0x1db, 0x1f7, 0x215, 0x235, 0x257, 0x27a, 0x29f }, - { 0x164, 0x179, 0x190, 0x1a8, 0x1c1, 0x1dc, 0x1f8, 0x216, 0x236, 0x258, 0x27b, 0x2a1 }, - { 0x165, 0x17a, 0x191, 0x1a9, 0x1c2, 0x1dd, 0x1f9, 0x217, 0x237, 0x259, 0x27c, 0x2a2 }, - { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1de, 0x1fa, 0x218, 0x238, 0x25a, 0x27e, 0x2a3 }, - { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1df, 0x1fb, 0x219, 0x239, 0x25b, 0x27f, 0x2a4 }, - { 0x167, 0x17c, 0x193, 0x1ab, 0x1c4, 0x1e0, 0x1fc, 0x21a, 0x23a, 0x25c, 0x280, 0x2a6 }, - { 0x168, 0x17d, 0x194, 0x1ac, 0x1c5, 0x1e0, 0x1fd, 0x21b, 0x23b, 0x25d, 0x281, 0x2a7 }, - { 0x168, 0x17d, 0x194, 0x1ad, 0x1c6, 0x1e1, 0x1fe, 0x21c, 0x23c, 0x25e, 0x282, 0x2a8 }, - { 0x169, 0x17e, 0x195, 0x1ad, 0x1c7, 0x1e2, 0x1ff, 0x21d, 0x23d, 0x260, 0x283, 0x2a9 }, - { 0x16a, 0x17f, 0x196, 0x1ae, 0x1c8, 0x1e3, 0x1ff, 0x21e, 0x23e, 0x261, 0x284, 0x2ab }, - { 0x16a, 0x17f, 0x197, 0x1af, 0x1c8, 0x1e4, 0x200, 0x21f, 0x23f, 0x262, 0x286, 0x2ac } -}; - -static inline double s_apogeeFreq(double note, double bend) -{ - uint_fast32_t noteI = (uint_fast32_t)(note + 0.5); - int_fast32_t bendI = 0; - int_fast32_t outHz = 0.0; - double bendDec = bend - (int)bend; - int_fast32_t octave; - int_fast32_t scaleNote; - - noteI += (int)bend; - bendI = (int_fast32_t)(bendDec * 32) + 32; - - noteI += bendI / 32; - noteI -= 1; - - scaleNote = noteI % 12; - octave = noteI / 12; - - outHz = s_apogee_freq_table[bendI % 32][scaleNote]; - - while(octave > 1) - { - outHz *= 2; - octave -= 1; - } - - return (double)outHz; -} - - - - -/*************************************************************** - * Windows 9x FM drivers frequency model * - ***************************************************************/ - -//static const double s_9x_opl_samplerate = 50000.0; -//static const double s_9x_opl_tune = 440.0; -static const uint_fast8_t s_9x_opl_pitchfrac = 8; - -static const uint_fast32_t s_9x_opl_freq[12] = -{ - 0xAB7, 0xB5A, 0xC07, 0xCBE, 0xD80, 0xE4D, 0xF27, 0x100E, 0x1102, 0x1205, 0x1318, 0x143A -}; - -static const int32_t s_9x_opl_uppitch = 31; -static const int32_t s_9x_opl_downpitch = 27; - -static uint_fast32_t s_9x_opl_applypitch(uint_fast32_t freq, int_fast32_t pitch) -{ - int32_t diff; - - if(pitch > 0) - { - diff = (pitch * s_9x_opl_uppitch) >> s_9x_opl_pitchfrac; - freq += (diff * freq) >> 15; - } - else if (pitch < 0) - { - diff = (-pitch * s_9x_opl_downpitch) >> s_9x_opl_pitchfrac; - freq -= (diff * freq) >> 15; - } - - return freq; -} - -static inline double s_9xFreq(double noteD, double bendD) -{ - uint_fast32_t note = (uint_fast32_t)(noteD + 0.5); - int_fast32_t bend; - double bendDec = bendD - (int)bendD; // 0.0 ± 1.0 - one halftone - - uint_fast32_t freq; - uint_fast32_t freqpitched; - uint_fast32_t octave; - - uint_fast32_t bendMsb; - uint_fast32_t bendLsb; - - note += (int)bendD; - bend = (int_fast32_t)(bendDec * 4096) + 8192; // convert to MIDI standard value - - bendMsb = (bend >> 7) & 0x7F; - bendLsb = (bend & 0x7F); - - bend = (bendMsb << 9) | (bendLsb << 2); - bend = (int16_t)(uint16_t)(bend + 0x8000); - - octave = note / 12; - freq = s_9x_opl_freq[note % 12]; - if(octave < 5) - freq >>= (5 - octave); - else if (octave > 5) - freq <<= (octave - 5); - - freqpitched = s_9x_opl_applypitch(freq, bend); - freqpitched *= 2; - - return (double)freqpitched; -} - - - - -/*************************************************************** - * HMI Sound Operating System frequency model * - ***************************************************************/ - -const size_t s_hmi_freqtable_size = 103; -static uint_fast32_t s_hmi_freqtable[s_hmi_freqtable_size] = -{ - 0x0157, 0x016B, 0x0181, 0x0198, 0x01B0, 0x01CA, 0x01E5, 0x0202, 0x0220, 0x0241, 0x0263, 0x0287, - 0x0557, 0x056B, 0x0581, 0x0598, 0x05B0, 0x05CA, 0x05E5, 0x0602, 0x0620, 0x0641, 0x0663, 0x0687, - 0x0957, 0x096B, 0x0981, 0x0998, 0x09B0, 0x09CA, 0x09E5, 0x0A02, 0x0A20, 0x0A41, 0x0A63, 0x0A87, - 0x0D57, 0x0D6B, 0x0D81, 0x0D98, 0x0DB0, 0x0DCA, 0x0DE5, 0x0E02, 0x0E20, 0x0E41, 0x0E63, 0x0E87, - 0x1157, 0x116B, 0x1181, 0x1198, 0x11B0, 0x11CA, 0x11E5, 0x1202, 0x1220, 0x1241, 0x1263, 0x1287, - 0x1557, 0x156B, 0x1581, 0x1598, 0x15B0, 0x15CA, 0x15E5, 0x1602, 0x1620, 0x1641, 0x1663, 0x1687, - 0x1957, 0x196B, 0x1981, 0x1998, 0x19B0, 0x19CA, 0x19E5, 0x1A02, 0x1A20, 0x1A41, 0x1A63, 0x1A87, - 0x1D57, 0x1D6B, 0x1D81, 0x1D98, 0x1DB0, 0x1DCA, 0x1DE5, 0x1E02, 0x1E20, 0x1E41, 0x1E63, 0x1E87, - 0x1EAE, 0x1EB7, 0x1F02, 0x1F30, 0x1F60, 0x1F94, 0x1FCA -}; - -const size_t s_hmi_bendtable_size = 12; -static uint_fast32_t s_hmi_bendtable[s_hmi_bendtable_size] = -{ - 0x144, 0x132, 0x121, 0x110, 0x101, 0xf8, 0xe5, 0xd8, 0xcc, 0xc1, 0xb6, 0xac -}; - -#define hmi_range_fix(formula, maxVal) \ - ( \ - (formula) < 0 ? \ - 0 : \ - ( \ - (formula) >= (int32_t)maxVal ? \ - (int32_t)maxVal : \ - (formula) \ - )\ - ) - -static uint_fast32_t s_hmi_bend_calc(uint_fast32_t bend, int_fast32_t note) -{ - const int_fast32_t midi_bend_range = 1; - uint_fast32_t bendFactor, outFreq, fmOctave, fmFreq, newFreq, idx; - int_fast32_t noteMod12; - - note -= 12; -// while(doNote >= 12) // ugly way to MOD 12 -// doNote -= 12; - noteMod12 = (note % 12); - - outFreq = s_hmi_freqtable[note]; - - fmOctave = outFreq & 0x1c00; - fmFreq = outFreq & 0x3ff; - - if(bend < 64) - { - bendFactor = ((63 - bend) * 1000) >> 6; - - idx = hmi_range_fix(note - midi_bend_range, s_hmi_freqtable_size); - newFreq = outFreq - s_hmi_freqtable[idx]; - - if(newFreq > 719) - { - newFreq = fmFreq - s_hmi_bendtable[midi_bend_range - 1]; - newFreq &= 0x3ff; - } - - newFreq = (newFreq * bendFactor) / 1000; - outFreq -= newFreq; - } - else - { - bendFactor = ((bend - 64) * 1000) >> 6; - - idx = hmi_range_fix(note + midi_bend_range, s_hmi_freqtable_size); - newFreq = s_hmi_freqtable[idx] - outFreq; - - if(newFreq > 719) - { - idx = hmi_range_fix(11 - noteMod12, s_hmi_bendtable_size); - fmFreq = s_hmi_bendtable[idx]; - outFreq = (fmOctave + 1024) | fmFreq; - - idx = hmi_range_fix(note + midi_bend_range, s_hmi_freqtable_size); - newFreq = s_hmi_freqtable[idx] - outFreq; - } - - newFreq = (newFreq * bendFactor) / 1000; - outFreq += newFreq; - } - - return outFreq; -} -#undef hmi_range_fix - -static inline double s_hmiFreq(double noteD, double bendD) -{ - int_fast32_t note = (int_fast32_t)(noteD + 0.5); - double bendDec = bendD - (int)bendD; // 0.0 ± 1.0 - one halftone - int_fast32_t bend; - uint_fast32_t inFreq; - uint_fast32_t freq; - int_fast32_t octave; - int_fast32_t octaveOffset = 0; - - note += (int)bendD; - - bend = (int_fast32_t)(bendDec * 64.0) + 64; - - while(note < 12) - { - octaveOffset--; - note += 12; - } - while(note > 114) - { - octaveOffset++; - note -= 12; - } - - if(bend == 64) - inFreq = s_hmi_freqtable[note - 12]; - else - inFreq = s_hmi_bend_calc(bend, note); - - freq = inFreq & 0x3FF; - octave = (inFreq >> 10) & 0x07; - - octave += octaveOffset; - - while(octave > 0) - { - freq *= 2; - octave -= 1; - } - - return freq; -} - - - - -/*************************************************************** - * Audio Interface Library frequency model * - ***************************************************************/ - -static const uint_fast16_t mo_freqtable[] = { - 0x02b2, 0x02b4, 0x02b7, 0x02b9, 0x02bc, 0x02be, 0x02c1, 0x02c3, - 0x02c6, 0x02c9, 0x02cb, 0x02ce, 0x02d0, 0x02d3, 0x02d6, 0x02d8, - 0x02db, 0x02dd, 0x02e0, 0x02e3, 0x02e5, 0x02e8, 0x02eb, 0x02ed, - 0x02f0, 0x02f3, 0x02f6, 0x02f8, 0x02fb, 0x02fe, 0x0301, 0x0303, - 0x0306, 0x0309, 0x030c, 0x030f, 0x0311, 0x0314, 0x0317, 0x031a, - 0x031d, 0x0320, 0x0323, 0x0326, 0x0329, 0x032b, 0x032e, 0x0331, - 0x0334, 0x0337, 0x033a, 0x033d, 0x0340, 0x0343, 0x0346, 0x0349, - 0x034c, 0x034f, 0x0352, 0x0356, 0x0359, 0x035c, 0x035f, 0x0362, - 0x0365, 0x0368, 0x036b, 0x036f, 0x0372, 0x0375, 0x0378, 0x037b, - 0x037f, 0x0382, 0x0385, 0x0388, 0x038c, 0x038f, 0x0392, 0x0395, - 0x0399, 0x039c, 0x039f, 0x03a3, 0x03a6, 0x03a9, 0x03ad, 0x03b0, - 0x03b4, 0x03b7, 0x03bb, 0x03be, 0x03c1, 0x03c5, 0x03c8, 0x03cc, - 0x03cf, 0x03d3, 0x03d7, 0x03da, 0x03de, 0x03e1, 0x03e5, 0x03e8, - 0x03ec, 0x03f0, 0x03f3, 0x03f7, 0x03fb, 0x03fe, 0xfe01, 0xfe03, - 0xfe05, 0xfe07, 0xfe08, 0xfe0a, 0xfe0c, 0xfe0e, 0xfe10, 0xfe12, - 0xfe14, 0xfe16, 0xfe18, 0xfe1a, 0xfe1c, 0xfe1e, 0xfe20, 0xfe21, - 0xfe23, 0xfe25, 0xfe27, 0xfe29, 0xfe2b, 0xfe2d, 0xfe2f, 0xfe31, - 0xfe34, 0xfe36, 0xfe38, 0xfe3a, 0xfe3c, 0xfe3e, 0xfe40, 0xfe42, - 0xfe44, 0xfe46, 0xfe48, 0xfe4a, 0xfe4c, 0xfe4f, 0xfe51, 0xfe53, - 0xfe55, 0xfe57, 0xfe59, 0xfe5c, 0xfe5e, 0xfe60, 0xfe62, 0xfe64, - 0xfe67, 0xfe69, 0xfe6b, 0xfe6d, 0xfe6f, 0xfe72, 0xfe74, 0xfe76, - 0xfe79, 0xfe7b, 0xfe7d, 0xfe7f, 0xfe82, 0xfe84, 0xfe86, 0xfe89, - 0xfe8b, 0xfe8d, 0xfe90, 0xfe92, 0xfe95, 0xfe97, 0xfe99, 0xfe9c, - 0xfe9e, 0xfea1, 0xfea3, 0xfea5, 0xfea8, 0xfeaa, 0xfead, 0xfeaf -}; - -static const uint_fast8_t mo_note_octave[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07 -}; - -static const uint_fast8_t mo_note_halftone[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b -}; - -static inline double s_ailFreq(double noteD, double bendD) -{ - int_fast32_t note = (int_fast32_t)(noteD + 0.5); - double bendDec = bendD - (int)bendD; // 0.0 ± 1.0 - one halftone - int_fast32_t pitch; - uint_fast16_t freq; - int_fast32_t octave; - int_fast32_t octaveOffset = 0; - uint_fast8_t halftones; - - note += (int)bendD; - pitch = (int_fast32_t)(bendDec * 4096) + 8192; // convert to MIDI standard value - pitch = ((pitch - 0x2000) / 0x20) * 2; - - note -= 12; - - while(note < 0) - { - octaveOffset--; - note += 12; - } - while(note > 95) - { - octaveOffset++; - note -= 12; - } - - pitch += (((uint_fast8_t)note) << 8) + 8; - pitch /= 16; - while (pitch < 12 * 16) { - pitch += 12 * 16; - } - while (pitch > 96 * 16 - 1) { - pitch -= 12 * 16; - } - - halftones = (mo_note_halftone[pitch >> 4] << 4) + (pitch & 0x0f); - freq = mo_freqtable[halftones]; - octave = mo_note_octave[pitch >> 4]; - - if((freq & 0x8000) == 0) - { - if (octave > 0) { - octave--; - } else { - freq /= 2; - } - } - - freq &= 0x3FF; - - octave += octaveOffset; - - while(octave > 0) - { - freq *= 2; - octave -= 1; - } - - return freq; -} - - - - enum { MasterVolumeDefault = 127 }; + inline bool isXgPercChannel(uint8_t msb, uint8_t lsb) { return (msb == 0x7E || msb == 0x7F) && (lsb == 0); @@ -1109,7 +533,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) if(ccount == 0) { // Only use four-op master channels - if(synth.m_channelCategory[a] != Synth::ChanCat_4op_Master) + if(synth.m_channelCategory[a] != Synth::ChanCat_4op_First) continue; } else @@ -1769,7 +1193,7 @@ void MIDIplay::noteUpdate(size_t midCh, { const MIDIchannel::NoteInfo::Phys &ins = info.chip_channels[ccount]; uint16_t c = ins.chip_chan; - uint16_t c_slave = info.chip_channels[1].chip_chan; + uint16_t c_secondary = info.chip_channels[1].chip_chan; if(select_adlchn >= 0 && c != select_adlchn) continue; @@ -1866,7 +1290,6 @@ void MIDIplay::noteUpdate(size_t midCh, double bend = midibend + ins.ains.finetune; double phase = 0.0; uint8_t vibrato = std::max(chan.vibrato, chan.aftertouch); - double finalFreq; vibrato = std::max(vibrato, info.vibrato); @@ -1878,39 +1301,7 @@ void MIDIplay::noteUpdate(size_t midCh, if(vibrato && (d.is_end() || d->value.vibdelay_us >= chan.vibdelay_us)) bend += static_cast<double>(vibrato) * chan.vibdepth * std::sin(chan.vibpos); - bend += phase; - - // Use different frequency formulas in depend on a volume model - switch(synth.m_volumeScale) - { - case Synth::VOLUME_DMX: - case Synth::VOLUME_DMX_FIXED: - finalFreq = s_dmxFreq(currentTone, bend); - break; - - case Synth::VOLUME_APOGEE: - case Synth::VOLUME_APOGEE_FIXED: - finalFreq = s_apogeeFreq(currentTone, bend); - break; - - case Synth::VOLUME_9X: - case Synth::VOLUME_9X_GENERIC_FM: - finalFreq = s_9xFreq(currentTone, bend); - break; - - case Synth::VOLUME_HMI: - finalFreq = s_hmiFreq(currentTone, bend); - break; - - case Synth::VOLUME_AIL: - finalFreq = s_ailFreq(currentTone, bend); - break; - - default: - finalFreq = s_commonFreq(currentTone, bend); - } - - synth.noteOn(c, c_slave, finalFreq); + synth.noteOn(c, c_secondary, currentTone + bend + phase); if(hooks.onNote) hooks.onNote(hooks.onNote_userData, c, noteTone, midiins, vol, midibend); @@ -2471,8 +1862,8 @@ void MIDIplay::describeChannels(char *str, char *attr, size_t size) case Synth::ChanCat_Regular: str[index] = '+'; break; - case Synth::ChanCat_4op_Master: - case Synth::ChanCat_4op_Slave: + case Synth::ChanCat_4op_First: + case Synth::ChanCat_4op_Second: str[index] = '#'; break; default: // rhythm-mode percussion |