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
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
260static void calcPeriod2HzTable(void) // called every time "linear/amiga frequency" mode is changed263double 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
275double amigaPeriod2Hz(int32_t period)
261{276{
262 dPeriod2HzTab[0] = 0.0; // in FT2, a period of 0 converts to 0Hz277 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
283static 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 periods287 // 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 else291 else
277 {292 {
278 // Amiga periods293 // 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
469double dPeriod2Hz(uint16_t period)484double dPeriod2Hz(uint16_t period) // uses LUT for fast operation
470{485{
471 return dPeriod2HzTab[period];486 return dPeriod2HzTab[period];
472}487}
src/ft2_replayer.h+5−1
@@ -265,7 +265,11 @@ void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag); · 264 unmodified lines
265 265
266void calcRevMixDeltaTable(void);266void calcRevMixDeltaTable(void);
267void calcReplayerLogTab(void);267void calcReplayerLogTab(void);
268double dPeriod2Hz(uint16_t period);268
269double linearPeriod2Hz(int32_t period);
270double amigaPeriod2Hz(int32_t period);
271
272double dPeriod2Hz(uint16_t period); // uses LUT for fast operation
269 273
270int64_t getMixerDelta(uint16_t period);274int64_t getMixerDelta(uint16_t period);
271uint32_t getRevMixerDelta(uint16_t period);275uint32_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