shithub: ft²

Download patch

ref: 64789ba9ad662eab1a1c7a4def30a618d8f9417d
parent: f5334d8324dae71325c59b559ab8fcceb8695fd8
author: Olav Sørensen <olav.sorensen@live.no>
date: Fri Feb 26 08:52:40 EST 2021

tuneSample() didn't use the correct period table under all circumstances

This was not a huge problem, as the tuning would only be very slightly off.

--- a/src/ft2_audio.h
+++ b/src/ft2_audio.h
@@ -28,7 +28,7 @@
 	char *currInputDevice, *currOutputDevice, *lastWorkingAudioDeviceName;
 	char *inputDeviceNames[MAX_AUDIO_DEVICES], *outputDeviceNames[MAX_AUDIO_DEVICES];
 	volatile bool locked, resetSyncTickTimeFlag, volumeRampingFlag;
-	bool linearFreqTable, rescanAudioDevicesSupported;
+	bool linearPeriodsFlag, rescanAudioDevicesSupported;
 	volatile uint8_t interpolationType;
 	int32_t quickVolRampSamples, inputDeviceNum, outputDeviceNum, lastWorkingAudioFreq, lastWorkingAudioBits;
 	uint32_t freq, audLatencyPerfValInt, audLatencyPerfValFrac, samplesPerTick, musicTimeSpeedVal;
--- a/src/ft2_config.c
+++ b/src/ft2_config.c
@@ -844,7 +844,7 @@
 
 	// FREQUENCY TABLE
 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_FREQ_TABLE);
-	tmpID = audio.linearFreqTable ? RB_CONFIG_FREQ_LINEAR : RB_CONFIG_FREQ_AMIGA;
+	tmpID = audio.linearPeriodsFlag ? RB_CONFIG_FREQ_LINEAR : RB_CONFIG_FREQ_AMIGA;
 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
 
 	// show result
--- a/src/ft2_inst_ed.c
+++ b/src/ft2_inst_ed.c
@@ -3372,7 +3372,7 @@
 
 				const double dFreq = (1.0 + (ih_PATWave.fineTune / 512.0)) * ih_PATWave.sampleRate;
 				int32_t freq = (const int32_t)(dFreq + 0.5);
-				tuneSample(s, freq);
+				tuneSample(s, freq, audio.linearPeriodsFlag);
 
 				a = s->relTon - (getPATNote(ih_PATWave.rootFrq) - (12 * 3));
 				s->relTon = (uint8_t)CLAMP(a, -48, 71);
--- a/src/ft2_main.c
+++ b/src/ft2_main.c
@@ -312,7 +312,7 @@
 	editor.diskOpReadOnOpen = true;
 	editor.programRunning = true;
 
-	audio.linearFreqTable = true;
+	audio.linearPeriodsFlag = true;
 
 	calcReplayerLogTab();
 }
--- a/src/ft2_module_loader.c
+++ b/src/ft2_module_loader.c
@@ -929,7 +929,7 @@
 			s->pek = s->origPek + SMP_DAT_OFFSET;
 
 			s->len = h_STM.instr[i].len;
-			tuneSample(s, h_STM.instr[i].rate);
+			tuneSample(s, h_STM.instr[i].rate, false);
 			s->vol = h_STM.instr[i].vol;
 			s->repS = h_STM.instr[i].repS;
 			s->repL = h_STM.instr[i].repE - h_STM.instr[i].repS;
@@ -1541,7 +1541,7 @@
 				if (h_S3MInstr.c2Spd > 65535) // ST3 (and OpenMPT) does this
 					h_S3MInstr.c2Spd = 65535;
 
-				tuneSample(s, h_S3MInstr.c2Spd);
+				tuneSample(s, h_S3MInstr.c2Spd, false);
 
 				s->len = h_S3MInstr.len;
 				s->vol = h_S3MInstr.vol;
--- a/src/ft2_module_saver.c
+++ b/src/ft2_module_saver.c
@@ -80,7 +80,7 @@
 		ai--;
 	h.antInstrs = ai;
 
