| @@ -130,7 +130,9 @@ void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag) · 129 unmodified lines |
| 130 | #define MIN_PERIOD (0) | 130 | #define MIN_PERIOD (0) |
| 131 | #define MAX_PERIOD (((10*12*16)-1)-1) /* -1 (because of bugged amigaPeriods table values) */ | 131 | #define MAX_PERIOD (((10*12*16)-1)-1) /* -1 (because of bugged amigaPeriods table values) */ |
| 132 | | 132 | |
| | 133 | double (*dGetHzFromPeriod)(int32_t) = linearPeriodsFlag ? &linearPeriod2Hz : &amigaPeriod2Hz; |
| 133 | const uint16_t *periodTab = linearPeriodsFlag ? linearPeriods : amigaPeriods; | 134 | const uint16_t *periodTab = linearPeriodsFlag ? linearPeriods : amigaPeriods; |
| | 135 | |
| 134 | if (midCFreq <= 0 || periodTab == NULL) | 136 | if (midCFreq <= 0 || periodTab == NULL) |
| 135 | { | 137 | { |
| 136 | s->fine = s->relTon = 0; | 138 | s->fine = s->relTon = 0; |
| @@ -139,14 +141,14 @@ void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag) · 2 unmodified lines |
| 139 | | 141 | |
| 140 | // handle frequency boundaries first... | 142 | // handle frequency boundaries first... |
| 141 | | 143 | |
| 142 | if (midCFreq <= (int32_t)dPeriod2HzTab[periodTab[MIN_PERIOD]]) | 144 | if (midCFreq <= (int32_t)dGetHzFromPeriod(periodTab[MIN_PERIOD])) |
| 143 | { | 145 | { |
| 144 | s->fine = -128; | 146 | s->fine = -128; |
| 145 | s->relTon = -48; | 147 | s->relTon = -48; |
| 146 | return; | 148 | return; |
| 147 | } | 149 | } |
| 148 | | 150 | |
| 149 | if (midCFreq >= (int32_t)dPeriod2HzTab[periodTab[MAX_PERIOD]]) | 151 | if (midCFreq >= (int32_t)dGetHzFromPeriod(periodTab[MAX_PERIOD])) |
| 150 | { | 152 | { |
| 151 | s->fine = 127; | 153 | s->fine = 127; |
| 152 | s->relTon = 71; | 154 | s->relTon = 71; |
| @@ -154,9 +156,10 @@ void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag) · 1 unmodified line |
| 154 | } | 156 | } |
| 155 | | 157 | |
| 156 | // check if midCFreq is matching any of the non-finetuned note frequencies (C-0..B-9) | 158 | // check if midCFreq is matching any of the non-finetuned note frequencies (C-0..B-9) |
| | 159 | |
| 157 | for (int8_t i = 0; i < 10*12; i++) | 160 | for (int8_t i = 0; i < 10*12; i++) |
| 158 | { | 161 | { |
| 159 | if (midCFreq == (int32_t)dPeriod2HzTab[periodTab[16 + (i<<4)]]) | 162 | if (midCFreq == (int32_t)dGetHzFromPeriod(periodTab[16 + (i<<4)])) |
| 160 | { | 163 | { |
| 161 | s->fine = 0; | 164 | s->fine = 0; |
| 162 | s->relTon = i - NOTE_C4; | 165 | s->relTon = i - NOTE_C4; |
| @@ -169,13 +172,13 @@ void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag) · 6 unmodified lines |
| 169 | int32_t period = MAX_PERIOD; | 172 | int32_t period = MAX_PERIOD; |
| 170 | for (; period >= MIN_PERIOD; period--) | 173 | for (; period >= MIN_PERIOD; period--) |
| 171 | { | 174 | { |
| 172 | const int32_t curr = (int32_t)dPeriod2HzTab[periodTab[period]]; | 175 | const int32_t curr = (int32_t)dGetHzFromPeriod(periodTab[period]); |
| 173 | if (midCFreq == curr) | 176 | if (midCFreq == curr) |
| 174 | break; | 177 | break; |
| 175 | | 178 | |
| 176 | if (midCFreq > curr) | 179 | if (midCFreq > curr) |
| 177 | { | 180 | { |
| 178 | const int32_t next = (int32_t)dPeriod2HzTab[periodTab[period+1]]; | 181 | const int32_t next = (int32_t)dGetHzFromPeriod(periodTab[period+1]); |
| 179 | const int32_t errorCurr = ABS(curr-midCFreq); | 182 | const int32_t errorCurr = ABS(curr-midCFreq); |
| 180 | const int32_t errorNext = ABS(next-midCFreq); | 183 | const int32_t errorNext = ABS(next-midCFreq); |
| 181 | | 184 | |
| @@ -257,27 +260,39 @@ int16_t getRealUsedSamples(int16_t nr) · 75 unmodified lines |
| 257 | return i+1; | 260 | return i+1; |
| 258 | } | 261 | } |
| 259 | | 262 | |
| 260 | static void calcPeriod2HzTable(void) // called every time "linear/amiga frequency" mode is changed | 263 | double linearPeriod2Hz(int32_t period) |
| | 264 | { |
| | 265 | if (period == 0) |
| | 266 | return 0.0; // in FT2, a period of 0 gives 0Hz |
| | 267 | |
| | 268 | const uint16_t invPeriod = (uint16_t)(12 * 192 * 4) - (uint16_t)period; // this intentionally 16-bit-underflows to be accurate to FT2 |
| | 269 | const int32_t quotient = invPeriod / 768; |
| | 270 | const int32_t remainder = invPeriod % 768; |
| | 271 | |
| | 272 | return dLogTab[remainder] * dExp2MulTab[(14-quotient) & 31]; // x = y >> ((14-octave) & 31) |
| | 273 | } |
| | 274 | |
| | 275 | double amigaPeriod2Hz(int32_t period) |
| 261 | { | 276 | { |
| 262 | dPeriod2HzTab[0] = 0.0; // in FT2, a period of 0 converts to 0Hz | 277 | if (period == 0) |
| | 278 | return 0.0; // in FT2, a period of 0 gives 0Hz |
| 263 | | 279 | |
| | 280 | return (double)(8363*1712) / period; |
| | 281 | } |
| | 282 | |
| | 283 | static void calcPeriod2HzTable(void) // called every time "linear/amiga frequency" mode is changed |
| | 284 | { |
| 264 | if (audio.linearPeriodsFlag) | 285 | if (audio.linearPeriodsFlag) |
| 265 | { | 286 | { |
| 266 | // linear periods | 287 | // linear periods |
| 267 | for (int32_t i = 1; i < 65536; i++) | 288 | for (int32_t i = 0; i < 65536; i++) |
| 268 | { | 289 | dPeriod2HzTab[i] = linearPeriod2Hz(i); |
| 269 | const uint16_t invPeriod = (12 * 192 * 4) - (uint16_t)i; // this intentionally 16-bit-underflows to be accurate to FT2 | | |
| 270 | const int32_t octave = invPeriod / 768; | | |
| 271 | const int32_t period = invPeriod % 768; | | |
| 272 | | | |
| 273 | dPeriod2HzTab[i] = dLogTab[period] * dExp2MulTab[(14-octave) & 31]; // x = y >> ((14-octave) & 31) | | |
| 274 | } | | |
| 275 | } | 290 | } |
| 276 | else | 291 | else |
| 277 | { | 292 | { |
| 278 | // Amiga periods | 293 | // Amiga periods |
| 279 | for (int32_t i = 1; i < 65536; i++) | 294 | for (int32_t i = 0; i < 65536; i++) |
| 280 | dPeriod2HzTab[i] = (8363.0 * 1712.0) / i; | 295 | dPeriod2HzTab[i] = amigaPeriod2Hz(i); |
| 281 | } | 296 | } |
| 282 | } | 297 | } |
| 283 | | 298 | |
| @@ -466,7 +481,7 @@ void calcReplayerVars(int32_t audioFreq) · 182 unmodified lines |
| 466 | } | 481 | } |
| 467 | } | 482 | } |
| 468 | | 483 | |
| 469 | double dPeriod2Hz(uint16_t period) | 484 | double dPeriod2Hz(uint16_t period) // uses LUT for fast operation |
| 470 | { | 485 | { |
| 471 | return dPeriod2HzTab[period]; | 486 | return dPeriod2HzTab[period]; |
| 472 | } | 487 | } |