History

tuneSample() fix for Amiga periods

Olav Sørensen committed 5 years ago

Commit 2c1dbb21 parent 64789ba2 files · +38 −19Browse files

Unified · Split

2 files
  1. src/ft2_replayer.c +33 −18
  2. src/ft2_replayer.h +5 −1
src/ft2_replayer.c+33−18
@@ -130,7 +130,9 @@ void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag) · 129 unmodified lines
130130 #define MIN_PERIOD (0)
131131 #define MAX_PERIOD (((10*12*16)-1)-1) /* -1 (because of bugged amigaPeriods table values) */
132132
133+ double (*dGetHzFromPeriod)(int32_t) = linearPeriodsFlag ? &linearPeriod2Hz : &amigaPeriod2Hz;
133134 const uint16_t *periodTab = linearPeriodsFlag ? linearPeriods : amigaPeriods;
135+
134136 if (midCFreq <= 0 || periodTab == NULL)
135137 {
136138 s->fine = s->relTon = 0;
@@ -139,14 +141,14 @@ void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag) · 2 unmodified lines
139141
140142 // handle frequency boundaries first...
141143
142− if (midCFreq <= (int32_t)dPeriod2HzTab[periodTab[MIN_PERIOD]])
144+ if (midCFreq <= (int32_t)dGetHzFromPeriod(periodTab[MIN_PERIOD]))
143145 {
144146 s->fine = -128;
145147 s->relTon = -48;
146148 return;
147149 }
148150
149− if (midCFreq >= (int32_t)dPeriod2HzTab[periodTab[MAX_PERIOD]])
151+ if (midCFreq >= (int32_t)dGetHzFromPeriod(periodTab[MAX_PERIOD]))
150152 {
151153 s->fine = 127;
152154 s->relTon = 71;
@@ -154,9 +156,10 @@ void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag) · 1 unmodified line
154156 }
155157
156158 // check if midCFreq is matching any of the non-finetuned note frequencies (C-0..B-9)
159+
157160 for (int8_t i = 0; i < 10*12; i++)
158161 {
159− if (midCFreq == (int32_t)dPeriod2HzTab[periodTab[16 + (i<<4)]])
162+ if (midCFreq == (int32_t)dGetHzFromPeriod(periodTab[16 + (i<<4)]))
160163 {
161164 s->fine = 0;
162165 s->relTon = i - NOTE_C4;
@@ -169,13 +172,13 @@ void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag) · 6 unmodified lines
169172 int32_t period = MAX_PERIOD;
170173 for (; period >= MIN_PERIOD; period--)
171174 {
172− const int32_t curr = (int32_t)dPeriod2HzTab[periodTab[period]];
175+ const int32_t curr = (int32_t)dGetHzFromPeriod(periodTab[period]);
173176 if (midCFreq == curr)
174177 break;
175178
176179 if (midCFreq > curr)
177180 {
178− const int32_t next = (int32_t)dPeriod2HzTab[periodTab[period+1]];
181+ const int32_t next = (int32_t)dGetHzFromPeriod(periodTab[period+1]);
179182 const int32_t errorCurr = ABS(curr-midCFreq);
180183 const int32_t errorNext = ABS(next-midCFreq);
181184
@@ -257,27 +260,39 @@ int16_t getRealUsedSamples(int16_t nr) · 75 unmodified lines
257260 return i+1;
258261 }
259262
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)
261276 {
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
263279
280+ return (double)(8363*1712) / period;
281+}
282+
283+static void calcPeriod2HzTable(void) // called every time "linear/amiga frequency" mode is changed
284+{
264285 if (audio.linearPeriodsFlag)
265286 {
266287 // linear periods
267− for (int32_t i = 1; i < 65536; i++)
268− {
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− }
288+ for (int32_t i = 0; i < 65536; i++)
289+ dPeriod2HzTab[i] = linearPeriod2Hz(i);
275290 }
276291 else
277292 {
278293 // Amiga periods
279− for (int32_t i = 1; i < 65536; i++)
280− dPeriod2HzTab[i] = (8363.0 * 1712.0) / i;
294+ for (int32_t i = 0; i < 65536; i++)
295+ dPeriod2HzTab[i] = amigaPeriod2Hz(i);
281296 }
282297 }
283298
@@ -466,7 +481,7 @@ void calcReplayerVars(int32_t audioFreq) · 182 unmodified lines
466481 }
467482 }
468483
469−double dPeriod2Hz(uint16_t period)
484+double dPeriod2Hz(uint16_t period) // uses LUT for fast operation
470485 {
471486 return dPeriod2HzTab[period];
472487 }
src/ft2_replayer.h+5−1
@@ -265,7 +265,11 @@ void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag); · 264 unmodified lines
265265
266266 void calcRevMixDeltaTable(void);
267267 void calcReplayerLogTab(void);
268−double dPeriod2Hz(uint16_t period);
268+
269+double linearPeriod2Hz(int32_t period);
270+double amigaPeriod2Hz(int32_t period);
271+
272+double dPeriod2Hz(uint16_t period); // uses LUT for fast operation
269273
270274 int64_t getMixerDelta(uint16_t period);
271275 uint32_t getRevMixerDelta(uint16_t period);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t