Skip to content

Commit 813029d

Browse files
committed
Some different tweaks
1 parent 82e421b commit 813029d

14 files changed

+276
-265
lines changed

src/ft2_audio.c

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
static int32_t smpShiftValue;
2929
static uint32_t oldAudioFreq, tickTimeLenInt, randSeed = INITIAL_DITHER_SEED;
3030
static uint64_t tickTimeLenFrac;
31-
static float fSqrtPanningTable[256+1];
32-
static double dAudioNormalizeMul, dPrngStateL, dPrngStateR;
31+
static float fSqrtPanningTable[256+1], fAudioNormalizeMul, fPrngStateL, fPrngStateR;
3332
static voice_t voice[MAX_CHANNELS * 2];
3433

3534
// globalized
@@ -103,11 +102,11 @@ void setAudioAmp(int16_t amp, int16_t masterVol, bool bitDepth32Flag)
103102
amp = CLAMP(amp, 1, 32);
104103
masterVol = CLAMP(masterVol, 0, 256);
105104

106-
double dAmp = (amp * masterVol) / (32.0 * 256.0);
105+
float fAmp = (amp * masterVol) / (32.0f * 256.0f);
107106
if (!bitDepth32Flag)
108-
dAmp *= 32768.0;
107+
fAmp *= 32768.0f;
109108

110-
dAudioNormalizeMul = dAmp;
109+
fAudioNormalizeMul = fAmp;
111110
}
112111

113112
void decreaseMasterVol(void)
@@ -194,17 +193,15 @@ void audioSetInterpolationType(uint8_t interpolationType)
194193
// set sinc LUT pointers
195194
if (config.interpolation == INTERPOLATION_SINC8)
196195
{
197-
fSinc_1 = fSinc8_1;
198-
fSinc_2 = fSinc8_2;
199-
fSinc_3 = fSinc8_3;
196+
for (int32_t i = 0; i < SINC_KERNELS; i++)
197+
fSinc[i] = fSinc8[i];
200198

201199
audio.sincInterpolation = true;
202200
}
203201
else if (config.interpolation == INTERPOLATION_SINC16)
204202
{
205-
fSinc_1 = fSinc16_1;
206-
fSinc_2 = fSinc16_2;
207-
fSinc_3 = fSinc16_3;
203+
for (int32_t i = 0; i < SINC_KERNELS; i++)
204+
fSinc[i] = fSinc16[i];
208205

209206
audio.sincInterpolation = true;
210207
}
@@ -381,19 +378,16 @@ void updateVoices(void)
381378

382379
if (status & CF_UPDATE_PERIOD)
383380
{
384-
const double dVoiceHz = dPeriod2Hz(ch->finalPeriod);
381+
v->delta = period2VoiceDelta(ch->finalPeriod);
385382

386-
// set voice delta
387-
v->delta = (int64_t)((dVoiceHz * audio.dHz2MixDeltaMul) + 0.5); // Hz -> fixed-point delta (rounded)
388383
if (audio.sincInterpolation)
389384
{
390-
// decide which sinc LUT to use according to the resampling ratio
391385
if (v->delta <= sincRatio1)
392-
v->fSincLUT = fSinc_1;
386+
v->fSincLUT = fSinc[0];
393387
else if (v->delta <= sincRatio2)
394-
v->fSincLUT = fSinc_2;
388+
v->fSincLUT = fSinc[1];
395389
else
396-
v->fSincLUT = fSinc_3;
390+
v->fSincLUT = fSinc[2];
397391
}
398392
}
399393

@@ -405,7 +399,7 @@ void updateVoices(void)
405399
void resetAudioDither(void)
406400
{
407401
randSeed = INITIAL_DITHER_SEED;
408-
dPrngStateL = dPrngStateR = 0.0;
402+
fPrngStateL = fPrngStateR = 0.0f;
409403
}
410404

