| @@ -28,7 +28,7 @@ · 27 unmodified lines |
| 28 | */ | 28 | */ |
| 29 | | 29 | |
| 30 | // non-FT2 precalced stuff (these are kinda big...) | 30 | // non-FT2 precalced stuff (these are kinda big...) |
| 31 | static double dPeriod2HzTab[65536], dLogTab[768], dLogMulTab[32], dHz2MixDeltaMul; | 31 | static double dPeriod2HzTab[65536], dLogTab[768], dExp2MulTab[32], dHz2MixDeltaMul; |
| 32 | static uint32_t revMixDeltaTab[65536]; | 32 | static uint32_t revMixDeltaTab[65536]; |
| 33 | static bool bxxOverflow; | 33 | static bool bxxOverflow; |
| 34 | static tonTyp nilPatternLine[MAX_VOICES]; | 34 | static tonTyp nilPatternLine[MAX_VOICES]; |
| @@ -274,9 +274,8 @@ static void calcPeriod2HzTable(void) // called every time "linear/amiga frequenc · 239 unmodified lines |
| 274 | const uint16_t invPeriod = (12 * 192 * 4) - (uint16_t)i; // this intentionally 16-bit-underflows to be accurate to FT2 | 274 | const uint16_t invPeriod = (12 * 192 * 4) - (uint16_t)i; // this intentionally 16-bit-underflows to be accurate to FT2 |
| 275 | const int32_t octave = invPeriod / 768; | 275 | const int32_t octave = invPeriod / 768; |
| 276 | const int32_t period = invPeriod % 768; | 276 | const int32_t period = invPeriod % 768; |
| 277 | const int32_t invOct = (14 - octave) & 0x1F; // accurate to FT2 | | |
| 278 | | 277 | |
| 279 | dPeriod2HzTab[i] = dLogTab[period] * dLogMulTab[invOct]; // x = y / 2^invOct | 278 | dPeriod2HzTab[i] = dLogTab[period] * dExp2MulTab[(14-octave) & 31]; // x = y >> ((14-octave) & 31) |
| 280 | } | 279 | } |
| 281 | } | 280 | } |
| 282 | else | 281 | else |
| @@ -314,10 +313,10 @@ void calcRevMixDeltaTable(void) · 31 unmodified lines |
| 314 | double getSampleC4Rate(sampleTyp *s) | 313 | double getSampleC4Rate(sampleTyp *s) |
| 315 | { | 314 | { |
| 316 | int32_t note = (96/2) + s->relTon; | 315 | int32_t note = (96/2) + s->relTon; |
| 317 | if (note >= (12*10)-1) | 316 | if (note >= (10*12)-1) |
| 318 | return -1; // B-9 (from relTon) = illegal! (won't play in replayer) | 317 | return -1; // B-9 (from relTon) = illegal! (won't play in replayer) |
| 319 | | 318 | |
| 320 | const int32_t C4Period = (note * 16) + (((int8_t)s->fine >> 3) + 16); | 319 | const int32_t C4Period = (note << 4) + (((int8_t)s->fine >> 3) + 16); |
| 321 | | 320 | |
| 322 | const uint16_t period = audio.linearFreqTable ? linearPeriods[C4Period] : amigaPeriods[C4Period]; | 321 | const uint16_t period = audio.linearFreqTable ? linearPeriods[C4Period] : amigaPeriods[C4Period]; |
| 323 | return dPeriod2Hz(period); | 322 | return dPeriod2Hz(period); |
| @@ -430,11 +429,11 @@ void keyOff(stmTyp *ch) · 106 unmodified lines |
| 430 | | 429 | |
| 431 | void calcReplayerLogTab(void) | 430 | void calcReplayerLogTab(void) |
| 432 | { | 431 | { |
| 433 | for (uint32_t i = 0; i < 32; i++) | 432 | for (int32_t i = 0; i < 32; i++) |
| 434 | dLogMulTab[i] = 1.0 / (1UL << i); | 433 | dExp2MulTab[i] = 1.0 / exp2(i); // 1/2^i |
| 435 | | 434 | |
| 436 | for (int32_t i = 0; i < 768; i++) | 435 | for (int32_t i = 0; i < 768; i++) |
| 437 | dLogTab[i] = exp2(i * (1.0 / 768.0)) * (8363.0 * 256.0); | 436 | dLogTab[i] = 8363.0 * 256.0 * exp2(i * (1.0 / 768.0)); |
| 438 | } | 437 | } |
| 439 | | 438 | |
| 440 | void calcReplayerVars(int32_t audioFreq) | 439 | void calcReplayerVars(int32_t audioFreq) |
| @@ -562,7 +561,7 @@ static void startTone(uint8_t ton, uint8_t effTyp, uint8_t eff, stmTyp *ch) · 121 unmodified lines |
| 562 | ch->relTonNr = s->relTon; | 561 | ch->relTonNr = s->relTon; |
| 563 | | 562 | |
| 564 | ton += ch->relTonNr; | 563 | ton += ch->relTonNr; |
| 565 | if (ton >= 12*10) | 564 | if (ton >= 10*12) |
| 566 | return; | 565 | return; |
| 567 | | 566 | |
| 568 | ch->oldVol = s->vol; | 567 | ch->oldVol = s->vol; |
| @@ -598,7 +597,7 @@ static void startTone(uint8_t ton, uint8_t effTyp, uint8_t eff, stmTyp *ch) · 29 unmodified lines |
| 598 | } | 597 | } |
| 599 | } | 598 | } |
| 600 | | 599 | |
| 601 | static void volume(stmTyp *ch, uint8_t param); // actually volume slide | 600 | static void volume(stmTyp *ch, uint8_t param); // volume slide |
| 602 | static void vibrato2(stmTyp *ch); | 601 | static void vibrato2(stmTyp *ch); |
| 603 | static void tonePorta(stmTyp *ch, uint8_t param); | 602 | static void tonePorta(stmTyp *ch, uint8_t param); |
| 604 | | 603 | |
| @@ -632,8 +631,8 @@ static void finePortaDown(stmTyp *ch, uint8_t param) · 27 unmodified lines |
| 632 | ch->fPortaDownSpeed = param; | 631 | ch->fPortaDownSpeed = param; |
| 633 | | 632 | |
| 634 | ch->realPeriod += param << 2; | 633 | ch->realPeriod += param << 2; |
| 635 | if ((int16_t)ch->realPeriod > 32000-1) | 634 | if ((int16_t)ch->realPeriod > MAX_FRQ-1) // FT2 bug, should've been unsigned comparison |
| 636 | ch->realPeriod = 32000-1; | 635 | ch->realPeriod = MAX_FRQ-1; |
| 637 | | 636 | |
| 638 | ch->outPeriod = ch->realPeriod; | 637 | ch->outPeriod = ch->realPeriod; |
| 639 | ch->status |= IS_Period; | 638 | ch->status |= IS_Period; |
| @@ -1181,8 +1180,8 @@ static void xFinePorta(stmTyp *ch, uint8_t param) · 541 unmodified lines |
| 1181 | uint16_t newPeriod = ch->realPeriod; | 1180 | uint16_t newPeriod = ch->realPeriod; |
| 1182 | | 1181 | |
| 1183 | newPeriod += param; | 1182 | newPeriod += param; |
| 1184 | if ((int16_t)newPeriod > 32000-1) | 1183 | if ((int16_t)newPeriod > MAX_FRQ-1) // FT2 bug, should've been unsigned comparison |
| 1185 | newPeriod = 32000-1; | 1184 | newPeriod = MAX_FRQ-1; |
| 1186 | | 1185 | |
| 1187 | ch->outPeriod = ch->realPeriod = newPeriod; | 1186 | ch->outPeriod = ch->realPeriod = newPeriod; |
| 1188 | ch->status |= IS_Period; | 1187 | ch->status |= IS_Period; |
| @@ -1696,7 +1695,7 @@ static void fixaEnvelopeVibrato(stmTyp *ch) · 507 unmodified lines |
| 1696 | uint16_t tmpPeriod = (autoVibVal * (int16_t)autoVibAmp) >> 16; | 1695 | uint16_t tmpPeriod = (autoVibVal * (int16_t)autoVibAmp) >> 16; |
| 1697 | | 1696 | |
| 1698 | tmpPeriod += ch->outPeriod; | 1697 | tmpPeriod += ch->outPeriod; |
| 1699 | if (tmpPeriod > 32000-1) | 1698 | if (tmpPeriod > MAX_FRQ-1) |
| 1700 | tmpPeriod = 0; // yes, FT2 does this (!) | 1699 | tmpPeriod = 0; // yes, FT2 does this (!) |
| 1701 | | 1700 | |
| 1702 | #ifdef HAS_MIDI | 1701 | #ifdef HAS_MIDI |
| @@ -1727,7 +1726,12 @@ static uint16_t relocateTon(uint16_t period, uint8_t arpNote, stmTyp *ch) · 24 unmodified lines |
| 1727 | int32_t tmpPeriod; | 1726 | int32_t tmpPeriod; |
| 1728 | | 1727 | |
| 1729 | const int32_t fineTune = ((int8_t)ch->fineTune >> 3) + 16; | 1728 | const int32_t fineTune = ((int8_t)ch->fineTune >> 3) + 16; |
| 1730 | int32_t hiPeriod = 1536; // FT2 bug: should've been 1935 | 1729 | |
| | 1730 | /* FT2 bug, should've been 10*12*16. Notes above B-7 (95) will have issues. |
| | 1731 | ** You can only achieve such high notes by having a high relative note setting. |
| | 1732 | */ |
| | 1733 | int32_t hiPeriod = 8*12*16; |
| | 1734 | |
| 1731 | int32_t loPeriod = 0; | 1735 | int32_t loPeriod = 0; |
| 1732 | | 1736 | |
| 1733 | for (int32_t i = 0; i < 8; i++) | 1737 | for (int32_t i = 0; i < 8; i++) |
| @@ -1736,7 +1740,7 @@ static uint16_t relocateTon(uint16_t period, uint8_t arpNote, stmTyp *ch) · 2 unmodified lines |
| 1736 | | 1740 | |
| 1737 | int32_t lookUp = tmpPeriod - 8; | 1741 | int32_t lookUp = tmpPeriod - 8; |
| 1738 | if (lookUp < 0) | 1742 | if (lookUp < 0) |
| 1739 | lookUp = 0; // 8bitbubsy: safety fix (C-0 w/ finetune <= -65) | 1743 | lookUp = 0; // safety fix (C-0 w/ finetune <= -65). This buggy read seems to return 0 in FT2 (TODO: Verify...) |
| 1740 | | 1744 | |
| 1741 | if (period >= note2Period[lookUp]) | 1745 | if (period >= note2Period[lookUp]) |
| 1742 | hiPeriod = (tmpPeriod - fineTune) & ~15; | 1746 | hiPeriod = (tmpPeriod - fineTune) & ~15; |
| @@ -1745,8 +1749,8 @@ static uint16_t relocateTon(uint16_t period, uint8_t arpNote, stmTyp *ch) · 2 unmodified lines |
| 1745 | } | 1749 | } |
| 1746 | | 1750 | |
| 1747 | tmpPeriod = loPeriod + fineTune + (arpNote << 4); | 1751 | tmpPeriod = loPeriod + fineTune + (arpNote << 4); |
| 1748 | if (tmpPeriod >= 1550) // FT2 bugs: off-by-one edge case, and should've been 1935 (1936) | 1752 | if (tmpPeriod >= (8*12*16+15)-1) // FT2 bug, should've been 10*12*16+16 (also notice the +2 difference) |
| 1749 | tmpPeriod = 1551; | 1753 | tmpPeriod = (8*12*16+16)-1; |
| 1750 | | 1754 | |
| 1751 | return note2Period[tmpPeriod]; | 1755 | return note2Period[tmpPeriod]; |
| 1752 | } | 1756 | } |
| @@ -1829,8 +1833,8 @@ static void portaDown(stmTyp *ch, uint8_t param) · 76 unmodified lines |
| 1829 | ch->portaDownSpeed = param; | 1833 | ch->portaDownSpeed = param; |
| 1830 | | 1834 | |
| 1831 | ch->realPeriod += param << 2; | 1835 | ch->realPeriod += param << 2; |
| 1832 | if ((int16_t)ch->realPeriod > 32000-1) // FT2 bug, should've been unsigned comparison | 1836 | if ((int16_t)ch->realPeriod > MAX_FRQ-1) // FT2 bug, should've been unsigned comparison |
| 1833 | ch->realPeriod = 32000-1; | 1837 | ch->realPeriod = MAX_FRQ-1; |
| 1834 | | 1838 | |
| 1835 | ch->outPeriod = ch->realPeriod; | 1839 | ch->outPeriod = ch->realPeriod; |
| 1836 | ch->status |= IS_Period; | 1840 | ch->status |= IS_Period; |
| @@ -1959,7 +1963,7 @@ static void tremolo(stmTyp *ch, uint8_t param) · 122 unmodified lines |
| 1959 | ch->tremPos += ch->tremSpeed; | 1963 | ch->tremPos += ch->tremSpeed; |
| 1960 | } | 1964 | } |
| 1961 | | 1965 | |
| 1962 | static void volume(stmTyp *ch, uint8_t param) // actually volume slide | 1966 | static void volume(stmTyp *ch, uint8_t param) // volume slide |
| 1963 | { | 1967 | { |
| 1964 | if (param == 0) | 1968 | if (param == 0) |
| 1965 | param = ch->volSlideSpeed; | 1969 | param = ch->volSlideSpeed; |