-	h.flags = audio.linearFreqTable;
+	h.flags = audio.linearPeriodsFlag;
 	memcpy(h.songTab, song.songTab, sizeof (song.songTab));
 
 	if (fwrite(&h, sizeof (h), 1, f) != 1)
@@ -266,7 +266,7 @@
 	incompatEfx = false;
 	noteUnderflow = false;
 
-	if (audio.linearFreqTable)
+	if (audio.linearPeriodsFlag)
 		okBoxThreadSafe(0, "System message", "Linear frequency table used!");
 
 	// sanity checking
--- a/src/ft2_pattern_ed.c
+++ b/src/ft2_pattern_ed.c
@@ -2613,7 +2613,7 @@
 
 	resetPlaybackTime();
 
-	if (!audio.linearFreqTable)
+	if (!audio.linearPeriodsFlag)
 		setFrqTab(true);
 
 	clearPattMark();
--- a/src/ft2_replayer.c
+++ b/src/ft2_replayer.c
@@ -123,13 +123,15 @@
 	editor.updateWindowTitle = true;
 }
 
-void tuneSample(sampleTyp *s, const int32_t midCFreq) // used on external sample load (not when loading module)
+// used on external sample load and during sample loading in some module formats
+void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag)
 {
 	#define NOTE_C4 (4*12)
 	#define MIN_PERIOD (0)
 	#define MAX_PERIOD (((10*12*16)-1)-1) /* -1 (because of bugged amigaPeriods table values) */
 
-	if (midCFreq <= 0 || note2Period == NULL)
+	const uint16_t *periodTab = linearPeriodsFlag ? linearPeriods : amigaPeriods;
+	if (midCFreq <= 0 || periodTab == NULL)
 	{
 		s->fine = s->relTon = 0;
 		return;
@@ -137,7 +139,7 @@
 
 	// handle frequency boundaries first...
 
-	if (midCFreq <= (int32_t)dPeriod2HzTab[note2Period[MIN_PERIOD]])
+	if (midCFreq <= (int32_t)dPeriod2HzTab[periodTab[MIN_PERIOD]])
 	{
 		s->fine = -128;
 		s->relTon = -48;
@@ -144,7 +146,7 @@
 		return;
 	}
 
-	if (midCFreq >= (int32_t)dPeriod2HzTab[note2Period[MAX_PERIOD]])
+	if (midCFreq >= (int32_t)dPeriod2HzTab[periodTab[MAX_PERIOD]])
 	{
 		s->fine = 127;
 		s->relTon = 71;
@@ -154,7 +156,7 @@
 	// check if midCFreq is matching any of the non-finetuned note frequencies (C-0..B-9)
 	for (int8_t i = 0; i < 10*12; i++)
 	{
-		if (midCFreq == (int32_t)dPeriod2HzTab[note2Period[16 + (i<<4)]])
+		if (midCFreq == (int32_t)dPeriod2HzTab[periodTab[16 + (i<<4)]])
 		{
 			s->fine = 0;
 			s->relTon = i - NOTE_C4;
@@ -167,13 +169,13 @@
 	int32_t period = MAX_PERIOD;
 	for (; period >= MIN_PERIOD; period--)
 	{
-		const int32_t curr = (int32_t)dPeriod2HzTab[note2Period[period]];
+		const int32_t curr = (int32_t)dPeriod2HzTab[periodTab[period]];
 		if (midCFreq == curr)
 			break;
 
 		if (midCFreq > curr)
 		{
-			const int32_t next = (int32_t)dPeriod2HzTab[note2Period[period+1]];
+			const int32_t next = (int32_t)dPeriod2HzTab[periodTab[period+1]];
 			const int32_t errorCurr = ABS(curr-midCFreq);
 			const int32_t errorNext = ABS(next-midCFreq);
 
@@ -259,7 +261,7 @@
 {
 	dPeriod2HzTab[0] = 0.0; // in FT2, a period of 0 converts to 0Hz
 
-	if (audio.linearFreqTable)
+	if (audio.linearPeriodsFlag)
 	{
 		// linear periods
 		for (int32_t i = 1; i < 65536; i++)
@@ -311,7 +313,7 @@
 
 	const int32_t C4Period = (note << 4) + (((int8_t)s->fine >> 3) + 16);
 
-	const uint16_t period = audio.linearFreqTable ? linearPeriods[C4Period] : amigaPeriods[C4Period];
+	const uint16_t period = audio.linearPeriodsFlag ? linearPeriods[C4Period] : amigaPeriods[C4Period];
 	return dPeriod2Hz(period);
 }
 
@@ -319,9 +321,9 @@
 {
 	pauseAudio();
 
-	audio.linearFreqTable = linear;
+	audio.linearPeriodsFlag = linear;
 
-	if (audio.linearFreqTable)
+	if (audio.linearPeriodsFlag)
 		note2Period = linearPeriods;
 	else
 		note2Period = amigaPeriods;
@@ -2839,7 +2841,7 @@
 	editor.tempo = song.tempo = 6;
 	editor.globalVol = song.globVol = 64;
 	song.initialTempo = song.tempo;
-	audio.linearFreqTable = true;
+	audio.linearPeriodsFlag = true;
 	note2Period = linearPeriods;
 
 	if (!calcWindowedSincTables())
--- a/src/ft2_replayer.h
+++ b/src/ft2_replayer.h
@@ -259,7 +259,9 @@
 void fixSongName(void); // removes spaces from right side of song name
 void fixSampleName(int16_t nr); // removes spaces from right side of ins/smp names
 void calcReplayerVars(int32_t rate);
-void tuneSample(sampleTyp *s, const int32_t midCFreq);
+
+// used on external sample load and during sample loading in some module formats
+void tuneSample(sampleTyp *s, const int32_t midCFreq, bool linearPeriodsFlag);
 
 void calcRevMixDeltaTable(void);
 void calcReplayerLogTab(void);
--- a/src/ft2_sample_loader.c
+++ b/src/ft2_sample_loader.c
@@ -650,7 +650,7 @@
 	tmpSmp.vol = 64;
 	tmpSmp.pan = 128;
 
-	tuneSample(&tmpSmp, sampleRate);
+	tuneSample(&tmpSmp, sampleRate, audio.linearPeriodsFlag);
 
 	// set sample name
 	char *tmpFilename = unicharToCp437(filename, true);
@@ -916,7 +916,7 @@
 	tmpSmp.vol = (uint8_t)sampleVol;
 	tmpSmp.pan = 128;
 
-	tuneSample(&tmpSmp, sampleRate);
+	tuneSample(&tmpSmp, sampleRate, audio.linearPeriodsFlag);
 
 	// set name
 	if (namePtr != 0 && nameLen > 0)
@@ -1788,7 +1788,7 @@
 		tmpSmp.pek = tmpSmp.origPek + SMP_DAT_OFFSET;
 	}
 
-	tuneSample(&tmpSmp, sampleRate);
+	tuneSample(&tmpSmp, sampleRate, audio.linearPeriodsFlag);
 
 	tmpSmp.vol = 64;
 	tmpSmp.pan = 128;
--- a/src/ft2_sampling.c
+++ b/src/ft2_sampling.c
@@ -387,7 +387,7 @@
 	freeSample(editor.curInstr, editor.curSmp);
 	s->typ |= 16; // we always sample in 16-bit
 
-	tuneSample(s, samplingRate); // tune sample (relTone/finetune) to the sampling frequency we obtained
+	tuneSample(s, samplingRate, audio.linearPeriodsFlag); // tune sample (relTone/finetune) to the sampling frequency we obtained
 
 	if (sampleInStereo)
 	{
@@ -409,7 +409,7 @@
 			nextSmp->typ |= 16; // we always sample in 16-bit
 			nextSmp->pan = 255;
 
-			tuneSample(nextSmp, samplingRate); // tune sample (relTone/finetune) to the sampling frequency we obtained
+			tuneSample(nextSmp, samplingRate, audio.linearPeriodsFlag); // tune sample (relTone/finetune) to the sampling frequency we obtained
 		}
 	}
 	else