411405
static inline int32_t random32(void)
@@ -420,26 +414,26 @@ static inline int32_t random32(void)
420414
static void sendSamples16BitStereo(void *stream, uint32_t sampleBlockLength)
421415
{
422416
int32_t out32;
423-
double dOut, dPrng;
417+
float fOut, fPrng;
424418

425419
int16_t *streamPtr16 = (int16_t *)stream;
426420
for (uint32_t i = 0; i < sampleBlockLength; i++)
427421
{
428422
// left channel - 1-bit triangular dithering
429-
dPrng = random32() * (1.0 / (UINT32_MAX+1.0)); // -0.5 .. 0.5
430-
dOut = (double)audio.fMixBufferL[i] * dAudioNormalizeMul;
431-
dOut = (dOut + dPrng) - dPrngStateL;
432-
dPrngStateL = dPrng;
433-
out32 = (int32_t)dOut;
423+
fPrng = (float)random32() * (1.0f / (UINT32_MAX+1.0f)); // -0.5f .. 0.5f
424+
fOut = audio.fMixBufferL[i] * fAudioNormalizeMul;
425+
fOut = (fOut + fPrng) - fPrngStateL;
426+
fPrngStateL = fPrng;
427+
out32 = (int32_t)fOut;
434428
CLAMP16(out32);
435429
*streamPtr16++ = (int16_t)out32;
436430

437431
// right channel - 1-bit triangular dithering
438-
dPrng = random32() * (1.0 / (UINT32_MAX+1.0)); // -0.5 .. 0.5
439-
dOut = (double)audio.fMixBufferR[i] * dAudioNormalizeMul;
440-
dOut = (dOut + dPrng) - dPrngStateR;
441-
dPrngStateR = dPrng;
442-
out32 = (int32_t)dOut;
432+
fPrng = (float)random32() * (1.0f / (UINT32_MAX+1.0f)); // -0.5f .. 0.5f
433+
fOut = audio.fMixBufferR[i] * fAudioNormalizeMul;
434+
fOut = (fOut + fPrng) - fPrngStateR;
435+
fPrngStateR = fPrng;
436+
out32 = (int32_t)fOut;
443437
CLAMP16(out32);
444438
*streamPtr16++ = (int16_t)out32;
445439

@@ -450,20 +444,20 @@ static void sendSamples16BitStereo(void *stream, uint32_t sampleBlockLength)
450444

451445
static void sendSamples32BitFloatStereo(void *stream, uint32_t sampleBlockLength)
452446
{
453-
double dOut;
447+
float fOut;
454448

455449
float *fStreamPtr32 = (float *)stream;
456450
for (uint32_t i = 0; i < sampleBlockLength; i++)
457451
{
458452
// left channel
459-
dOut = (double)audio.fMixBufferL[i] * dAudioNormalizeMul;
460-
dOut = CLAMP(dOut, -1.0, 1.0);
461-
*fStreamPtr32++ = (float)dOut;
453+
fOut = audio.fMixBufferL[i] * fAudioNormalizeMul;
454+
fOut = CLAMP(fOut, -1.0f, 1.0f);
455+
*fStreamPtr32++ = fOut;
462456

463457
// right channel
464-
dOut = (double)audio.fMixBufferR[i] * dAudioNormalizeMul;
465-
dOut = CLAMP(dOut, -1.0, 1.0);
466-
*fStreamPtr32++ = (float)dOut;
458+
fOut = audio.fMixBufferR[i] * fAudioNormalizeMul;
459+
fOut = CLAMP(fOut, -1.0f, 1.0f);
460+
*fStreamPtr32++ = fOut;
467461

468462
// clear what we read from the mixing buffer
469463
audio.fMixBufferL[i] = audio.fMixBufferR[i] = 0.0f;

src/ft2_audio.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ typedef struct audio_t
5050
uint64_t tickTime64, tickTime64Frac;
5151

5252
float *fMixBufferL, *fMixBufferR, fQuickVolRampSamplesMul, fSamplesPerTickIntMul;
53-
double dHz2MixDeltaMul;
5453

5554
SDL_AudioDeviceID dev;
5655
uint32_t wantFreq, haveFreq, wantSamples, haveSamples;

src/ft2_main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,8 @@ static void initializeVars(void)
278278
memset(&chSync, 0, sizeof (chSync));
279279
memset(&song, 0, sizeof (song));
280280

281+
calcMiscReplayerVars();
282+
281283
// used for scopes and sampling position line (sampler screen)
282284
for (int32_t i = 0; i < MAX_CHANNELS; i++)
283285
{
@@ -317,7 +319,6 @@ static void initializeVars(void)
317319
editor.diskOpReadOnOpen = true;
318320

319321
audio.linearPeriodsFlag = true;
320-
calcReplayerLogTab();
321322

322323
#ifdef HAS_MIDI
323324
midi.enable = true;

src/ft2_replayer.c

Lines changed: 92 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include "mixer/ft2_cubic_spline.h"
3131
#include "mixer/ft2_windowed_sinc.h"
3232

33+
static uint64_t logTab[4*12*16], scopeLogTab[4*12*16], scopeDrawLogTab[4*12*16];
34+
static uint64_t amigaPeriodDiv, scopeAmigaPeriodDiv, scopeDrawAmigaPeriodDiv;
3335
static double dLogTab[4*12*16], dExp2MulTab[32];
3436
static bool bxxOverflow;
3537
static note_t nilPatternLine[MAX_CHANNELS];
@@ -232,34 +234,92 @@ int16_t getRealUsedSamples(int16_t smpNum)
232234
return i+1;
233235
}
234236

235-
double dLinearPeriod2Hz(int32_t period)
237+
double dPeriod2Hz(uint32_t period)
236238
{
237239
period &= 0xFFFF; // just in case (actual period range is 0..65535)
238240

239241
if (period == 0)
240242
return 0.0; // in FT2, a period of 0 results in 0Hz
241243

242-
const uint32_t invPeriod = ((12 * 192 * 4) - period) & 0xFFFF; // mask needed for FT2 period overflow quirk
244+
if (audio.linearPeriodsFlag)
245+
{
246+
const uint32_t invPeriod = ((12 * 192 * 4) - period) & 0xFFFF; // mask needed for FT2 period overflow quirk
243247

244-
const uint32_t quotient = invPeriod / (12 * 16 * 4);
245-
const uint32_t remainder = invPeriod % (12 * 16 * 4);
248+
const uint32_t quotient = invPeriod / (12 * 16 * 4);
249+
const uint32_t remainder = invPeriod % (12 * 16 * 4);
246250

247-
return dLogTab[remainder] * dExp2MulTab[(14-quotient) & 31]; // x = y >> ((14-quotient) & 31);
251+
return dLogTab[remainder] * dExp2MulTab[(14-quotient) & 31]; // x = y >> ((14-quotient) & 31);
252+
}
253+
else
254+
{
255+
return (8363.0 * 1712.0) / (int32_t)period;
256+
}
248257
}
249258

250-
double dAmigaPeriod2Hz(int32_t period)
259+
uint64_t period2VoiceDelta(uint32_t period)
251260
{
252261
period &= 0xFFFF; // just in case (actual period range is 0..65535)
253262

254263
if (period == 0)
255-
return 0.0; // in FT2, a period of 0 results in 0Hz
264+
return 0; // in FT2, a period of 0 results in 0Hz
265+
266+
if (audio.linearPeriodsFlag)
267+
{
268+
const uint32_t invPeriod = ((12 * 192 * 4) - period) & 0xFFFF; // mask needed for FT2 period overflow quirk
269+
270+
const uint32_t quotient = invPeriod / (12 * 16 * 4);
271+
const uint32_t remainder = invPeriod % (12 * 16 * 4);
272+
273+
return logTab[remainder] >> ((14-quotient) & 31);
274+
}
275+
else
276+
{
277+
return amigaPeriodDiv / period;
278+
}
279+
}
280+
281+
uint64_t period2ScopeDelta(uint32_t period)
282+
{
283+
period &= 0xFFFF; // just in case (actual period range is 0..65535)
284+
285+
if (period == 0)
286+
return 0; // in FT2, a period of 0 results in 0Hz
287+
288+
if (audio.linearPeriodsFlag)
289+
{
290+
const uint32_t invPeriod = ((12 * 192 * 4) - period) & 0xFFFF; // mask needed for FT2 period overflow quirk
291+
292+
const uint32_t quotient = invPeriod / (12 * 16 * 4);
293+
const uint32_t remainder = invPeriod % (12 * 16 * 4);
256294

257-
return (8363.0 * 1712.0) / period;
295+
return scopeLogTab[remainder] >> ((14-quotient) & 31);
296+
}
297+
else
298+
{
299+
return scopeAmigaPeriodDiv / period;
300+
}
258301
}
259302

260-
double dPeriod2Hz(int32_t period)
303+
uint64_t period2ScopeDrawDelta(uint32_t period)
261304
{
262-
return audio.linearPeriodsFlag ? dLinearPeriod2Hz(period) : dAmigaPeriod2Hz(period);
305+
period &= 0xFFFF; // just in case (actual period range is 0..65535)
306+
307+
if (period == 0)
308+
return 0; // in FT2, a period of 0 results in 0Hz
309+
310+
if (audio.linearPeriodsFlag)
311+
{
312+
const uint32_t invPeriod = ((12 * 192 * 4) - period) & 0xFFFF; // mask needed for FT2 period overflow quirk
313+
314+
const uint32_t quotient = invPeriod / (12 * 16 * 4);
315+
const uint32_t remainder = invPeriod % (12 * 16 * 4);
316+
317+
return scopeDrawLogTab[remainder] >> ((14-quotient) & 31);
318+
}
319+
else
320+
{
321+
return scopeDrawAmigaPeriodDiv / period;
322+
}
263323
}
264324

265325
// returns *exact* FT2 C-4 voice rate (depending on finetune, relativeNote and linear/Amiga period mode)
@@ -386,22 +446,18 @@ void keyOff(channel_t *ch)
386446
}
387447
}
388448

389-
void calcReplayerLogTab(void) // for linear period -> hz calculation
390-
{
391-
for (int32_t i = 0; i < 32; i++)
392-
dExp2MulTab[i] = 1.0 / exp2(i); // 1/(2^i)
393-
394-
for (int32_t i = 0; i < 4*12*16; i++)
395-
dLogTab[i] = (8363.0 * 256.0) * exp2(i / (4.0 * 12.0 * 16.0));
396-
}
397-
398449
void calcReplayerVars(int32_t audioFreq)
399450
{
400451
assert(audioFreq > 0);
401452
if (audioFreq <= 0)
402453
return;
403454

404-
audio.dHz2MixDeltaMul = (double)MIXER_FRAC_SCALE / audioFreq;
455+
const double logTabMul = (UINT32_MAX+1.0) / audioFreq;
456+
for (int32_t i = 0; i < 4*12*16; i++)
457+
logTab[i] = (uint64_t)round(dLogTab[i] * logTabMul);
458+
459+
amigaPeriodDiv = (uint64_t)round((MIXER_FRAC_SCALE * (1712.0*8363.0)) / audioFreq);
460+
405461
audio.quickVolRampSamples = (uint32_t)round(audioFreq / (1000.0 / FT2_QUICK_VOLRAMP_MILLISECONDS));
406462
audio.fQuickVolRampSamplesMul = (float)(1.0 / audio.quickVolRampSamples);
407463

@@ -2807,6 +2863,22 @@ void closeReplayer(void)
28072863
freeWindowedSincTables();
28082864
}
28092865

2866+
void calcMiscReplayerVars(void)
2867+
{
2868+
for (int32_t i = 0; i < 32; i++)
2869+
dExp2MulTab[i] = 1.0 / exp2(i); // 1/(2^i)
2870+
2871+
for (int32_t i = 0; i < 4*12*16; i++)
2872+
{
2873+
dLogTab[i] = (8363.0 * 256.0) * exp2(i / (4.0 * 12.0 * 16.0));
2874+
scopeLogTab[i] = (uint64_t)round(dLogTab[i] * (SCOPE_FRAC_SCALE / SCOPE_HZ));
2875+
scopeDrawLogTab[i] = (uint64_t)round(dLogTab[i] * (SCOPE_FRAC_SCALE / (C4_FREQ/2.0)));
2876+
}
2877+
2878+
scopeAmigaPeriodDiv = (uint64_t)round((SCOPE_FRAC_SCALE * (1712.0*8363.0)) / SCOPE_HZ);
2879+
scopeDrawAmigaPeriodDiv = (uint64_t)round((SCOPE_FRAC_SCALE * (1712.0*8363.0)) / (C4_FREQ/2.0));
2880+
}
2881+
28102882
bool setupReplayer(void)
28112883
{
28122884
for (int32_t i = 0; i < MAX_PATTERNS; i++)

src/ft2_replayer.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,11 @@ void fixInstrAndSampleNames(int16_t insNum);
288288

289289
void calcReplayerVars(int32_t rate);
290290
void setSampleC4Hz(sample_t *s, double dC4Hz);
291-
void calcReplayerLogTab(void); // for linear period -> hz calculation
292291

293-
double dLinearPeriod2Hz(int32_t period);
294-
double dAmigaPeriod2Hz(int32_t period);
295-
double dPeriod2Hz(int32_t period);
292+
double dPeriod2Hz(uint32_t period);
293+
uint64_t period2VoiceDelta(uint32_t period);
294+
uint64_t period2ScopeDelta(uint32_t period);
295+
uint64_t period2ScopeDrawDelta(uint32_t period);
296296

297297
int32_t getPianoKey(int32_t period, int8_t finetune, int8_t relativeNote); // for piano in Instr. Ed.
298298
void triggerNote(uint8_t note, uint8_t efx, uint8_t efxData, channel_t *ch);
@@ -305,6 +305,7 @@ void freeSample(int16_t insNum, int16_t smpNum);
305305

306306
void freeAllPatterns(void);
307307
void updateChanNums(void);
308+
void calcMiscReplayerVars(void);
308309
bool setupReplayer(void);
309310
void closeReplayer(void);
310311
void resetMusic(void);

0 commit comments

Comments
 (0)