shithub: ft²

Download patch

ref: 6c3d4b444a9a087946cf974ce394497ffe598872
parent: 6c8bd4efbb4713c2c1e83ded672244219596f4d2
author: Olav Sørensen <[email protected]>
date: Mon Apr 13 18:29:27 EDT 2020

Pushed v1.20 code

- x86_64/amd64 users now get 32.32 fixed-point precision in the audio channel
  mixer, an extra 192kHz mixing frequency mode (may only work with a larger
  buffer size), and double the amount of phases in the cubic spline table. This
  will only make an improved outcome in very few cases (like extremely high/low
  channel rates), so don't expect to hear any difference. Non-x86_64 users now
  lose 96kHz mode as it was a bit unsuitable with 16.16 fixed-point precision.
- The "Volume" function in Smp. Ed. now has more precision and takes less time
  to complete. Not that it was slow to begin with...
- Increased the minimum .WAV rendering frequency from 8kHz to 44.1kHz, because
  the mixer delta calculations could overflow on such low rates.
- Some more small miscellaneous changes not worth of a mention
- Code cleanup

--- a/src/ft2_audio.c
+++ b/src/ft2_audio.c
@@ -19,7 +19,7 @@
 
 static int8_t pmpCountDiv, pmpChannels = 2;
 static uint16_t smpBuffSize;
-static int32_t masterVol, oldAudioFreq, speedVal, pmpLeft, randSeed = INITIAL_DITHER_SEED;
+static int32_t masterVol, oldAudioFreq, pmpLeft, randSeed = INITIAL_DITHER_SEED;
 static int32_t prngStateL, prngStateR;
 static uint32_t tickTimeLen, tickTimeLenFrac;
 static float fAudioAmpMul;
@@ -45,7 +45,7 @@
 }
 #endif
 
-void stopVoice(uint8_t i)
+void stopVoice(int32_t i)
 {
 	voice_t *v;
 
@@ -71,7 +71,7 @@
 		// set back old known working settings
 
 		config.audioFreq = audio.lastWorkingAudioFreq;
-		config.specialFlags &= ~(BITDEPTH_16 + BITDEPTH_24 + BUFFSIZE_512 + BUFFSIZE_1024 + BUFFSIZE_2048);
+		config.specialFlags &= ~(BITDEPTH_16 + BITDEPTH_32 + BUFFSIZE_512 + BUFFSIZE_1024 + BUFFSIZE_2048);
 		config.specialFlags |= audio.lastWorkingAudioBits;
 
 		if (audio.lastWorkingAudioDeviceName != NULL)
@@ -119,7 +119,7 @@
 
 	if (bitDepth32Flag)
 	{
-		// 32-bit floating point (24-bit)
+		// 32-bit floating point
 		fAudioAmpMul = fAudioNorm * (master / 256.0f) * (ampFactor / 32.0f);
 	}
 	else
@@ -153,11 +153,11 @@
 	if (bpm == 0)
 		return;
 
-	speedVal = ((audio.freq + audio.freq) + (audio.freq >> 1)) / bpm; // (audio.freq * 2.5) / BPM
-	if (speedVal > 0) // calculate tick time length for audio/video sync timestamp
+	audio.speedVal = ((audio.freq + audio.freq) + (audio.freq >> 1)) / bpm; // (audio.freq * 2.5) / BPM
+	if (audio.speedVal > 0) // calculate tick time length for audio/video sync timestamp
 	{
 		// number of samples per tick -> tick length for performance counter
-		dFrac = modf(speedVal * audio.dSpeedValMul, &dInt);
+		dFrac = modf(audio.speedVal * audio.dSpeedValMul, &dInt);
 
 		/* - integer part -
 		** Cast to int32_t so that the compiler will use fast SSE2 float->int instructions.
@@ -167,9 +167,13 @@
 
 		// - fractional part (scaled to 0..2^32-1) -
 		dFrac *= UINT32_MAX;
-		tickTimeLenFrac = (uint32_t)(dFrac + 0.5);
+		dFrac += 0.5;
+		if (dFrac > UINT32_MAX)
+			dFrac = UINT32_MAX;
 
-		audio.rampSpeedValMul = 0xFFFFFFFF / speedVal;
+		tickTimeLenFrac = (uint32_t)dFrac;
+
+		audio.rampSpeedValMul = 0xFFFFFFFF / audio.speedVal;
 	}
 }
 
@@ -262,7 +266,7 @@
 			}
 			else
 			{
-				v->SVolIPLen = speedVal;
+				v->SVolIPLen = audio.speedVal;
 				v->SLVolIP = ((int64_t)destVolL * audio.rampSpeedValMul) >> 32;
 				v->SRVolIP = ((int64_t)destVolR * audio.rampSpeedValMul) >> 32;
 			}
@@ -337,7 +341,7 @@
 void mix_SaveIPVolumes(void) // for volume ramping
 {
 	voice_t *v = voice;
-	for (uint32_t i = 0; i < MAX_VOICES; i++, v++)
+	for (int32_t i = 0; i < song.antChn; i++, v++)
 	{
 		v->SLVol2 = v->SLVol1;
 		v->SRVol2 = v->SRVol1;
@@ -357,24 +361,18 @@
 	for (int32_t i = 0; i < song.antChn; i++, ch++, v++)
 	{
 		status = ch->tmpStatus = ch->status; // ch->tmpStatus is used for audio/video sync queue
-		if (status == 0)
-			continue;
-
+		if (status == 0) continue;
 		ch->status = 0;
 
-		// volume change
 		if (status & IS_Vol)
 			v->SVol = ch->finalVol;
 
-		// panning change
 		if (status & IS_Pan)
 			v->SPan = ch->finalPan;
 
-		// update mixing volumes if vol/pan change
 		if (status & (IS_Vol + IS_Pan))
 			voiceUpdateVolumes(i, status);
 
-		// frequency change (received even if the period didn't change!)
 		if (status & IS_Period)
 		{
 #if defined __amd64__ || defined _WIN64
@@ -397,7 +395,6 @@
 #endif
 		}
 
-		// sample trigger (note)
 		if (status & IS_NyTon)
 			voiceTrigger(i, ch->smpPtr, ch->smpStartPos);
 	}
@@ -590,9 +587,9 @@
 {
 	voice_t *v, *r;
 
-	assert(speedVal <= MAX_WAV_RENDER_SAMPLES_PER_TICK);
-	memset(audio.mixBufferL, 0, speedVal * sizeof (int32_t));
-	memset(audio.mixBufferR, 0, speedVal * sizeof (int32_t));
+	assert(audio.speedVal <= MAX_WAV_RENDER_SAMPLES_PER_TICK);
+	memset(audio.mixBufferL, 0, audio.speedVal * sizeof (int32_t));
+	memset(audio.mixBufferR, 0, audio.speedVal * sizeof (int32_t));
 
 	// mix channels
 	v = voice; // normal voices
@@ -601,8 +598,8 @@
 	for (int32_t i = 0; i < song.antChn; i++, v++, r++)
 	{
 		// call the mixing routine currently set for the voice
-		if (v->mixRoutine != NULL) v->mixRoutine(v, speedVal); // mix normal voice
-		if (r->mixRoutine != NULL) r->mixRoutine(r, speedVal); // mix volume ramp voice
+		if (v->mixRoutine != NULL) v->mixRoutine(v, audio.speedVal); // mix normal voice
+		if (r->mixRoutine != NULL) r->mixRoutine(r, audio.speedVal); // mix volume ramp voice
 	}
 
 	// normalize mix buffer and send to audio stream
@@ -609,16 +606,16 @@
 	if (bitDepth == 16)
 	{
 		if (config.specialFlags2 & DITHERED_AUDIO)
-			sendSamples16BitDitherStereo(stream, speedVal, 2);
+			sendSamples16BitDitherStereo(stream, audio.speedVal, 2);
 		else
-			sendSamples16BitStereo(stream, speedVal, 2);
+			sendSamples16BitStereo(stream, audio.speedVal, 2);
 	}
 	else
 	{
-		sendSamples24BitStereo(stream, speedVal, 2);
+		sendSamples24BitStereo(stream, audio.speedVal, 2);
 	}
 
-	return speedVal;
+	return audio.speedVal;
 }
 
 int32_t pattQueueReadSize(void)
@@ -932,12 +929,12 @@
 			}
 
 			// push channel variables to sync queue
-			for (int32_t i = 0; i < song.antChn; i++)
-			{
-				c = &chSyncData.channels[i];
-				s = &stm[i];
 
-				c->voiceDelta = voice[i].SFrq;
+			c = chSyncData.channels;
+			s = stm;
+
+			for (int32_t i = 0; i < song.antChn; i++, c++, s++)
+			{
 				c->finalPeriod = s->finalPeriod;
 				c->fineTune = s->fineTune;
 				c->relTonNr = s->relTonNr;
@@ -960,7 +957,7 @@
 				audio.tickTime64++;
 			}
 
-			pmpLeft = speedVal;
+			pmpLeft = audio.speedVal;
 			replayerBusy = false;
 		}
 
@@ -1016,8 +1013,8 @@
 	if (lockMixer)
 		lockMixerCallback();
 
-	// force dither off if somehow set with 24-bit float (illegal)
-	if ((config.specialFlags2 & DITHERED_AUDIO) && (config.specialFlags & BITDEPTH_24))
+	// force dither off if somehow set with 32-bit float (illegal)
+	if ((config.specialFlags2 & DITHERED_AUDIO) && (config.specialFlags & BITDEPTH_32))
 		config.specialFlags2 &= ~DITHERED_AUDIO;
 
 	if (config.specialFlags2 & DITHERED_AUDIO)
@@ -1062,15 +1059,17 @@
 
 	dAudioLatencySecs = haveSamples / dHaveFreq;
 
-	// XXX: haveSamples and haveFreq better not be bogus values...
 	dFrac = modf(dAudioLatencySecs * editor.dPerfFreq, &dInt);
 
 	// integer part
-	audio.audLatencyPerfValInt = (uint32_t)dInt;
+	audio.audLatencyPerfValInt = (int32_t)dInt;
 
 	// fractional part (scaled to 0..2^32-1)
 	dFrac *= UINT32_MAX;
-	audio.audLatencyPerfValFrac = (uint32_t)(dFrac + 0.5);
+	dFrac += 0.5;
+	if (dFrac > UINT32_MAX)
+		dFrac = UINT32_MAX;
+	audio.audLatencyPerfValFrac = (uint32_t)dFrac;
 
 	audio.dAudioLatencyMs = dAudioLatencySecs * 1000.0;
 }
@@ -1108,10 +1107,7 @@
 	closeAudio();
 
 	if (config.audioFreq < MIN_AUDIO_FREQ || config.audioFreq > MAX_AUDIO_FREQ)
-	{
-		// set default rate
-		config.audioFreq = 48000;
-	}
+		config.audioFreq = 48000; // set default rate
 
 	// get audio buffer size from config special flags
 
@@ -1130,7 +1126,7 @@
 
 	// these three may change after opening a device, but our mixer is dealing with it
 	want.freq = config.audioFreq;
-	want.format = (config.specialFlags & BITDEPTH_24) ? AUDIO_F32 : AUDIO_S16;
+	want.format = (config.specialFlags & BITDEPTH_32) ? AUDIO_F32 : AUDIO_S16;
 	want.channels = 2;
 	// -------------------------------------------------------------------------------
 	want.callback = mixCallback;
@@ -1149,7 +1145,7 @@
 	if (have.format != AUDIO_S16 && have.format != AUDIO_F32)
 	{
 		if (showErrorMsg)
-			showErrorMsgBox("Couldn't open audio device:\nThe program doesn't support an SDL_AudioFormat of '%d' (not 16-bit or 24-bit float).",
+			showErrorMsgBox("Couldn't open audio device:\nThe program doesn't support an SDL_AudioFormat of '%d' (not 16-bit or 32-bit float).",
 				(uint32_t)have.format);
 
 		closeAudio();
@@ -1157,7 +1153,12 @@
 	}
 
 	// test if the received audio rate is compatible
-	if (have.freq != 44100 && have.freq != 48000 && have.freq != 96000)
+
+#if defined _WIN64 || defined __amd64__
+	if (have.freq != 44100 && have.freq != 48000 && have.freq != 96000 && have.freq != 192000)
+#else
+	if (have.freq != 44100 && have.freq != 48000)
+#endif
 	{
 		if (showErrorMsg)
 			showErrorMsgBox("Couldn't open audio device:\nThe program doesn't support an audio output rate of %dHz. Sorry!", have.freq);
@@ -1178,7 +1179,7 @@
 	// set new bit depth flag
 
 	newBitDepth = 16;
-	config.specialFlags &= ~BITDEPTH_24;
+	config.specialFlags &= ~BITDEPTH_32;
 	config.specialFlags |=  BITDEPTH_16;
 
 	if (have.format == AUDIO_F32)
@@ -1185,7 +1186,7 @@
 	{
 		newBitDepth = 24;
 		config.specialFlags &= ~BITDEPTH_16;
-		config.specialFlags |=  BITDEPTH_24;
+		config.specialFlags |=  BITDEPTH_32;
 	}
 
 	audio.haveFreq = have.freq;
@@ -1209,7 +1210,7 @@
 	// make a copy of the new known working audio settings
 
 	audio.lastWorkingAudioFreq = config.audioFreq;
-	audio.lastWorkingAudioBits = config.specialFlags & (BITDEPTH_16 + BITDEPTH_24 + BUFFSIZE_512 + BUFFSIZE_1024 + BUFFSIZE_2048);
+	audio.lastWorkingAudioBits = config.specialFlags & (BITDEPTH_16 + BITDEPTH_32 + BUFFSIZE_512 + BUFFSIZE_1024 + BUFFSIZE_2048);
 	setLastWorkingAudioDevName();
 
 	// update config audio radio buttons if we're on that screen at the moment
@@ -1217,10 +1218,10 @@
 		showConfigScreen();
 
 	updateWavRendererSettings();
-	setAudioAmp(config.boostLevel, config.masterVol, (config.specialFlags & BITDEPTH_24) ? true : false);
+	setAudioAmp(config.boostLevel, config.masterVol, (config.specialFlags & BITDEPTH_32) ? true : false);
 
 	// don't call stopVoices() in this routine
-	for (uint8_t i = 0; i < MAX_VOICES; i++)
+	for (int32_t i = 0; i < MAX_VOICES; i++)
 		stopVoice(i);
 
 	stopAllScopes();
--- a/src/ft2_audio.h
+++ b/src/ft2_audio.h
@@ -11,32 +11,37 @@
 	FREQ_TABLE_AMIGA = 1,
 };
 
-/* Warning: MIXER_FRAC_BITS must NOT be higher than 22!
-** This can create an overflow in certain calculations.
-**
-** Use 16 on non-x86_64 platforms so that we can avoid a
+/*  Use 16 on non-x86_64 platforms so that we can avoid a
 ** 64-bit division in the outside mixer loop. x86_64 users
-** are lucky and will get higher fractional delta precision.
-** This is beneficial in 96kHz mode, where deltas are lower
-** in value.
+** are lucky and will get double the fractional delta precision.
+** This is beneficial in 96kHz/192kHz mode, where deltas are
+** lower in value.
 */
-#if defined __amd64__ || defined _WIN64
-#define MIXER_FRAC_BITS 22
+#if defined _WIN64 || defined __amd64__
+
+#define MIN_AUDIO_FREQ 44100
+#define MAX_AUDIO_FREQ 192000
+
+#define MIXER_FRAC_BITS 32
+#define MIXER_FRAC_SCALE (1ULL << MIXER_FRAC_BITS)
+#define MIXER_FRAC_MASK (MIXER_FRAC_SCALE-1)
+
 #else
+
+#define MIN_AUDIO_FREQ 44100
+#define MAX_AUDIO_FREQ 48000
+
 #define MIXER_FRAC_BITS 16
+#define MIXER_FRAC_SCALE (1UL << MIXER_FRAC_BITS)
+#define MIXER_FRAC_MASK (MIXER_FRAC_SCALE-1)
+
 #endif
 
-#define MIXER_FRAC_SCALE (1L << MIXER_FRAC_BITS)
-#define MIXER_FRAC_MASK (MIXER_FRAC_SCALE-1)
+#define MAX_AUDIO_DEVICES 99
 
 // for audio/video sync queue. (2^n-1 - don't change this! Queue buffer is already ~2.7MB in size)
 #define SYNC_QUEUE_LEN 4095
 
-#define MAX_AUDIO_DEVICES 99
-
-#define MIN_AUDIO_FREQ 44100
-#define MAX_AUDIO_FREQ 96000
-
 struct audio_t
 {
 	char *currInputDevice, *currOutputDevice, *lastWorkingAudioDeviceName;
@@ -47,7 +52,7 @@
 	int32_t quickVolSizeVal, *mixBufferL, *mixBufferR, *mixBufferLUnaligned, *mixBufferRUnaligned;
 	int32_t rampQuickVolMul, rampSpeedValMul;
 	uint32_t freq;
-	uint32_t audLatencyPerfValInt, audLatencyPerfValFrac;
+	uint32_t audLatencyPerfValInt, audLatencyPerfValFrac, speedVal, musicTimeSpeedVal;
 	uint64_t tickTime64, tickTime64Frac;
 	double dAudioLatencyMs, dSpeedValMul, dPianoDeltaMul;
 	SDL_AudioDeviceID dev;
@@ -63,10 +68,12 @@
 	uint16_t SVol;
 	int32_t SLVol1, SRVol1, SLVol2, SRVol2, SLVolIP, SRVolIP;
 	int32_t SPos, SLen, SRepS, SRepL;
-	uint32_t SVolIPLen, SPosDec, SFrq;
-	
-#if !defined __amd64__ && !defined _WIN64
-	uint32_t SFrqRev;
+	uint32_t SVolIPLen;
+
+#if defined _WIN64 || defined __amd64__
+	uint64_t SPosDec, SFrq;
+#else
+	uint32_t SPosDec, SFrq, SFrqRev;
 #endif
 
 	void (*mixRoutine)(void *, int32_t); // function pointer to mix routine
@@ -109,6 +116,7 @@
 int32_t pattQueueWriteSize(void);
 bool pattQueuePush(pattSyncData_t t);
 bool pattQueuePop(void);
+bool pattQueuePop(void);
 pattSyncData_t *pattQueuePeek(void);
 uint64_t getPattQueueTimestamp(void);
 int32_t chQueueReadSize(void);
@@ -123,7 +131,7 @@
 void setSpeed(uint16_t bpm);
 void audioSetVolRamp(bool volRamp);
 void audioSetInterpolation(bool interpolation);
-void stopVoice(uint8_t i);
+void stopVoice(int32_t i);
 bool setupAudio(bool showErrorMsg);
 void closeAudio(void);
 void pauseAudio(void);
--- a/src/ft2_config.c
+++ b/src/ft2_config.c
@@ -135,8 +135,13 @@
 		config.recQuantRes = 16;
 	}
 
-	if (config.audioFreq != 44100 && config.audioFreq != 48000 && config.audioFreq != 96000)
+#if defined __amd64__ || defined _WIN64
+	if (config.audioFreq != 44100 && config.audioFreq != 48000 && config.audioFreq != 96000 && config.audioFreq != 192000)
 		config.audioFreq = 48000;
+#else
+	if (config.audioFreq != 44100 && config.audioFreq != 48000)
+		config.audioFreq = 48000;
+#endif
 
 	if (config.audioInputFreq <= 1) // default value from FT2 (this was cdr_Sync) - set defaults
 		config.audioInputFreq = INPUT_FREQ_48KHZ;
@@ -154,9 +159,9 @@
 	if (config.windowFlags == 0) // default value from FT2 (this was ptnDefaultLen byte #2) - set defaults
 		config.windowFlags = WINSIZE_AUTO;
 
-	// audio bit depth - remove 24-bit flag if both are enabled
-	if ((config.specialFlags & BITDEPTH_16) && (config.specialFlags & BITDEPTH_24))
-		config.specialFlags &= ~BITDEPTH_24;
+	// audio bit depth - remove 32-bit flag if both are enabled
+	if ((config.specialFlags & BITDEPTH_16) && (config.specialFlags & BITDEPTH_32))
+		config.specialFlags &= ~BITDEPTH_32;
 
 	if (audio.dev != 0)
 		setNewAudioSettings();
@@ -163,7 +168,7 @@
 
 	audioSetInterpolation(config.interpolation ? true : false);
 	audioSetVolRamp((config.specialFlags & NO_VOLRAMP_FLAG) ? false : true);
-	setAudioAmp(config.boostLevel, config.masterVol, config.specialFlags & BITDEPTH_24);
+	setAudioAmp(config.boostLevel, config.masterVol, config.specialFlags & BITDEPTH_32);
 	setMouseShape(config.mouseType);
 	changeLogoType(config.id_FastLogo);
 	changeBadgeType(config.id_TritonProd);
@@ -804,7 +809,7 @@
 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_BIT_DEPTH);
 
 	tmpID = RB_CONFIG_AUDIO_16BIT;
-	if (config.specialFlags & BITDEPTH_24)
+	if (config.specialFlags & BITDEPTH_32)
 		tmpID = RB_CONFIG_AUDIO_24BIT;
 
 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
@@ -813,9 +818,12 @@
 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_FREQ);
 	switch (config.audioFreq)
 	{
-		         case 44100: tmpID = RB_CONFIG_AUDIO_44KHZ; break;
-		default: case 48000: tmpID = RB_CONFIG_AUDIO_48KHZ; break;
-		         case 96000: tmpID = RB_CONFIG_AUDIO_96KHZ; break;
+		         case 44100:  tmpID = RB_CONFIG_AUDIO_44KHZ;  break;
+		default: case 48000:  tmpID = RB_CONFIG_AUDIO_48KHZ;  break;
+#if defined __amd64__ || defined _WIN64
+		         case 96000:  tmpID = RB_CONFIG_AUDIO_96KHZ;  break;
+		         case 192000: tmpID = RB_CONFIG_AUDIO_192KHZ; break;
+#endif
 	}
 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
 
@@ -847,7 +855,7 @@
 {
 	checkBoxes[CB_CONF_INTERPOLATION].checked = config.interpolation;
 	checkBoxes[CB_CONF_VOL_RAMP].checked = (config.specialFlags & NO_VOLRAMP_FLAG) ? false : true;
-	checkBoxes[CB_CONF_DITHER].checked = (config.specialFlags & BITDEPTH_24) ? false : config.specialFlags2 & DITHERED_AUDIO;
+	checkBoxes[CB_CONF_DITHER].checked = (config.specialFlags & BITDEPTH_32) ? false : config.specialFlags2 & DITHERED_AUDIO;
 
 	showCheckBox(CB_CONF_INTERPOLATION);
 	showCheckBox(CB_CONF_VOL_RAMP);
@@ -1134,7 +1142,7 @@
 
 			textOutShadow(390,  76, PAL_FORGRND, PAL_DSKTOP2, "Audio bit depth:");
 			textOutShadow(406,  90, PAL_FORGRND, PAL_DSKTOP2, "16-bit (default)");
-			textOutShadow(406, 104, PAL_FORGRND, PAL_DSKTOP2, "24-bit float");
+			textOutShadow(406, 104, PAL_FORGRND, PAL_DSKTOP2, "32-bit float");
 
 			textOutShadow(390, 120, PAL_FORGRND, PAL_DSKTOP2, "Mixing device ctrl.:");
 			textOutShadow(406, 134, PAL_FORGRND, PAL_DSKTOP2, "Interpolation");
@@ -1144,8 +1152,10 @@
 			textOutShadow(509,   3, PAL_FORGRND, PAL_DSKTOP2, "Mixing frequency:");
 			textOutShadow(525,  17, PAL_FORGRND, PAL_DSKTOP2, "44100Hz");
 			textOutShadow(525,  31, PAL_FORGRND, PAL_DSKTOP2, "48000Hz (default)");
+#if defined __amd64__ || defined _WIN64
 			textOutShadow(525,  45, PAL_FORGRND, PAL_DSKTOP2, "96000Hz");
-
+			textOutShadow(525,  59, PAL_FORGRND, PAL_DSKTOP2, "192000Hz");
+#endif
 			textOutShadow(509,  76, PAL_FORGRND, PAL_DSKTOP2, "Frequency table:");
 			textOutShadow(525,  90, PAL_FORGRND, PAL_DSKTOP2, "Amiga freq. table");
 			textOutShadow(525, 104, PAL_FORGRND, PAL_DSKTOP2, "Linear freq. table");
@@ -1561,7 +1571,7 @@
 
 void rbConfigAudio16bit(void)
 {
-	config.specialFlags &= ~BITDEPTH_24;
+	config.specialFlags &= ~BITDEPTH_32;
 	config.specialFlags |=  BITDEPTH_16;
 
 	setNewAudioSettings();
@@ -1570,9 +1580,9 @@
 void rbConfigAudio24bit(void)
 {
 	config.specialFlags &= ~BITDEPTH_16;
-	config.specialFlags |=  BITDEPTH_24;
+	config.specialFlags |=  BITDEPTH_32;
 
-	config.specialFlags2 &= ~DITHERED_AUDIO; // no dither in "24-bit float" mode
+	config.specialFlags2 &= ~DITHERED_AUDIO; // no dither in "32-bit float" mode
 
 	checkBoxes[CB_CONF_DITHER].checked = false;
 	if (editor.currConfigScreen == CONFIG_SCREEN_IO_DEVICES)
@@ -1599,6 +1609,12 @@
 	setNewAudioSettings();
 }
 
+void rbConfigAudio192kHz(void)
+{
+	config.audioFreq = 192000;
+	setNewAudioSettings();
+}
+
 void rbConfigAudioInput44kHz(void)
 {
 	config.audioInputFreq = INPUT_FREQ_44KHZ;
@@ -1650,7 +1666,7 @@
 
 void cbConfigDither(void)
 {
-	if (config.specialFlags & BITDEPTH_24) // no dither in float mode, force off
+	if (config.specialFlags & BITDEPTH_32) // no dither in float mode, force off
 	{
 		config.specialFlags2 &= ~DITHERED_AUDIO;
 
@@ -2151,7 +2167,7 @@
 	if (config.boostLevel != (int8_t)pos + 1)
 	{
 		config.boostLevel = (int8_t)pos + 1;
-		setAudioAmp(config.boostLevel, config.masterVol, config.specialFlags & BITDEPTH_24);
+		setAudioAmp(config.boostLevel, config.masterVol, config.specialFlags & BITDEPTH_32);
 		configDrawAmp();
 		updateWavRendererSettings();
 	}
@@ -2172,7 +2188,7 @@
 	if (config.masterVol != (int16_t)pos)
 	{
 		config.masterVol = (int16_t)pos;
-		setAudioAmp(config.boostLevel, config.masterVol, config.specialFlags & BITDEPTH_24);
+		setAudioAmp(config.boostLevel, config.masterVol, config.specialFlags & BITDEPTH_32);
 	}
 }
 
--- a/src/ft2_config.h
+++ b/src/ft2_config.h
@@ -67,7 +67,7 @@
 	// specialFlags
 	NO_VOLRAMP_FLAG = 1,
 	BITDEPTH_16 = 2,
-	BITDEPTH_24 = 4,
+	BITDEPTH_32 = 4,
 	BUFFSIZE_512 = 8,
 	BUFFSIZE_1024 = 16,
 	BUFFSIZE_2048 = 32,
@@ -208,6 +208,7 @@
 void rbConfigAudio44kHz(void);
 void rbConfigAudio48kHz(void);
 void rbConfigAudio96kHz(void);
+void rbConfigAudio192kHz(void);
 void rbConfigAudioInput44kHz(void);
 void rbConfigAudioInput48kHz(void);
 void rbConfigAudioInput96kHz(void);
--- a/src/ft2_gui.c
+++ b/src/ft2_gui.c
@@ -1162,6 +1162,7 @@
 		textOutShadow(204, 80, PAL_FORGRND, PAL_DSKTOP2, "Time");
 		charOutShadow(250, 80, PAL_FORGRND, PAL_DSKTOP2, ':');
 		charOutShadow(270, 80, PAL_FORGRND, PAL_DSKTOP2, ':');
+
 		drawPlaybackTime();
 
 		     if (editor.ui.sampleEditorExtShown) drawSampleEditorExt();
--- a/src/ft2_inst_ed.c
+++ b/src/ft2_inst_ed.c
@@ -109,7 +109,7 @@
 static uint16_t saveInstrNr;
 static SDL_Thread *thread;
 
-extern const int16_t *note2Period; // ft2_replayer.c
+extern const uint16_t *note2Period; // ft2_replayer.c
 
 void updateInstEditor(void);
 void updateNewInstrument(void);
@@ -227,33 +227,24 @@
 
 static void drawMIDICh(void)
 {
-	char str[8];
 	instrTyp *ins = getCurDispInstr();
-
 	assert(ins->midiChannel <= 15);
-	uint8_t disp = ins->midiChannel + 1;
-	sprintf(str, "%02d", disp);
-	textOutFixed(156, 132, PAL_FORGRND, PAL_DESKTOP, str);
+	const uint8_t val = ins->midiChannel + 1;
+	textOutFixed(156, 132, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[val]);
 }
 
 static void drawMIDIPrg(void)
 {
-	char str[8];
 	instrTyp *ins = getCurDispInstr();
-
 	assert(ins->midiProgram <= 127);
-	sprintf(str, "%03d", ins->midiProgram);
-	textOutFixed(149, 146, PAL_FORGRND, PAL_DESKTOP, str);
+	textOutFixed(149, 146, PAL_FORGRND, PAL_DESKTOP, dec3StrTab[ins->midiProgram]);
 }
 
 static void drawMIDIBend(void)
 {
-	char str[8];
 	instrTyp *ins = getCurDispInstr();
-
 	assert(ins->midiBend <= 36);
-	sprintf(str, "%02d", ins->midiBend);
-	textOutFixed(156, 160, PAL_FORGRND, PAL_DESKTOP, str);
+	textOutFixed(156, 160, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->midiBend]);
 }
 
 void midiChDown(void)
@@ -384,56 +375,44 @@
 
 static void drawVolEnvSus(void)
 {
-	char str[8];
 	instrTyp *ins = getCurDispInstr();
-
-	sprintf(str, "%02d", ins->envVSust);
-	textOutFixed(382, 206, PAL_FORGRND, PAL_DESKTOP, str);
+	assert(ins->envVSust < 100);
+	textOutFixed(382, 206, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->envVSust]);
 }
 
 static void drawVolEnvRepS(void)
 {
-	char str[8];
 	instrTyp *ins = getCurDispInstr();
-
-	sprintf(str, "%02d", ins->envVRepS);
-	textOutFixed(382, 233, PAL_FORGRND, PAL_DESKTOP, str);
+	assert(ins->envVRepS < 100);
+	textOutFixed(382, 233, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->envVRepS]);
 }
 
 static void drawVolEnvRepE(void)
 {
-	char str[8];
 	instrTyp *ins = getCurDispInstr();
-
-	sprintf(str, "%02d", ins->envVRepE);
-	textOutFixed(382, 247, PAL_FORGRND, PAL_DESKTOP, str);
+	assert(ins->envVRepE < 100);
+	textOutFixed(382, 247, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->envVRepE]);
 }
 
 static void drawPanEnvSus(void)
 {
-	char str[8];
 	instrTyp *ins = getCurDispInstr();
-
-	sprintf(str, "%02d", ins->envPSust);
-	textOutFixed(382, 293, PAL_FORGRND, PAL_DESKTOP, str);
+	assert(ins->envPSust < 100);
+	textOutFixed(382, 293, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->envPSust]);
 }
 
 static void drawPanEnvRepS(void)
 {
-	char str[8];
 	instrTyp *ins = getCurDispInstr();
-
-	sprintf(str, "%02d", ins->envPRepS);
-	textOutFixed(382, 320, PAL_FORGRND, PAL_DESKTOP, str);
+	assert(ins->envPRepS < 100);
+	textOutFixed(382, 320, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->envPRepS]);
 }
 
 static void drawPanEnvRepE(void)
 {
-	char str[8];
 	instrTyp *ins = getCurDispInstr();
-
-	sprintf(str, "%02d", ins->envPRepE);
-	textOutFixed(382, 334, PAL_FORGRND, PAL_DESKTOP, str);
+	assert(ins->envPRepE < 100);
+	textOutFixed(382, 334, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[ins->envPRepE]);
 }
 
 static void drawVolume(void)
@@ -1693,33 +1672,10 @@
 	return true;
 }
 
-/* 8bitbubsy: This is my new version of FT2's buggy getNote().
-** It's used to convert a channel's period into a piano key number.
-** Or in this case, a voice's frequency into a piano key number.
-**
-** It's probably slower than the original version, but this one is
-** 100% accurate in all (quirky) situations.
-**
-** Warning: This function intentionally doesn't clamp the output value!
-*/
-static int32_t getPianoKey(int32_t voiceDelta, int32_t finetune, int32_t relativeNote)
-{
-	finetune >>= 3; // FT2 does this in the replayer internally (-128..127 -> -16..15)
-
-	double dTmp = voiceDelta * audio.dPianoDeltaMul;
-	dTmp = (log2(dTmp) * 12.0) - (finetune * (1.0 / 16.0));
-	int32_t note = (int32_t)(dTmp + 0.5); // rounded
-
-	note -= relativeNote;
-	// "note" is now the raw piano key number, unaffected by finetune/relativeNote
-
-	return note;
-}
-
 void drawPiano(chSyncData_t *chSyncData)
 {
 	bool newStatus[96];
-	int32_t note;
+	int32_t i, note;
 
 	memset(newStatus, 0, sizeof (newStatus));
 
@@ -1729,11 +1685,11 @@
 		if (chSyncData != NULL) // song is playing, use replayer channel state
 		{
 			syncedChannel_t *c = chSyncData->channels;
-			for (int32_t i = 0; i < song.antChn; i++, c++)
+			for (i = 0; i < song.antChn; i++, c++)
 			{
 				if (c->instrNr == editor.curInstr && c->envSustainActive)
 				{
-					note = getPianoKey(c->voiceDelta, c->fineTune, c->relTonNr);
+					note = getPianoKey(c->finalPeriod, c->fineTune, c->relTonNr);
 					if (note >= 0 && note <= 95)
 						newStatus[note] = true;
 				}
@@ -1742,12 +1698,11 @@
 		else // song is not playing (jamming from keyboard/MIDI)
 		{
 			stmTyp *c = stm;
-			for (int32_t i = 0; i < song.antChn; i++, c++)
+			for (i = 0; i < song.antChn; i++, c++)
 			{
 				if (c->instrNr == editor.curInstr && c->envSustainActive)
 				{
-					int32_t voiceDelta = getFrequenceValue(c->finalPeriod);
-					note = getPianoKey(voiceDelta, c->fineTune, c->relTonNr);
+					note = getPianoKey(c->finalPeriod, c->fineTune, c->relTonNr);
 					if (note >= 0 && note <= 95)
 						newStatus[note] = true;
 				}
@@ -1756,9 +1711,9 @@
 	}
 
 	// draw keys
-	for (int32_t i = 0; i < 96; i++)
+	for (i = 0; i < 96; i++)
 	{
-		bool keyDown = newStatus[i];
+		const bool keyDown = newStatus[i];
 		if (pianoKeyStatus[i] ^ keyDown)
 		{
 			uint8_t key = noteTab1[i];
--- a/src/ft2_intrp_table.c
+++ b/src/ft2_intrp_table.c
@@ -1,12 +1,12 @@
 #include <stdint.h>
 #include "ft2_intrp_table.h"
 
-/* 4-tap cubic spline table
-**
-** This table was generated using a modified version of Schism Tracker's lutgen.cpp
-** with 15-bit precision and 8192 phases.
-*/
+// 4-tap cubic spline table
 
+#if defined __amd64__ || defined _WIN64
+
+// 15-bit precision, 8192 phases (slightly harder on the CPU cache)
+
 const int16_t cubicSplineTable[CUBIC_WIDTH * CUBIC_PHASES] =
 {
 	    0, 32767,     0,     0,    -2, 32767,     2,     0,    -4, 32767,     4,     0,    -6, 32767,     6,     0,
@@ -2058,3 +2058,141 @@
 	    0,    16, 32767,   -16,     0,    14, 32767,   -14,     0,    12, 32767,   -12,     0,    10, 32767,   -10,
 	    0,     8, 32767,    -8,     0,     6, 32767,    -6,     0,     4, 32767,    -4,     0,     2, 32767,    -2
 };
+
+#else
+
+// for non-x86_64 CPUs: 15-bit precision, 512 phases
+
+const int16_t cubicSplineTable[CUBIC_WIDTH * CUBIC_PHASES] =
+{
+	    0, 32767,     0,     0,   -32, 32767,    32,     0,   -64, 32767,    65,     0,   -95, 32766,    98,    -1,
+	 -126, 32763,   132,    -1,  -157, 32761,   166,    -2,  -188, 32757,   201,    -2,  -218, 32753,   236,    -3,
+	 -248, 32748,   272,    -4,  -278, 32743,   308,    -5,  -308, 32737,   345,    -6,  -337, 32730,   382,    -7,
+	 -366, 32724,   419,    -9,  -395, 32716,   457,   -10,  -424, 32708,   496,   -12,  -452, 32699,   535,   -14,
+	 -481, 32690,   575,   -16,  -508, 32679,   614,   -17,  -536, 32669,   655,   -20,  -564, 32658,   696,   -22,
+	 -591, 32646,   737,   -24,  -618, 32633,   779,   -26,  -645, 32621,   821,   -29,  -671, 32607,   864,   -32,
+	 -698, 32593,   907,   -34,  -724, 32578,   951,   -37,  -750, 32563,   995,   -40,  -775, 32547,  1039,   -43,
+	 -801, 32531,  1084,   -46,  -826, 32515,  1129,   -50,  -851, 32497,  1175,   -53,  -876, 32479,  1221,   -56,
+	 -900, 32460,  1268,   -60,  -924, 32441,  1315,   -64,  -948, 32420,  1363,   -67,  -972, 32400,  1411,   -71,
+	 -996, 32380,  1459,   -75, -1019, 32358,  1508,   -79, -1042, 32337,  1557,   -84, -1065, 32314,  1607,   -88,
+	-1088, 32291,  1657,   -92, -1110, 32268,  1707,   -97, -1133, 32244,  1758,  -101, -1155, 32220,  1809,  -106,
+	-1176, 32194,  1861,  -111, -1198, 32168,  1913,  -115, -1219, 32142,  1965,  -120, -1241, 32116,  2018,  -125,
+	-1262, 32089,  2072,  -131, -1282, 32061,  2125,  -136, -1303, 32033,  2179,  -141, -1323, 32003,  2234,  -146,
+	-1343, 31974,  2289,  -152, -1363, 31944,  2344,  -157, -1383, 31915,  2399,  -163, -1402, 31884,  2455,  -169,
+	-1421, 31852,  2512,  -175, -1440, 31820,  2568,  -180, -1459, 31787,  2626,  -186, -1478, 31755,  2683,  -192,
+	-1496, 31722,  2741,  -199, -1515, 31689,  2799,  -205, -1533, 31654,  2858,  -211, -1550, 31619,  2917,  -218,
+	-1568, 31584,  2976,  -224, -1585, 31548,  3036,  -231, -1603, 31512,  3096,  -237, -1620, 31476,  3156,  -244,
+	-1636, 31438,  3217,  -251, -1653, 31400,  3278,  -257, -1669, 31362,  3339,  -264, -1686, 31324,  3401,  -271,
+	-1702, 31285,  3463,  -278, -1717, 31245,  3526,  -286, -1733, 31205,  3589,  -293, -1748, 31164,  3652,  -300,
+	-1764, 31124,  3715,  -307, -1779, 31083,  3779,  -315, -1793, 31040,  3843,  -322, -1808, 30998,  3908,  -330,
+	-1823, 30956,  3973,  -338, -1837, 30912,  4038,  -345, -1851, 30869,  4103,  -353, -1865, 30825,  4169,  -361,
+	-1878, 30780,  4235,  -369, -1892, 30736,  4301,  -377, -1905, 30690,  4368,  -385, -1918, 30644,  4435,  -393,
+	-1931, 30598,  4502,  -401, -1944, 30551,  4570,  -409, -1956, 30503,  4638,  -417, -1969, 30457,  4706,  -426,
+	-1981, 30408,  4775,  -434, -1993, 30359,  4844,  -442, -2005, 30311,  4913,  -451, -2017, 30262,  4982,  -459,
+	-2028, 30212,  5052,  -468, -2039, 30162,  5122,  -477, -2050, 30111,  5192,  -485, -2061, 30060,  5263,  -494,
+	-2072, 30009,  5334,  -503, -2083, 29958,  5405,  -512, -2093, 29906,  5476,  -521, -2103, 29853,  5548,  -530,
+	-2113, 29800,  5620,  -539, -2123, 29747,  5692,  -548, -2133, 29693,  5765,  -557, -2142, 29638,  5838,  -566,
+	-2152, 29584,  5911,  -575, -2161, 29529,  5984,  -584, -2170, 29474,  6058,  -594, -2179, 29419,  6131,  -603,
+	-2188, 29363,  6206,  -613, -2196, 29306,  6280,  -622, -2204, 29249,  6354,  -631, -2213, 29193,  6429,  -641,
+	-2221, 29135,  6504,  -650, -2228, 29076,  6580,  -660, -2236, 29019,  6655,  -670, -2244, 28960,  6731,  -679,
+	-2251, 28901,  6807,  -689, -2258, 28842,  6883,  -699, -2265, 28782,  6960,  -709, -2272, 28721,  7037,  -718,
+	-2279, 28661,  7114,  -728, -2285, 28600,  7191,  -738, -2292, 28540,  7268,  -748, -2298, 28478,  7346,  -758,
+	-2304, 28416,  7424,  -768, -2310, 28354,  7502,  -778, -2316, 28292,  7580,  -788, -2321, 28228,  7659,  -798,
+	-2327, 28165,  7738,  -808, -2332, 28101,  7817,  -818, -2337, 28038,  7896,  -829, -2342, 27974,  7975,  -839,
+	-2347, 27909,  8055,  -849, -2352, 27844,  8135,  -859, -2356, 27778,  8215,  -869, -2361, 27714,  8295,  -880,
+	-2365, 27648,  8375,  -890, -2369, 27581,  8456,  -900, -2373, 27516,  8536,  -911, -2377, 27449,  8617,  -921,
+	-2381, 27382,  8699,  -932, -2384, 27314,  8780,  -942, -2387, 27246,  8861,  -952, -2391, 27179,  8943,  -963,
+	-2394, 27110,  9025,  -973, -2397, 27042,  9107,  -984, -2399, 26972,  9189,  -994, -2402, 26904,  9271, -1005,
+	-2405, 26834,  9354, -1015, -2407, 26764,  9437, -1026, -2409, 26693,  9520, -1036, -2411, 26623,  9603, -1047,
+	-2413, 26553,  9686, -1058, -2415, 26482,  9769, -1068, -2417, 26411,  9853, -1079, -2419, 26340,  9936, -1089,
+	-2420, 26268, 10020, -1100, -2421, 26196, 10104, -1111, -2422, 26123, 10188, -1121, -2424, 26052, 10272, -1132,
+	-2424, 25978, 10357, -1143, -2425, 25905, 10441, -1153, -2426, 25832, 10526, -1164, -2426, 25758, 10611, -1175,
+	-2427, 25684, 10696, -1185, -2427, 25610, 10781, -1196, -2427, 25536, 10866, -1207, -2427, 25461, 10951, -1217,
+	-2427, 25386, 11037, -1228, -2427, 25312, 11122, -1239, -2427, 25236, 11208, -1249, -2426, 25160, 11294, -1260,
+	-2426, 25085, 11380, -1271, -2425, 25008, 11466, -1281, -2424, 24932, 11552, -1292, -2423, 24855, 11638, -1302,
+	-2422, 24779, 11724, -1313, -2421, 24702, 11811, -1324, -2419, 24624, 11897, -1334, -2418, 24547, 11984, -1345,
+	-2416, 24469, 12071, -1356, -2415, 24391, 12158, -1366, -2413, 24314, 12244, -1377, -2411, 24234, 12332, -1387,
+	-2409, 24156, 12419, -1398, -2407, 24077, 12506, -1408, -2405, 23999, 12593, -1419, -2402, 23918, 12681, -1429,
+	-2400, 23840, 12768, -1440, -2397, 23759, 12856, -1450, -2395, 23681, 12943, -1461, -2392, 23600, 13031, -1471,
+	-2389, 23520, 13119, -1482, -2386, 23440, 13206, -1492, -2383, 23360, 13294, -1503, -2380, 23279, 13382, -1513,
+	-2377, 23198, 13470, -1523, -2373, 23117, 13558, -1534, -2370, 23035, 13647, -1544, -2366, 22953, 13735, -1554,
+	-2362, 22872, 13823, -1565, -2359, 22791, 13911, -1575, -2355, 22708, 14000, -1585, -2351, 22626, 14088, -1595,
+	-2347, 22544, 14177, -1606, -2342, 22461, 14265, -1616, -2338, 22378, 14354, -1626, -2334, 22296, 14442, -1636,
+	-2329, 22212, 14531, -1646, -2325, 22130, 14619, -1656, -2320, 22046, 14708, -1666, -2315, 21962, 14797, -1676,
+	-2310, 21879, 14885, -1686, -2305, 21795, 14974, -1696, -2300, 21711, 15063, -1706, -2295, 21626, 15152, -1715,
+	-2290, 21542, 15241, -1725, -2284, 21458, 15329, -1735, -2279, 21374, 15418, -1745, -2274, 21289, 15507, -1754,
+	-2268, 21204, 15596, -1764, -2262, 21119, 15685, -1774, -2257, 21034, 15774, -1783, -2251, 20949, 15863, -1793,
+	-2245, 20863, 15952, -1802, -2239, 20779, 16040, -1812, -2233, 20693, 16129, -1821, -2227, 20607, 16218, -1830,
+	-2220, 20521, 16307, -1840, -2214, 20435, 16396, -1849, -2208, 20349, 16485, -1858, -2201, 20262, 16574, -1867,
+	-2195, 20177, 16662, -1876, -2188, 20091, 16751, -1886, -2181, 20004, 16840, -1895, -2174, 19917, 16929, -1904,
+	-2168, 19831, 17018, -1913, -2161, 19744, 17106, -1921, -2154, 19657, 17195, -1930, -2146, 19569, 17284, -1939,
+	-2139, 19483, 17372, -1948, -2132, 19395, 17461, -1956, -2125, 19309, 17549, -1965, -2117, 19221, 17638, -1974,
+	-2110, 19134, 17726, -1982, -2102, 19046, 17815, -1991, -2095, 18959, 17903, -1999, -2087, 18871, 17991, -2007,
+	-2079, 18783, 18080, -2016, -2072, 18696, 18168, -2024, -2064, 18608, 18256, -2032, -2056, 18520, 18344, -2040,
+	-2048, 18432, 18432, -2048, -2040, 18344, 18520, -2056, -2032, 18256, 18608, -2064, -2024, 18168, 18696, -2072,
+	-2016, 18080, 18783, -2079, -2007, 17991, 18871, -2087, -1999, 17903, 18959, -2095, -1991, 17815, 19046, -2102,
+	-1982, 17726, 19134, -2110, -1974, 17638, 19221, -2117, -1965, 17549, 19309, -2125, -1956, 17461, 19395, -2132,
+	-1948, 17372, 19483, -2139, -1939, 17284, 19569, -2146, -1930, 17195, 19657, -2154, -1921, 17106, 19744, -2161,
+	-1913, 17018, 19831, -2168, -1904, 16929, 19917, -2174, -1895, 16840, 20004, -2181, -1886, 16751, 20091, -2188,
+	-1876, 16662, 20177, -2195, -1867, 16574, 20262, -2201, -1858, 16485, 20349, -2208, -1849, 16396, 20435, -2214,
+	-1840, 16307, 20521, -2220, -1830, 16218, 20607, -2227, -1821, 16129, 20693, -2233, -1812, 16040, 20779, -2239,
+	-1802, 15952, 20863, -2245, -1793, 15863, 20949, -2251, -1783, 15774, 21034, -2257, -1774, 15685, 21119, -2262,
+	-1764, 15596, 21204, -2268, -1754, 15507, 21289, -2274, -1745, 15418, 21374, -2279, -1735, 15329, 21458, -2284,
+	-1725, 15241, 21542, -2290, -1715, 15152, 21626, -2295, -1706, 15063, 21711, -2300, -1696, 14974, 21795, -2305,
+	-1686, 14885, 21879, -2310, -1676, 14797, 21962, -2315, -1666, 14708, 22046, -2320, -1656, 14619, 22130, -2325,
+	-1646, 14531, 22212, -2329, -1636, 14442, 22296, -2334, -1626, 14354, 22378, -2338, -1616, 14265, 22461, -2342,
+	-1606, 14177, 22544, -2347, -1595, 14088, 22626, -2351, -1585, 14000, 22708, -2355, -1575, 13911, 22791, -2359,
+	-1565, 13823, 22872, -2362, -1554, 13735, 22953, -2366, -1544, 13647, 23035, -2370, -1534, 13558, 23117, -2373,
+	-1523, 13470, 23198, -2377, -1513, 13382, 23279, -2380, -1503, 13294, 23360, -2383, -1492, 13206, 23440, -2386,
+	-1482, 13119, 23520, -2389, -1471, 13031, 23600, -2392, -1461, 12943, 23681, -2395, -1450, 12856, 23759, -2397,
+	-1440, 12768, 23840, -2400, -1429, 12681, 23918, -2402, -1419, 12593, 23999, -2405, -1408, 12506, 24077, -2407,
+	-1398, 12419, 24156, -2409, -1387, 12332, 24234, -2411, -1377, 12244, 24314, -2413, -1366, 12158, 24391, -2415,
+	-1356, 12071, 24469, -2416, -1345, 11984, 24547, -2418, -1334, 11897, 24624, -2419, -1324, 11811, 24702, -2421,
+	-1313, 11724, 24779, -2422, -1302, 11638, 24855, -2423, -1292, 11552, 24932, -2424, -1281, 11466, 25008, -2425,
+	-1271, 11380, 25085, -2426, -1260, 11294, 25160, -2426, -1249, 11208, 25236, -2427, -1239, 11122, 25312, -2427,
+	-1228, 11037, 25386, -2427, -1217, 10951, 25461, -2427, -1207, 10866, 25536, -2427, -1196, 10781, 25610, -2427,
+	-1185, 10696, 25684, -2427, -1175, 10611, 25758, -2426, -1164, 10526, 25832, -2426, -1153, 10441, 25905, -2425,
+	-1143, 10357, 25978, -2424, -1132, 10272, 26052, -2424, -1121, 10188, 26123, -2422, -1111, 10104, 26196, -2421,
+	-1100, 10020, 26268, -2420, -1089,  9936, 26340, -2419, -1079,  9853, 26411, -2417, -1068,  9769, 26482, -2415,
+	-1058,  9686, 26553, -2413, -1047,  9603, 26623, -2411, -1036,  9520, 26693, -2409, -1026,  9437, 26764, -2407,
+	-1015,  9354, 26834, -2405, -1005,  9271, 26904, -2402,  -994,  9189, 26972, -2399,  -984,  9107, 27042, -2397,
+	 -973,  9025, 27110, -2394,  -963,  8943, 27179, -2391,  -952,  8861, 27246, -2387,  -942,  8780, 27314, -2384,
+	 -932,  8699, 27382, -2381,  -921,  8617, 27449, -2377,  -911,  8536, 27516, -2373,  -900,  8456, 27581, -2369,
+	 -890,  8375, 27648, -2365,  -880,  8295, 27714, -2361,  -869,  8215, 27778, -2356,  -859,  8135, 27844, -2352,
+	 -849,  8055, 27909, -2347,  -839,  7975, 27974, -2342,  -829,  7896, 28038, -2337,  -818,  7817, 28101, -2332,
+	 -808,  7738, 28165, -2327,  -798,  7659, 28228, -2321,  -788,  7580, 28292, -2316,  -778,  7502, 28354, -2310,
+	 -768,  7424, 28416, -2304,  -758,  7346, 28478, -2298,  -748,  7268, 28540, -2292,  -738,  7191, 28600, -2285,
+	 -728,  7114, 28661, -2279,  -718,  7037, 28721, -2272,  -709,  6960, 28782, -2265,  -699,  6883, 28842, -2258,
+	 -689,  6807, 28901, -2251,  -679,  6731, 28960, -2244,  -670,  6655, 29019, -2236,  -660,  6580, 29076, -2228,
+	 -650,  6504, 29135, -2221,  -641,  6429, 29193, -2213,  -631,  6354, 29249, -2204,  -622,  6280, 29306, -2196,
+	 -613,  6206, 29363, -2188,  -603,  6131, 29419, -2179,  -594,  6058, 29474, -2170,  -584,  5984, 29529, -2161,
+	 -575,  5911, 29584, -2152,  -566,  5838, 29638, -2142,  -557,  5765, 29693, -2133,  -548,  5692, 29747, -2123,
+	 -539,  5620, 29800, -2113,  -530,  5548, 29853, -2103,  -521,  5476, 29906, -2093,  -512,  5405, 29958, -2083,
+	 -503,  5334, 30009, -2072,  -494,  5263, 30060, -2061,  -485,  5192, 30111, -2050,  -477,  5122, 30162, -2039,
+	 -468,  5052, 30212, -2028,  -459,  4982, 30262, -2017,  -451,  4913, 30311, -2005,  -442,  4844, 30359, -1993,
+	 -434,  4775, 30408, -1981,  -426,  4706, 30457, -1969,  -417,  4638, 30503, -1956,  -409,  4570, 30551, -1944,
+	 -401,  4502, 30598, -1931,  -393,  4435, 30644, -1918,  -385,  4368, 30690, -1905,  -377,  4301, 30736, -1892,
+	 -369,  4235, 30780, -1878,  -361,  4169, 30825, -1865,  -353,  4103, 30869, -1851,  -345,  4038, 30912, -1837,
+	 -338,  3973, 30956, -1823,  -330,  3908, 30998, -1808,  -322,  3843, 31040, -1793,  -315,  3779, 31083, -1779,
+	 -307,  3715, 31124, -1764,  -300,  3652, 31164, -1748,  -293,  3589, 31205, -1733,  -286,  3526, 31245, -1717,
+	 -278,  3463, 31285, -1702,  -271,  3401, 31324, -1686,  -264,  3339, 31362, -1669,  -257,  3278, 31400, -1653,
+	 -251,  3217, 31438, -1636,  -244,  3156, 31476, -1620,  -237,  3096, 31512, -1603,  -231,  3036, 31548, -1585,
+	 -224,  2976, 31584, -1568,  -218,  2917, 31619, -1550,  -211,  2858, 31654, -1533,  -205,  2799, 31689, -1515,
+	 -199,  2741, 31722, -1496,  -192,  2683, 31755, -1478,  -186,  2626, 31787, -1459,  -180,  2568, 31820, -1440,
+	 -175,  2512, 31852, -1421,  -169,  2455, 31884, -1402,  -163,  2399, 31915, -1383,  -157,  2344, 31944, -1363,
+	 -152,  2289, 31974, -1343,  -146,  2234, 32003, -1323,  -141,  2179, 32033, -1303,  -136,  2125, 32061, -1282,
+	 -131,  2072, 32089, -1262,  -125,  2018, 32116, -1241,  -120,  1965, 32142, -1219,  -115,  1913, 32168, -1198,
+	 -111,  1861, 32194, -1176,  -106,  1809, 32220, -1155,  -101,  1758, 32244, -1133,   -97,  1707, 32268, -1110,
+	  -92,  1657, 32291, -1088,   -88,  1607, 32314, -1065,   -84,  1557, 32337, -1042,   -79,  1508, 32358, -1019,
+	  -75,  1459, 32380,  -996,   -71,  1411, 32400,  -972,   -67,  1363, 32420,  -948,   -64,  1315, 32441,  -924,
+	  -60,  1268, 32460,  -900,   -56,  1221, 32479,  -876,   -53,  1175, 32497,  -851,   -50,  1129, 32515,  -826,
+	  -46,  1084, 32531,  -801,   -43,  1039, 32547,  -775,   -40,   995, 32563,  -750,   -37,   951, 32578,  -724,
+	  -34,   907, 32593,  -698,   -32,   864, 32607,  -671,   -29,   821, 32621,  -645,   -26,   779, 32633,  -618,
+	  -24,   737, 32646,  -591,   -22,   696, 32658,  -564,   -20,   655, 32669,  -536,   -17,   614, 32679,  -508,
+	  -16,   575, 32690,  -481,   -14,   535, 32699,  -452,   -12,   496, 32708,  -424,   -10,   457, 32716,  -395,
+	   -9,   419, 32724,  -366,    -7,   382, 32730,  -337,    -6,   345, 32737,  -308,    -5,   308, 32743,  -278,
+	   -4,   272, 32748,  -248,    -3,   236, 32753,  -218,    -2,   201, 32757,  -188,    -2,   166, 32761,  -157,
+	   -1,   132, 32763,  -126,    -1,    98, 32766,   -95,     0,    65, 32767,   -64,     0,    32, 32767,   -32
+};
+
+#endif
--- a/src/ft2_intrp_table.h
+++ b/src/ft2_intrp_table.h
@@ -5,8 +5,18 @@
 
 #define CUBIC_WIDTH 4
 #define CUBIC_WIDTH_BITS 2
+
+#if defined __amd64__ || defined _WIN64
+
 #define CUBIC_PHASES 8192
 #define CUBIC_PHASES_BITS 13
+
+#else
+
+#define CUBIC_PHASES 512
+#define CUBIC_PHASES_BITS 9
+
+#endif
 
 #define CUBIC_FSHIFT (MIXER_FRAC_BITS-(CUBIC_PHASES_BITS+CUBIC_WIDTH_BITS))
 #define CUBIC_FMASK ((CUBIC_WIDTH*CUBIC_PHASES)-CUBIC_WIDTH)
--- a/src/ft2_main.c
+++ b/src/ft2_main.c
@@ -182,7 +182,7 @@
 		config.audioFreq = 48000;
 
 		// try 16-bit audio at 1024 samples (44.1kHz/48kHz)
-		config.specialFlags &= ~(BITDEPTH_24 + BUFFSIZE_512 + BUFFSIZE_2048);
+		config.specialFlags &= ~(BITDEPTH_32 + BUFFSIZE_512 + BUFFSIZE_2048);
 		config.specialFlags |=  (BITDEPTH_16 + BUFFSIZE_1024);
 
 		setToDefaultAudioOutputDevice();
@@ -308,6 +308,8 @@
 
 	editor.diskOpReadOnOpen = true;
 	editor.programRunning = true;
+
+	audio.linearFreqTable = true;
 }
 
 static void cleanUpAndExit(void) // never call this inside the main loop!
@@ -410,7 +412,8 @@
 	uint64_t perfFreq64;
 	double dInt, dFrac;
 
-	perfFreq64 = SDL_GetPerformanceFrequency(); assert(perfFreq64 != 0);
+	perfFreq64 = SDL_GetPerformanceFrequency();
+	assert(perfFreq64 != 0);
 	editor.dPerfFreq = (double)perfFreq64;
 	editor.dPerfFreqMulMicro = 1000000.0 / editor.dPerfFreq;
 	editor.dPerfFreqMulMs = 1.0 / (editor.dPerfFreq / 1000.0);
@@ -423,7 +426,11 @@
 
 	// fractional part scaled to 0..2^32-1
 	dFrac *= UINT32_MAX;
-	video.vblankTimeLenFrac = (uint32_t)(dFrac + 0.5);
+	dFrac += 0.5;
+	if (dFrac > UINT32_MAX)
+		dFrac = UINT32_MAX;
+
+	video.vblankTimeLenFrac = (uint32_t)dFrac;
 }
 
 #ifdef _WIN32
--- a/src/ft2_mix.c
+++ b/src/ft2_mix.c
@@ -8,8 +8,10 @@
 ** --------------------- 32-bit fixed-point audio channel mixer ---------------------
 **              (Note: Mixing macros can be found in ft2_mix_macros.h)
 **
-** 8bitbubsy: This is mostly ported from the i386-asm 32-bit mixer that was introduced in
-** FT2.08 (MS-DOS). It has been changed and improved quite a bit, though...
+** 8bitbubsy: This is mostly ported from the i386-asm 32-bit mixer that was introduced
+** in FT2.08 (MS-DOS). It has been changed and improved quite a bit, though...
+** Instead of 2-tap linear interpolation, it has 4-tap cubic spline interpolation.
+** For x86_64: Fixed-point precision is 32.32 instead of 16.16
 **
 ** This file has separate routines for EVERY possible sampling variation:
 ** Interpolation on/off, volume ramping on/off, 8-bit, 16-bit, no loop, loop, pingpong.
@@ -39,13 +41,18 @@
 	const int8_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol | CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_NO_LOOP
+		VOL0_MIXING_NO_LOOP
 		return;
 	}
 
@@ -102,13 +109,18 @@
 	const int8_t *CDA_LinearAdr, *smpPtr;;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol | CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_LOOP
+		VOL0_MIXING_LOOP
 		return;
 	}
 
@@ -165,13 +177,18 @@
 	const int8_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, delta, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos, delta;
+#else
+	uint32_t pos, delta;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol | CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_BIDI_LOOP
+		VOL0_MIXING_BIDI_LOOP
 		return;
 	}
 
@@ -229,13 +246,18 @@
 	const int8_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol | CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_NO_LOOP
+		VOL0_MIXING_NO_LOOP
 		return;
 	}
 
@@ -292,13 +314,18 @@
 	const int8_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol | CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_LOOP
+		VOL0_MIXING_LOOP
 		return;
 	}
 
@@ -355,13 +382,18 @@
 	const int8_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, delta, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos, delta;
+#else
+	uint32_t pos, delta;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol | CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_BIDI_LOOP
+		VOL0_MIXING_BIDI_LOOP
 		return;
 	}
 
@@ -420,11 +452,16 @@
 	const int8_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_NO_LOOP
+		VOL0_MIXING_NO_LOOP
 		return;
 	}
 
@@ -487,14 +524,19 @@
 
 static void mix8bRampLoop(voice_t *v, uint32_t numSamples)
 {
-	const int8_t *CDA_LinearAdr, *smpPtr;;
+	const int8_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_LOOP
+		VOL0_MIXING_LOOP
 		return;
 	}
 
@@ -560,11 +602,16 @@
 	const int8_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, delta, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos, delta;
+#else
+	uint32_t pos, delta;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_BIDI_LOOP
+		VOL0_MIXING_BIDI_LOOP
 		return;
 	}
 
@@ -632,11 +679,16 @@
 	const int8_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_NO_LOOP
+		VOL0_MIXING_NO_LOOP
 		return;
 	}
 
@@ -702,11 +754,16 @@
 	const int8_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_LOOP
+		VOL0_MIXING_LOOP
 		return;
 	}
 
@@ -772,11 +829,16 @@
 	const int8_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, delta, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos, delta;
+#else
+	uint32_t pos, delta;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_BIDI_LOOP
+		VOL0_MIXING_BIDI_LOOP
 		return;
 	}
 
@@ -849,13 +911,18 @@
 	const int16_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol | CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_NO_LOOP
+		VOL0_MIXING_NO_LOOP
 		return;
 	}
 
@@ -912,13 +979,18 @@
 	const int16_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol | CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_LOOP
+		VOL0_MIXING_LOOP
 		return;
 	}
 
@@ -975,13 +1047,18 @@
 	const int16_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, delta, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos, delta;
+#else
+	uint32_t pos, delta;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol | CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_BIDI_LOOP
+		VOL0_MIXING_BIDI_LOOP
 		return;
 	}
 
@@ -1040,13 +1117,18 @@
 	const int16_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol | CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_NO_LOOP
+		VOL0_MIXING_NO_LOOP
 		return;
 	}
 
@@ -1103,13 +1185,18 @@
 	const int16_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol| CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_LOOP
+		VOL0_MIXING_LOOP
 		return;
 	}
 
@@ -1166,13 +1253,18 @@
 	const int16_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVol, CDA_RVol;
-	uint32_t pos, delta, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos, delta;
+#else
+	uint32_t pos, delta;
+#endif
 
 	GET_VOL
 
 	if ((CDA_LVol | CDA_RVol) == 0)
 	{
-		VOL0_OPTIMIZATION_BIDI_LOOP
+		VOL0_MIXING_BIDI_LOOP
 		return;
 	}
 
@@ -1231,11 +1323,16 @@
 	const int16_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_NO_LOOP
+		VOL0_MIXING_NO_LOOP
 		return;
 	}
 
@@ -1301,11 +1398,16 @@
 	const int16_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_LOOP
+		VOL0_MIXING_LOOP
 		return;
 	}
 
@@ -1371,11 +1473,16 @@
 	const int16_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
 	int32_t realPos, sample, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, delta, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos, delta;
+#else
+	uint32_t pos, delta;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_BIDI_LOOP
+		VOL0_MIXING_BIDI_LOOP
 		return;
 	}
 
@@ -1443,11 +1550,16 @@
 	const int16_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_NO_LOOP
+		VOL0_MIXING_NO_LOOP
 		return;
 	}
 
@@ -1513,11 +1625,16 @@
 	const int16_t *CDA_LinearAdr, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos;
+#else
+	uint32_t pos;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_LOOP
+		VOL0_MIXING_LOOP
 		return;
 	}
 
@@ -1583,11 +1700,16 @@
 	const int16_t *CDA_LinearAdr, *CDA_LinAdrRev, *smpPtr;
 	int32_t realPos, sample, sample2, sample3, sample4, *audioMixL, *audioMixR;
 	int32_t CDA_LVolIP, CDA_RVolIP, CDA_LVol, CDA_RVol;
-	uint32_t pos, delta, i, samplesToMix, CDA_BytesLeft;
+	uint32_t i, samplesToMix, CDA_BytesLeft;
+#if defined _WIN64 || defined __amd64__
+	uint64_t pos, delta;
+#else
+	uint32_t pos, delta;
+#endif
 
 	if ((v->SLVol1 | v->SRVol1 | v->SLVol2 | v->SRVol2) == 0)
 	{
-		VOL0_OPTIMIZATION_BIDI_LOOP
+		VOL0_MIXING_BIDI_LOOP
 		return;
 	}
 
--- a/src/ft2_mix_macros.h
+++ b/src/ft2_mix_macros.h
@@ -15,7 +15,29 @@
 	v->SLVol2 = CDA_LVol; \
 	v->SRVol2 = CDA_RVol; \
 
+#if defined _WIN64 || defined __amd64__
+
 #define GET_MIXER_VARS \
+	const uint64_t SFrq = v->SFrq; \
+	audioMixL = audio.mixBufferL; \
+	audioMixR = audio.mixBufferR; \
+	const bool mixInMono = (CDA_LVol == CDA_RVol); \
+	realPos = v->SPos; \
+	pos = v->SPosDec; \
+
+#define GET_MIXER_VARS_RAMP \
+	const uint64_t SFrq = v->SFrq; \
+	audioMixL = audio.mixBufferL; \
+	audioMixR = audio.mixBufferR; \
+	CDA_LVolIP = v->SLVolIP; \
+	CDA_RVolIP = v->SRVolIP; \
+	const bool mixInMono = (v->SLVol2 == v->SRVol2) && (CDA_LVolIP == CDA_RVolIP); \
+	realPos = v->SPos; \
+	pos = v->SPosDec; \
+
+#else
+
+#define GET_MIXER_VARS \
 	const uint32_t SFrq = v->SFrq; \
 	audioMixL = audio.mixBufferL; \
 	audioMixR = audio.mixBufferR; \
@@ -33,6 +55,8 @@
 	realPos = v->SPos; \
 	pos = v->SPosDec; \
 
+#endif
+
 #define SET_BASE8 \
 	CDA_LinearAdr = v->SBase8; \
 	smpPtr = CDA_LinearAdr + realPos; \
@@ -176,22 +200,40 @@
 /*                      SAMPLES-TO-MIX LIMITING MACROS                     */
 /* ----------------------------------------------------------------------- */
 
-#if defined __amd64__ || defined _WIN64
+#if defined _WIN64 || defined __amd64__
 
 #define LIMIT_MIX_NUM \
-	samplesToMix = UINT32_MAX; \
+	samplesToMix = CDA_BytesLeft; \
 	i = (v->SLen - 1) - realPos; \
 	\
-	if (SFrq > i>>MIXER_FRAC_BITS) \
+	if (SFrq > 0) \
 	{ \
-		const uint64_t tmp64 = ((uint64_t)i << MIXER_FRAC_BITS) | (pos ^ MIXER_FRAC_MASK); \
-		samplesToMix = (uint32_t)(tmp64 / SFrq); \
-		samplesToMix++; \
+		uint64_t tmp64 = ((uint64_t)i << MIXER_FRAC_BITS) | (pos ^ MIXER_FRAC_MASK); \
+		samplesToMix = (uint32_t)(tmp64 / SFrq) + 1; \
+		if (samplesToMix > CDA_BytesLeft) \
+			samplesToMix = CDA_BytesLeft; \
 	} \
 	\
-	if (samplesToMix > CDA_BytesLeft) \
-		samplesToMix = CDA_BytesLeft; \
 
+#define START_BIDI \
+	if (v->backwards) \
+	{ \
+		delta = 0 - SFrq; \
+		assert(realPos >= v->SRepS && realPos < v->SLen); \
+		realPos = ~realPos; \
+		smpPtr = CDA_LinAdrRev + realPos; \
+		pos ^= MIXER_FRAC_MASK; \
+	} \
+	else \
+	{ \
+		delta = SFrq; \
+		assert(realPos >= 0 && realPos < v->SLen); \
+		smpPtr = CDA_LinearAdr + realPos; \
+	} \
+	\
+	const int32_t CDA_IPValH = (int64_t)delta >> MIXER_FRAC_BITS; \
+	const uint32_t CDA_IPValL = delta & MIXER_FRAC_MASK; \
+
 #else
 
 #define LIMIT_MIX_NUM \
@@ -206,6 +248,25 @@
 	if (samplesToMix > CDA_BytesLeft) \
 		samplesToMix = CDA_BytesLeft; \
 
+#define START_BIDI \
+	if (v->backwards) \
+	{ \
+		delta = 0 - SFrq; \
+		assert(realPos >= v->SRepS && realPos < v->SLen); \
+		realPos = ~realPos; \
+		smpPtr = CDA_LinAdrRev + realPos; \
+		pos ^= MIXER_FRAC_MASK; \
+	} \
+	else \
+	{ \
+		delta = SFrq; \
+		assert(realPos >= 0 && realPos < v->SLen); \
+		smpPtr = CDA_LinearAdr + realPos; \
+	} \
+	\
+	const int32_t CDA_IPValH = (int32_t)delta >> MIXER_FRAC_BITS; \
+	const uint32_t CDA_IPValL = delta & MIXER_FRAC_MASK; \
+
 #endif
 
 #define LIMIT_MIX_NUM_RAMP \
@@ -249,25 +310,6 @@
 		v->backwards ^= 1; \
 	} \
 
-#define START_BIDI \
-	if (v->backwards) \
-	{ \
-		delta = 0 - SFrq; \
-		assert(realPos >= v->SRepS && realPos < v->SLen); \
-		realPos = ~realPos; \
-		smpPtr = CDA_LinAdrRev + realPos; \
-		pos ^= MIXER_FRAC_MASK; \
-	} \
-	else \
-	{ \
-		delta = SFrq; \
-		assert(realPos >= 0 && realPos < v->SLen); \
-		smpPtr = CDA_LinearAdr + realPos; \
-	} \
-	\
-	const int32_t CDA_IPValH = (int32_t)delta >> MIXER_FRAC_BITS; \
-	const int32_t CDA_IPValL = delta & MIXER_FRAC_MASK; \
-
 #define END_BIDI \
 	if (v->backwards) \
 	{ \
@@ -281,19 +323,22 @@
 	\
 
 /* ----------------------------------------------------------------------- */
-/*                       VOLUME=0 OPTIMIZATION MACROS                      */
+/*                          VOLUME=0 MIXING MACROS                         */
 /* ----------------------------------------------------------------------- */
 
+
+#if defined _WIN64 || defined __amd64__
+
 #define	VOL0_INC_POS \
-	const uint64_t newPos = (uint64_t)v->SFrq * numSamples; \
+	const uint64_t newPos = v->SFrq * (uint64_t)numSamples; \
 	const uint32_t addPos = (uint32_t)(newPos >> MIXER_FRAC_BITS); \
-	uint32_t addFrac = (uint32_t)(newPos & MIXER_FRAC_MASK); \
+	uint64_t addFrac = newPos & MIXER_FRAC_MASK; \
 	\
 	addFrac += v->SPosDec; \
-	realPos = v->SPos + addPos + (addFrac >> MIXER_FRAC_BITS); \
+	realPos = v->SPos + addPos + (uint32_t)(addFrac >> MIXER_FRAC_BITS); \
 	pos = addFrac & MIXER_FRAC_MASK; \
 
-#define VOL0_OPTIMIZATION_NO_LOOP \
+#define VOL0_MIXING_NO_LOOP \
 	VOL0_INC_POS \
 	if (realPos >= v->SLen) \
 	{ \
@@ -303,14 +348,67 @@
 	\
 	SET_BACK_MIXER_POS
 
-#define VOL0_OPTIMIZATION_LOOP \
+#define VOL0_MIXING_LOOP \
 	VOL0_INC_POS \
+	if (realPos >= v->SLen) \
+	{ \
+		if (v->SRepL >= 2) \
+			realPos = v->SRepS + ((realPos - v->SLen) % v->SRepL); \
+		else \
+			realPos = v->SRepS; \
+	} \
+	\
+	SET_BACK_MIXER_POS
+
+#define VOL0_MIXING_BIDI_LOOP \
+	VOL0_INC_POS \
+	if (realPos >= v->SLen) \
+	{ \
+		if (v->SRepL >= 2) \
+		{ \
+			const int32_t overflow = realPos - v->SLen; \
+			const int32_t cycles = overflow / v->SRepL; \
+			const int32_t phase = overflow % v->SRepL; \
+			\
+			realPos = v->SRepS + phase; \
+			v->backwards ^= !(cycles & 1); \
+		} \
+		else \
+		{ \
+			realPos = v->SRepS; \
+		} \
+	} \
+	\
+	SET_BACK_MIXER_POS
+
+#else
+
+#define	VOL0_INC_POS \
+	assert(numSamples <= 65536); \
+	\
+	pos = v->SPosDec + ((v->SFrq & 0xFFFF) * numSamples); \
+	realPos = v->SPos + ((v->SFrq >> 16) * numSamples) + (pos >> 16); \
+	pos &= 0xFFFF; \
+
+#define VOL0_MIXING_NO_LOOP \
+	VOL0_INC_POS \
+	if (realPos >= v->SLen) \
+	{ \
+		v->mixRoutine = NULL; /* shut down voice */ \
+		return; \
+	} \
+	\
+	SET_BACK_MIXER_POS
+
+#define VOL0_MIXING_LOOP \
+	VOL0_INC_POS \
+	\
 	while (realPos >= v->SLen) \
 		realPos -= v->SRepL; \
 	\
 	SET_BACK_MIXER_POS
 
-#define VOL0_OPTIMIZATION_BIDI_LOOP \
+#define VOL0_MIXING_BIDI_LOOP \
 	VOL0_INC_POS \
 	while (realPos >= v->SLen) \
 	{ \
@@ -319,3 +417,5 @@
 	} \
 	\
 	SET_BACK_MIXER_POS
+
+#endif
--- a/src/ft2_module_loader.c
+++ b/src/ft2_module_loader.c
@@ -1747,14 +1747,13 @@
 	songTmp.len = h.len;
 	songTmp.repS = h.repS;
 	songTmp.antChn = (uint8_t)h.antChn;
-	songTmp.speed = h.defSpeed ? h.defSpeed : 125;
-	songTmp.tempo = h.defTempo ? h.defTempo : 6;
+	songTmp.speed = h.defSpeed;
+	songTmp.tempo = h.defTempo;
 	songTmp.ver = h.ver;
 	linearFreqTable = h.flags & 1;
 
 	songTmp.speed = CLAMP(songTmp.speed, 32, 255);
-	if (songTmp.tempo > 31)
-		songTmp.tempo = 31;
+	songTmp.tempo = CLAMP(songTmp.tempo, 1, 31);
 
 	songTmp.initialTempo = songTmp.tempo;
 
@@ -2463,8 +2462,7 @@
 	resetWavRenderer();
 	clearPattMark();
 	resetTrimSizes();
-
-	song.musicTime = 0;
+	resetPlaybackTime();
 
 	diskOpSetFilename(DISKOP_ITEM_MODULE, editor.tmpFilenameU);
 
--- a/src/ft2_module_saver.c
+++ b/src/ft2_module_saver.c
@@ -84,7 +84,7 @@
 		ai--;
 	h.antInstrs = ai;
 
-	h.flags = linearFrqTab;
+	h.flags = audio.linearFreqTable;
 	memcpy(h.songTab, song.songTab, sizeof (song.songTab));
 
 	if (fwrite(&h, sizeof (h), 1, f) != 1)
@@ -278,7 +278,7 @@
 	incompatEfx = false;
 	noteUnderflow = false;
 
-	if (linearFrqTab)
+	if (audio.linearFreqTable)
 		okBoxThreadSafe(0, "System message", "Linear frequency table used!");
 
 	// sanity checking
--- a/src/ft2_nibbles.c
+++ b/src/ft2_nibbles.c
@@ -9,6 +9,7 @@
 #include "ft2_gui.h"
 #include "ft2_pattern_ed.h"
 #include "ft2_bmp.h"
+#include "ft2_tables.h"
 
 #define NI_MAXLEVEL 30
 
@@ -366,21 +367,15 @@
 
 static void drawScoresLives(void)
 {
-	char str[8];
-
 	// player 1
+	assert(NI_P1Lives < 100);
 	hexOutBg(89, 27, PAL_FORGRND, PAL_DESKTOP, NI_P1Score, 8);
+	textOutFixed(131, 39, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[NI_P1Lives]);
 
-	assert(NI_P1Lives < 100);
-	sprintf(str, "%02d", NI_P1Lives);
-	textOutFixed(131, 39, PAL_FORGRND, PAL_DESKTOP, str);
-
 	// player 2
-	hexOutBg(89, 75, PAL_FORGRND, PAL_DESKTOP, NI_P2Score, 8);
-
 	assert(NI_P2Lives < 100);
-	sprintf(str, "%02d", NI_P2Lives);
-	textOutFixed(131, 87, PAL_FORGRND, PAL_DESKTOP, str);
+	hexOutBg(89, 75, PAL_FORGRND, PAL_DESKTOP, NI_P2Score, 8);
+	textOutFixed(131, 87, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[NI_P2Lives]);
 }
 
 static void nibblesDecLives(int16_t l1, int16_t l2)
--- a/src/ft2_pattern_ed.c
+++ b/src/ft2_pattern_ed.c
@@ -37,6 +37,7 @@
 static const uint16_t iSwitchExtX[4] = { 221, 262, 303, 344 };
 
 static int32_t lastMouseX, lastMouseY;
+static int32_t last_TimeH, last_TimeM, last_TimeS;
 
 bool allocatePattern(uint16_t nr) // for tracker use only, not in loader!
 {
@@ -1679,7 +1680,7 @@
 {
 	bool audioWasntLocked;
 
-	if (song.len == 0)
+	if (song.len <= 1)
 		return;
 
 	audioWasntLocked = !audio.locked;
@@ -2181,24 +2182,20 @@
 
 void drawSongBPM(uint16_t val)
 {
-	char str[8];
-
 	if (editor.ui.extended)
 		return;
 
-	sprintf(str, "%03d", val);
-	textOutFixed(145, 36, PAL_FORGRND, PAL_DESKTOP, str);
+	assert(val < 256);
+	textOutFixed(145, 36, PAL_FORGRND, PAL_DESKTOP, dec3StrTab[val]);
 }
 
 void drawSongSpeed(uint16_t val)
 {
-	char str[8];
-
 	if (editor.ui.extended)
 		return;
 
-	sprintf(str, "%02d", val);
-	textOutFixed(152, 50, PAL_FORGRND, PAL_DESKTOP, str);
+	assert(val < 32);
+	textOutFixed(152, 50, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[val]);
 }
 
 void drawEditPattern(uint16_t editPattern)
@@ -2237,55 +2234,43 @@
 	hexOutBg(x, y, PAL_FORGRND, PAL_DESKTOP, pattLens[editPattern], 3);
 }
 
-void drawGlobalVol(int16_t globalVol)
+void drawGlobalVol(uint16_t val)
 {
-	char str[8];
-
 	if (editor.ui.extended)
 		return;
 
-	assert(globalVol >= 0 && globalVol <= 64);
-	sprintf(str, "%02d", globalVol);
-	textOutFixed(87, 80, PAL_FORGRND, PAL_DESKTOP, str);
+	assert(val <= 64);
+	textOutFixed(87, 80, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[val]);
 }
 
 void drawIDAdd(void)
 {
-	char str[8];
-
 	assert(editor.ID_Add <= 16);
-	sprintf(str, "%02d", editor.ID_Add);
-	textOutFixed(152, 64, PAL_FORGRND, PAL_DESKTOP, str);
+	textOutFixed(152, 64, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[editor.ID_Add]);
 }
 
+void resetPlaybackTime(void)
+{
+	song.musicTime64 = 0;
+	last_TimeH = 0;
+	last_TimeM = 0;
+	last_TimeS = 0;
+}
+
 void drawPlaybackTime(void)
 {
-	char str[2 + 1];
-	uint32_t a, MI_TimeH, MI_TimeM, MI_TimeS;
+	if (songPlaying)
+	{
+		uint32_t seconds = song.musicTime64 >> 32;
 
-	a = ((song.musicTime >> 8) * 5) >> 9;
-	MI_TimeH = a / 3600;
-	a -= (MI_TimeH * 3600);
-	MI_TimeM = a / 60;
-	MI_TimeS = a - (MI_TimeM * 60);
+		last_TimeH = seconds / 3600; seconds -= last_TimeH * 3600;
+		last_TimeM = seconds / 60;   seconds -= last_TimeM * 60;
+		last_TimeS = seconds;
+	}
 
-	// hours
-	str[0] = '0' + (char)(MI_TimeH / 10);
-	str[1] = '0' + (char)(MI_TimeH % 10);
-	str[2] = '\0';
-	textOutFixed(235, 80, PAL_FORGRND, PAL_DESKTOP, str);
-
-	// minutes
-	str[0] = '0' + (char)(MI_TimeM / 10);
-	str[1] = '0' + (char)(MI_TimeM % 10);
-	str[2] = '\0';
-	textOutFixed(255, 80, PAL_FORGRND, PAL_DESKTOP, str);
-
-	// seconds
-	str[0] = '0' + (char)(MI_TimeS / 10);
-	str[1] = '0' + (char)(MI_TimeS % 10);
-	str[2] = '\0';
-	textOutFixed(275, 80, PAL_FORGRND, PAL_DESKTOP, str);
+	textOutFixed(235, 80, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[last_TimeH]);
+	textOutFixed(255, 80, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[last_TimeM]);
+	textOutFixed(275, 80, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[last_TimeS]);
 }
 
 void drawSongName(void)
@@ -2716,10 +2701,10 @@
 	editor.globalVol = song.globVol;
 	editor.timer = 1;
 
-	if (songPlaying)
-		song.musicTime = 0;
+	resetPlaybackTime();
 
-	setFrqTab(true);
+	if (!audio.linearFreqTable)
+		setFrqTab(true);
 
 	clearPattMark();
 	resetWavRenderer();
--- a/src/ft2_pattern_ed.h
+++ b/src/ft2_pattern_ed.h
@@ -57,6 +57,8 @@
 	int16_t markX1, markX2, markY1, markY2;
 } pattMark;
 
+void resetPlaybackTime(void);
+
 bool allocatePattern(uint16_t nr);
 void killPatternIfUnused(uint16_t nr);
 uint8_t getMaxVisibleChannels(void);
@@ -133,7 +135,7 @@
 void drawSongSpeed(uint16_t val);
 void drawEditPattern(uint16_t editPattern);
 void drawPatternLength(uint16_t editPattern);
-void drawGlobalVol(int16_t globalVol);
+void drawGlobalVol(uint16_t val);
 void drawIDAdd(void);
 void drawPlaybackTime(void);
 void drawSongName(void);
--- a/src/ft2_pushbuttons.c
+++ b/src/ft2_pushbuttons.c
@@ -335,15 +335,15 @@
 
 	// ------ CONFIG MISCELLANEOUS PUSHBUTTONS ------
 	//x,   y,   w,  h,  p, d, text #1,                         text #2, funcOnDown,          funcOnUp
-	{ 113, 155, 93, 16, 0, 0, editor.ui.fullscreenButtonText, NULL,    NULL,                toggleFullScreen },
-	{ 370, 121, 18, 13, 1, 4, ARROW_UP_STRING,                NULL,    configQuantizeUp,    NULL },
-	{ 387, 121, 18, 13, 1, 4, ARROW_DOWN_STRING,              NULL,    configQuantizeDown,  NULL },
-	{ 594, 106, 18, 13, 1, 4, ARROW_UP_STRING,                NULL,    configMIDIChnUp,     NULL },
-	{ 611, 106, 18, 13, 1, 4, ARROW_DOWN_STRING,              NULL,    configMIDIChnDown,   NULL },
-	{ 594, 120, 18, 13, 1, 4, ARROW_UP_STRING,                NULL,    configMIDITransUp,   NULL },
-	{ 611, 120, 18, 13, 1, 4, ARROW_DOWN_STRING,              NULL,    configMIDITransDown, NULL },
-	{ 556, 158, 22, 13, 1, 4, ARROW_LEFT_STRING,              NULL,    configMIDISensDown,  NULL },
-	{ 607, 158, 22, 13, 1, 4, ARROW_RIGHT_STRING,             NULL,    configMIDISensUp,    NULL },
+	{ 113, 155, 93, 16, 0, 0, editor.ui.fullscreenButtonText,  NULL,    NULL,                toggleFullScreen },
+	{ 370, 121, 18, 13, 1, 4, ARROW_UP_STRING,                 NULL,    configQuantizeUp,    NULL },
+	{ 387, 121, 18, 13, 1, 4, ARROW_DOWN_STRING,               NULL,    configQuantizeDown,  NULL },
+	{ 594, 106, 18, 13, 1, 4, ARROW_UP_STRING,                 NULL,    configMIDIChnUp,     NULL },
+	{ 611, 106, 18, 13, 1, 4, ARROW_DOWN_STRING,               NULL,    configMIDIChnDown,   NULL },
+	{ 594, 120, 18, 13, 1, 4, ARROW_UP_STRING,                 NULL,    configMIDITransUp,   NULL },
+	{ 611, 120, 18, 13, 1, 4, ARROW_DOWN_STRING,               NULL,    configMIDITransDown, NULL },
+	{ 556, 158, 22, 13, 1, 4, ARROW_LEFT_STRING,               NULL,    configMIDISensDown,  NULL },
+	{ 607, 158, 22, 13, 1, 4, ARROW_RIGHT_STRING,              NULL,    configMIDISensUp,    NULL },
 
 #ifdef HAS_MIDI
 	// ------ CONFIG MIDI PUSHBUTTONS ------
@@ -357,7 +357,7 @@
 	{  70,   2, 58, 16, 0, 0, "Save",            NULL,    NULL,             pbDiskOpSave },
 	{  70,  19, 58, 16, 0, 0, "Delete",          NULL,    NULL,             pbDiskOpDelete },
 	{  70,  36, 58, 16, 0, 0, "Rename",          NULL,    NULL,             pbDiskOpRename },
-	{  70,  53, 58, 16, 0, 0, "Make dir.",        NULL,    NULL,             pbDiskOpMakeDir },
+	{  70,  53, 58, 16, 0, 0, "Make dir.",       NULL,    NULL,             pbDiskOpMakeDir },
 	{  70,  70, 58, 16, 0, 0, "Refresh",         NULL,    NULL,             pbDiskOpRefresh },
 	{  70,  87, 58, 16, 0, 0, "Set path",        NULL,    NULL,             pbDiskOpSetPath },
 	{  70, 104, 58, 16, 0, 0, "Show all",        NULL,    NULL,             pbDiskOpShowAll },
--- a/src/ft2_radiobuttons.c
+++ b/src/ft2_radiobuttons.c
@@ -87,8 +87,10 @@
 	//x,   y,   w,  group,                      funcOnUp
 	{ 509, 16,  66, RB_GROUP_CONFIG_AUDIO_FREQ, rbConfigAudio44kHz },
 	{ 509, 30, 121, RB_GROUP_CONFIG_AUDIO_FREQ, rbConfigAudio48kHz },
+#if defined __amd64__ || defined _WIN64
 	{ 509, 44,  66, RB_GROUP_CONFIG_AUDIO_FREQ, rbConfigAudio96kHz },
-
+	{ 509, 58,  73, RB_GROUP_CONFIG_AUDIO_FREQ, rbConfigAudio192kHz },
+#endif
 	// audio input frequency
 	//x,   y,  w,   group,                            funcOnUp
 	{ 180, 156, 60, RB_GROUP_CONFIG_AUDIO_INPUT_FREQ, rbConfigAudioInput44kHz },
--- a/src/ft2_radiobuttons.h
+++ b/src/ft2_radiobuttons.h
@@ -57,7 +57,10 @@
 	// AUDIO FREQUENCY
 	RB_CONFIG_AUDIO_44KHZ,
 	RB_CONFIG_AUDIO_48KHZ,
+#if defined __amd64__ || defined _WIN64
 	RB_CONFIG_AUDIO_96KHZ,
+	RB_CONFIG_AUDIO_192KHZ,
+#endif
 
 	// AUDIO INPUT FREQUENCY
 	RB_CONFIG_AUDIO_INPUT_44KHZ,
--- a/src/ft2_replayer.c
+++ b/src/ft2_replayer.c
@@ -22,21 +22,30 @@
 
 /* This is a *huge* mess, directly ported from the original FT2 code (and modified).
 ** You will experience a lot of headaches if you dig into it...
-** If something looks to be off, it's probably not!
+** If something looks to be off, it probably isn't!
 */
 
+/* Tables for pre-calculated stuff on run time and when changing freq. and/or linear/amiga mode.
+** FT2 obviously didn't have such big tables.
+*/
+
+static uint32_t musicTimeTab[256-32];
+static uint64_t period2ScopeDeltaTab[65536], scopeLogTab[768], scopeAmigaPeriodDiv;
+#if defined _WIN64 || defined __amd64__
+static uint64_t period2DeltaTab[65536], logTab[768], amigaPeriodDiv;
+#else
+static uint32_t period2DeltaTab[65536], logTab[768], amigaPeriodDiv;
+#endif
+
 static bool bxxOverflow;
-static int32_t oldPeriod;
-static uint32_t period2DeltaTab[768][32], oldDelta;
-static double dAmigaPeriodDiv;
 static tonTyp nilPatternLine;
 
 // globally accessed
 
 int8_t playMode = 0;
-bool linearFrqTab = false, songPlaying = false, audioPaused = false, musicPaused = false;
+bool songPlaying = false, audioPaused = false, musicPaused = false;
 volatile bool replayerBusy = false;
-const int16_t *note2Period = NULL;
+const uint16_t *note2Period = NULL;
 int16_t pattLens[MAX_PATTERNS];
 stmTyp stm[MAX_VOICES];
 songTyp song;
@@ -43,8 +52,6 @@
 instrTyp *instr[132];
 tonTyp *patt[MAX_PATTERNS];
 
-// CODE START
-
 void fixSongName(void) // removes spaces from right side of song name
 {
 	for (int16_t i = 20; i >= 0; i--)
@@ -216,23 +223,76 @@
 	return i+1;
 }
 
-void setFrqTab(bool linear)
+// called every time you change linear/amiga mode and mixing frequency
+static void calcDelta2PeriodTabs(void)
 {
-	linearFrqTab = linear;
+	int32_t baseDelta;
+	uint32_t i;
 
-	if (linearFrqTab)
+	period2DeltaTab[0] = 0; // FT2 converts period 0 to a delta of 0
+
+	if (audio.linearFreqTable)
 	{
-		audio.linearFreqTable = true;
-		note2Period = linearPeriods;
+		for (i = 1; i < 65536; i++)
+		{
+			const uint16_t invPeriod = (12 * 192 * 4) - (uint16_t)i; // this intentionally overflows uint16_t to be accurate to FT2
+			const int32_t octave = invPeriod / 768;
+			const int32_t period = invPeriod % 768;
+			const int32_t shift = (14 - octave) & 0x1F; // this is exactly how FT2 does it
+
+#if defined _WIN64 || defined __amd64__
+			uint64_t delta = logTab[period];
+#else
+			uint32_t delta = logTab[period];
+#endif
+			uint64_t scopeDelta = scopeLogTab[period];
+
+			if (shift > 0)
+			{
+				delta >>= shift;
+				scopeDelta >>= shift;
+			}
+
+			period2DeltaTab[i] = delta;
+			period2ScopeDeltaTab[i] = scopeDelta;
+		}
 	}
 	else
 	{
-		audio.linearFreqTable = false;
-		note2Period = amigaPeriods;
+		// Note: these calculations should remain truncated and not rounded!
+		for (i = 1; i < 65536; i++)
+		{
+			period2DeltaTab[i] = amigaPeriodDiv / i;
+			period2ScopeDeltaTab[i] = scopeAmigaPeriodDiv / i;
+		}
 	}
 
-	resetCachedFrequencyVars();
+	// for piano in Instr. Ed.
 
+	// (this delta is small enough to fit in int32_t even with 32.32 deltas)
+	if (audio.linearFreqTable)
+		baseDelta = (int32_t)period2DeltaTab[7680];
+	else
+		baseDelta = (int32_t)period2DeltaTab[1712*16];
+
+	audio.dPianoDeltaMul = 1.0 / baseDelta;
+}
+
+void setFrqTab(bool linear)
+{
+	pauseAudio();
+
+	audio.linearFreqTable = linear;
+
+	if (audio.linearFreqTable)
+		note2Period = linearPeriods;
+	else
+		note2Period = amigaPeriods;
+
+	calcDelta2PeriodTabs();
+
+	resumeAudio();
+
 	// update "frequency table" radiobutton, if it's shown
 	if (editor.ui.configScreenShown && editor.currConfigScreen == CONFIG_SCREEN_IO_DEVICES)
 		setConfigIORadioButtonStates();
@@ -323,76 +383,84 @@
 
 void calcReplayRate(int32_t rate)
 {
+	int32_t i;
+
 	if (rate == 0)
 		return;
 
-	const double dRateFactor = (double)MIXER_FRAC_SCALE / rate;
+	const double dScopeRateFactor = SCOPE_FRAC_SCALE / (double)SCOPE_HZ;
+	const double dAudioRateFactor = MIXER_FRAC_SCALE / (double)rate;
 
-	// generate period-to-delta table
-	const double dMul = dRateFactor * (8363.0 * 256.0);
-	for (int32_t i = 0; i < 768; i++)
+	scopeAmigaPeriodDiv = (uint64_t)(((8363.0 * 1712.0) * dScopeRateFactor) + 0.5);
+
+#if defined _WIN64 || defined __amd64__
+	amigaPeriodDiv = (uint64_t)(((8363.0 * 1712.0) * dAudioRateFactor) + 0.5);
+	for (i = 0; i < 768; i++)
 	{
-		const double dDelta = exp2(i * (1.0 / 768.0)) * dMul;
-		for (int32_t j = 0; j < 32; j++)
-		{
-			const double dOut = dDelta * exp2(-j);
-			period2DeltaTab[i][j] = (int32_t)(dOut + 0.5);
-		}
+		double dHz = exp2(i * (1.0 / 768.0)) * (8363.0 * 256.0);
+		logTab[i] = (uint64_t)((dHz * dAudioRateFactor) + 0.5);
+		scopeLogTab[i] = (uint64_t)((dHz * dScopeRateFactor) + 0.5);
 	}
+#else
+	amigaPeriodDiv = (uint32_t)(((8363 * 1712) * dAudioRateFactor) + 0.5);
+	for (i = 0; i < 768; i++)
+	{
+		double dHz = exp2(i * (1.0 / 768.0)) * (8363.0 * 256.0);
+		logTab[i] = (uint32_t)((dHz * dAudioRateFactor) + 0.5);
+		scopeLogTab[i] = (uint64_t)((dHz * dScopeRateFactor) + 0.5);
+	}
+#endif
 
-	dAmigaPeriodDiv = dRateFactor * (8363.0 * 1712.0);
-
 	audio.quickVolSizeVal = rate / 200; // FT2 truncates here
-	audio.rampQuickVolMul = (int32_t)round((UINT32_MAX + 1.0) / audio.quickVolSizeVal);
+	audio.rampQuickVolMul = (int32_t)(((UINT32_MAX + 1.0) / audio.quickVolSizeVal) + 0.5);
 	audio.dSpeedValMul = editor.dPerfFreq / rate; // for audio/video sync
 
-	// exact integer fixed-point delta base for piano in Instr. Ed.
-	int32_t deltaBase = (int32_t)round(dAmigaPeriodDiv / (1712 * 16));
-	audio.dPianoDeltaMul = 1.0 / deltaBase;
+	// calculate table used to count replayer time (displayed as hours/minutes/seconds)
+	const double dMul = (UINT32_MAX + 1.0) / rate;
+	for (i = 32; i < 256; i++)
+	{
+		uint32_t samplesPerTick = ((rate + rate) + (rate >> 1)) / i; // exactly how setSpeed() calculates it
+		const double dVal = samplesPerTick * dMul;
+		musicTimeTab[i-32] = (int32_t)(dVal + 0.5);
+	}
+
+	calcDelta2PeriodTabs();
 }
 
+#if defined _WIN64 || defined __amd64__
+uint64_t getFrequenceValue(uint16_t period)
+{
+	return period2DeltaTab[period];
+}
+#else
 uint32_t getFrequenceValue(uint16_t period)
 {
-	uint32_t delta;
+	return period2DeltaTab[period];
+}
+#endif
 
-	if (period == 0)
-		return 0;
+int32_t getPianoKey(uint16_t period, int32_t finetune, int32_t relativeNote) // for piano in Instr. Ed.
+{
+#if defined _WIN64 || defined __amd64__
+	uint64_t delta = period2DeltaTab[period];
+#else
+	uint32_t delta = period2DeltaTab[period];
+#endif
 
-	if (period == oldPeriod)
-		return oldDelta; // we have already calculated this delta
+	finetune >>= 3; // FT2 does this in the replayer internally, so the actual range is -16..15
 
-	if (linearFrqTab)
-	{
-		const uint16_t invPeriod = (12 * 192 * 4) - period; // this intentionally overflows uint16_t to be accurate to FT2
+	const double dNote = (log2(delta * audio.dPianoDeltaMul) * 12.0) - (finetune * (1.0 / 16.0));
+	int32_t note = (int32_t)(dNote + 0.5);
 
-		const int32_t quotient = invPeriod / 768;
-		const int32_t remainder = invPeriod % 768;
-		
-		const int32_t octave = (14 - quotient) & 0x1F; // this is accurate to FT2 (it can go crazy on very high periods)
+	note -= relativeNote;
 
-		delta = period2DeltaTab[remainder][octave];
-	}
-	else
-	{
-		const double dHz = dAmigaPeriodDiv / period;
-		delta = (int32_t)(dHz + 0.5); // rounded (don't cast to uint32_t as it will avoid SSE2 usage, and delta is <= 2^31 anyway)
-	}
-
-	oldPeriod = period;
-	oldDelta = delta;
-
-	return delta;
+	// "note" is now the raw piano key number, unaffected by finetune/relativeNote
+	return note;
 }
 
-void resetCachedFrequencyVars(void)
+uint64_t getScopeFrequenceValue(uint16_t period)
 {
-	oldPeriod = -1;
-	oldDelta = 0;
-
-	resetCachedScopeVars();
-#if !defined __amd64__ && !defined _WIN64
-	resetCachedMixerVars();
-#endif
+	return period2ScopeDeltaTab[period];
 }
 
 static void startTone(uint8_t ton, uint8_t effTyp, uint8_t eff, stmTyp *ch)
@@ -466,7 +534,7 @@
 		if (eff)
 			ch->smpOffset = ch->eff;
 
-		ch->smpStartPos = ch->smpOffset * 256;
+		ch->smpStartPos = ch->smpOffset << 8;
 	}
 	else
 	{
@@ -577,21 +645,18 @@
 				{
 					ch->pattPos = song.pattPos & 0x00FF;
 				}
-				else
+				else if (ch->loopCnt == 0)
 				{
-					if (ch->loopCnt == 0)
-					{
-						ch->loopCnt = ch->eff & 0x0F;
+					ch->loopCnt = ch->eff & 0x0F;
 
-						song.pBreakPos = ch->pattPos;
-						song.pBreakFlag = true;
-					}
-					else if (--ch->loopCnt > 0)
-					{
-						song.pBreakPos = ch->pattPos;
-						song.pBreakFlag = true;
-					}
+					song.pBreakPos = ch->pattPos;
+					song.pBreakFlag = true;
 				}
+				else if (--ch->loopCnt > 0)
+				{
+					song.pBreakPos = ch->pattPos;
+					song.pBreakFlag = true;
+				}
 			}
 
 			// EEx - pattern delay
@@ -613,8 +678,8 @@
 
 			ch->fPortaUpSpeed = tmpEff;
 
-			ch->realPeriod -= (tmpEff * 4);
-			if (ch->realPeriod < 1)
+			ch->realPeriod -= tmpEff << 2;
+			if ((int16_t)ch->realPeriod < 1)
 				ch->realPeriod = 1;
 
 			ch->outPeriod = ch->realPeriod;
@@ -630,9 +695,9 @@
 
 			ch->fPortaDownSpeed = tmpEff;
 
-			ch->realPeriod += (tmpEff * 4);
-			if (ch->realPeriod > (32000 - 1))
-				ch->realPeriod =  32000 - 1;
+			ch->realPeriod += tmpEff << 2;
+			if ((int16_t)ch->realPeriod > 32000-1)
+				ch->realPeriod = 32000-1;
 
 			ch->outPeriod = ch->realPeriod;
 			ch->status |= IS_Period;
@@ -653,24 +718,18 @@
 			{
 				ch->pattPos = song.pattPos & 0xFF;
 			}
-			else
+			else if (ch->loopCnt == 0)
 			{
-				if (ch->loopCnt == 0)
-				{
-					ch->loopCnt = ch->eff & 0x0F;
+				ch->loopCnt = ch->eff & 0x0F;
 
-					song.pBreakPos = ch->pattPos;
-					song.pBreakFlag = true;
-				}
-				else
-				{
-					if (--ch->loopCnt > 0)
-					{
-						song.pBreakPos = ch->pattPos;
-						song.pBreakFlag = true;
-					}
-				}
+				song.pBreakPos = ch->pattPos;
+				song.pBreakFlag = true;
 			}
+			else if (--ch->loopCnt > 0)
+			{
+				song.pBreakPos = ch->pattPos;
+				song.pBreakFlag = true;
+			}
 		}
 
 		// E7x - set tremolo waveform
@@ -685,10 +744,8 @@
 
 			ch->fVolSlideUpSpeed = tmpEff;
 
-			// unsigned clamp
-			if (ch->realVol <= (64 - tmpEff))
-				ch->realVol += tmpEff;
-			else
+			ch->realVol += tmpEff;
+			if (ch->realVol > 64)
 				ch->realVol = 64;
 
 			ch->outVol = ch->realVol;
@@ -704,10 +761,8 @@
 
 			ch->fVolSlideDownSpeed = tmpEff;
 
-			// unsigned clamp
-			if (ch->realVol >= tmpEff)
-				ch->realVol -= tmpEff;
-			else
+			ch->realVol -= tmpEff;
+			if ((int8_t)ch->realVol < 0)
 				ch->realVol = 0;
 
 			ch->outVol = ch->realVol;
@@ -743,8 +798,7 @@
 		}
 		else
 		{
-			song.tempo = ch->eff;
-			song.timer = ch->eff;
+			song.timer = song.tempo = ch->eff;
 		}
 	}
 
@@ -898,7 +952,9 @@
 {
 	uint8_t tmpEff, tmpEffHi, volKol;
 
-	// this one is manipulated by vol column effects, then used for multiretrig (FT2 quirk)
+	/* This one is manipulated by vol column effects,
+	** then used for multiretrig vol testing (FT2 quirk).
+	*/
 	volKol = ch->volKolVol;
 
 	// *** VOLUME COLUMN EFFECTS (TICK 0) ***
@@ -919,13 +975,11 @@
 	{
 		volKol = ch->volKolVol & 0x0F;
 
-		// unsigned clamp
-		if (ch->realVol >= volKol)
-			ch->realVol -= volKol;
-		else
+		ch->realVol -= volKol;
+		if ((int8_t)ch->realVol < 0)
 			ch->realVol = 0;
 
-		ch->outVol  = ch->realVol;
+		ch->outVol = ch->realVol;
 		ch->status |= IS_Vol;
 	}
 
@@ -934,13 +988,11 @@
 	{
 		volKol = ch->volKolVol & 0x0F;
 
-		// unsigned clamp
-		if (ch->realVol <= 64-volKol)
-			ch->realVol += volKol;
-		else
+		ch->realVol += volKol;
+		if (ch->realVol > 64)
 			ch->realVol = 64;
 
-		ch->outVol  = ch->realVol;
+		ch->outVol = ch->realVol;
 		ch->status |= IS_Vol;
 	}
 
@@ -1017,7 +1069,7 @@
 		ch->ePortaUpSpeed = tmpEff;
 
 		ch->realPeriod -= tmpEff;
-		if (ch->realPeriod < 1)
+		if ((int16_t)ch->realPeriod < 1)
 			ch->realPeriod = 1;
 
 		ch->outPeriod = ch->realPeriod;
@@ -1036,7 +1088,7 @@
 		ch->ePortaDownSpeed = tmpEff;
 
 		ch->realPeriod += tmpEff;
-		if (ch->realPeriod > 32000-1)
+		if ((int16_t)ch->realPeriod > 32000-1)
 			ch->realPeriod = 32000-1;
 
 		ch->outPeriod = ch->realPeriod;
@@ -1067,7 +1119,7 @@
 				ch->wantPeriod = note2Period[portaTmp];
 
 				     if (ch->wantPeriod == ch->realPeriod) ch->portaDir = 0;
-				else if (ch->wantPeriod  > ch->realPeriod) ch->portaDir = 1;
+				else if (ch->wantPeriod > ch->realPeriod) ch->portaDir = 1;
 				else ch->portaDir = 2;
 			}
 		}
@@ -1208,8 +1260,7 @@
 	bool envInterpolateFlag, envDidInterpolate;
 	uint8_t envPos;
 	int16_t autoVibVal, panTmp;
-	uint16_t autoVibAmp, tmpPeriod, envVal;
-	int32_t tmp32;
+	uint16_t tmpPeriod, autoVibAmp, envVal;
 	uint32_t vol;
 	instrTyp *ins;
 
@@ -1476,17 +1527,22 @@
 
 		     if (ins->vibTyp == 1) autoVibVal = (ch->eVibPos > 127) ? 64 : -64; // square
 		else if (ins->vibTyp == 2) autoVibVal = (((ch->eVibPos >> 1) + 64) & 127) - 64; // ramp up
-		else if (ins->vibTyp == 3) autoVibVal = (((0 - (ch->eVibPos >> 1)) + 64) & 127) - 64; // ramp down
+		else if (ins->vibTyp == 3) autoVibVal = ((-(ch->eVibPos >> 1) + 64) & 127) - 64; // ramp down
 		else autoVibVal = vibSineTab[ch->eVibPos]; // sine
 
 		autoVibVal <<= 2;
+		tmpPeriod = (autoVibVal * (int16_t)autoVibAmp) >> 16;
 
-		tmp32 = ((autoVibVal * (int16_t)autoVibAmp) >> 16) & 0x8000FFFF;
-		tmpPeriod = ch->outPeriod + (int16_t)tmp32;
+		tmpPeriod += ch->outPeriod;
 		if (tmpPeriod > 32000-1)
-			tmpPeriod = 0;
+			tmpPeriod = 0; // yes, FT2 does this (!)
 
-		ch->finalPeriod = tmpPeriod - ch->midiPitch;
+#ifdef HAS_MIDI
+		if (midi.enable)
+			tmpPeriod -= ch->midiPitch;
+#endif
+
+		ch->finalPeriod = tmpPeriod;
 		ch->status |= IS_Period;
 	}
 	else
@@ -1504,7 +1560,7 @@
 }
 
 // for arpeggio and portamento (semitone-slide mode)
-static int16_t relocateTon(int16_t period, uint8_t arpNote, stmTyp *ch)
+static uint16_t relocateTon(uint16_t period, uint8_t arpNote, stmTyp *ch)
 {
 	int32_t fineTune, loPeriod, hiPeriod, tmpPeriod, tableIndex;
 
@@ -1512,11 +1568,11 @@
 	hiPeriod = (8 * 12 * 16) * 2;
 	loPeriod = 0;
 
-	for (int8_t i = 0; i < 8; i++)
+	for (int32_t i = 0; i < 8; i++)
 	{
 		tmpPeriod = (((loPeriod + hiPeriod) >> 1) & 0xFFFFFFE0) + fineTune;
 
-		tableIndex = (tmpPeriod - 16) >> 1;
+		tableIndex = (uint32_t)(tmpPeriod - 16) >> 1;
 		tableIndex = CLAMP(tableIndex, 0, 1935); // 8bitbubsy: added security check
 
 		if (period >= note2Period[tableIndex])
@@ -1533,7 +1589,7 @@
 	if (tmpPeriod >= (8*12*16+15)*2-1) // FT2 bug: off-by-one edge case
 		tmpPeriod = (8*12*16+15)*2;
 
-	return note2Period[tmpPeriod>>1];
+	return note2Period[(uint32_t)tmpPeriod>>1];
 }
 
 static void tonePorta(stmTyp *ch)
@@ -1544,7 +1600,7 @@
 	if (ch->portaDir > 1)
 	{
 		ch->realPeriod -= ch->portaSpeed;
-		if (ch->realPeriod <= ch->wantPeriod)
+		if ((int16_t)ch->realPeriod <= (int16_t)ch->wantPeriod)
 		{
 			ch->portaDir = 1;
 			ch->realPeriod = ch->wantPeriod;
@@ -1578,18 +1634,16 @@
 
 	if ((tmpEff & 0xF0) == 0)
 	{
-		// unsigned clamp
-		if (ch->realVol >= tmpEff)
-			ch->realVol -= tmpEff;
-		else
+		ch->realVol -= tmpEff;
+		if ((int8_t)ch->realVol < 0)
 			ch->realVol = 0;
 	}
 	else
 	{
-		// unsigned clamp
-		if (ch->realVol <= 64-(tmpEff>>4))
-			ch->realVol += tmpEff>>4;
-		else
+		tmpEff >>= 4;
+
+		ch->realVol += tmpEff;
+		if (ch->realVol > 64)
 			ch->realVol = 64;
 	}
 
@@ -1599,7 +1653,7 @@
 
 static void vibrato2(stmTyp *ch)
 {
-	uint8_t tmpVib = (ch->vibPos / 4) & 0x1F;
+	uint8_t tmpVib = (ch->vibPos >> 2) & 0x1F;
 
 	switch (ch->waveCtrl & 3)
 	{
@@ -1609,9 +1663,9 @@
 		// 1: ramp
 		case 1:
 		{
-			tmpVib *= 8;
-			if (ch->vibPos >= 128)
-				tmpVib ^= 0xFF;
+			tmpVib <<= 3;
+			if ((int8_t)ch->vibPos < 0)
+				tmpVib = ~tmpVib;
 		}
 		break;
 
@@ -1619,9 +1673,9 @@
 		default: tmpVib = 255; break;
 	}
 
-	tmpVib = (tmpVib * ch->vibDepth) / 32;
+	tmpVib = (tmpVib * ch->vibDepth) >> 5; // logical shift (unsigned calc.), not arithmetic shift
 
-	if (ch->vibPos >= 128)
+	if ((int8_t)ch->vibPos < 0)
 		ch->outPeriod = ch->realPeriod - tmpVib;
 	else
 		ch->outPeriod = ch->realPeriod + tmpVib;
@@ -1632,10 +1686,17 @@
 
 static void vibrato(stmTyp *ch)
 {
+	uint8_t tmp8;
+
 	if (ch->eff > 0)
 	{
-		if ((ch->eff & 0x0F) > 0) ch->vibDepth = ch->eff & 0x0F;
-		if ((ch->eff & 0xF0) > 0) ch->vibSpeed = (ch->eff >> 4) * 4;
+		tmp8 = ch->eff & 0x0F;
+		if (tmp8 > 0)
+			ch->vibDepth = tmp8;
+
+		tmp8 = (ch->eff & 0xF0) >> 2;
+		if (tmp8 > 0)
+			ch->vibSpeed = tmp8;
 	}
 
 	vibrato2(ch);
@@ -1644,12 +1705,12 @@
 static void doEffects(stmTyp *ch)
 {
 	int8_t note;
-	uint8_t tmpEff, tremorData, tremorSign, tmpTrem;
-	int16_t tremVol;
+	uint8_t tmp8, tmpEff, tremorData, tremorSign, tmpTrem;
+	int16_t tremVol, tmp16;
 	uint16_t i, tick;
 
 	if (ch->stOff)
-		return;
+		return; // muted
 
 	// *** VOLUME COLUMN EFFECTS (TICKS >0) ***
 
@@ -1656,10 +1717,8 @@
 	// volume slide down
 	if ((ch->volKolVol & 0xF0) == 0x60)
 	{
-		// unsigned clamp
-		if (ch->realVol >= (ch->volKolVol & 0x0F))
-			ch->realVol -= ch->volKolVol & 0x0F;
-		else
+		ch->realVol -= ch->volKolVol & 0x0F;
+		if ((int8_t)ch->realVol < 0)
 			ch->realVol = 0;
 
 		ch->outVol = ch->realVol;
@@ -1669,10 +1728,8 @@
 	// volume slide up
 	else if ((ch->volKolVol & 0xF0) == 0x70)
 	{
-		// unsigned clamp
-		if (ch->realVol <= 64-(ch->volKolVol & 0x0F))
-			ch->realVol += ch->volKolVol & 0x0F;
-		else
+		ch->realVol += ch->volKolVol & 0x0F;
+		if (ch->realVol > 64)
 			ch->realVol = 64;
 
 		ch->outVol = ch->realVol;
@@ -1691,12 +1748,11 @@
 	// pan slide left
 	else if ((ch->volKolVol & 0xF0) == 0xD0)
 	{
-		// unsigned clamp + a bug when the parameter is 0
-		if ((ch->volKolVol & 0x0F) == 0 || ch->outPan < (ch->volKolVol & 0x0F))
-			ch->outPan = 0;
-		else
-			ch->outPan -= ch->volKolVol & 0x0F;
+		tmp16 = (int16_t)ch->outPan - (ch->volKolVol & 0x0F);
+		if (tmp16 < 0 || (ch->volKolVol & 0x0F) == 0) // FT2 bug: param 0 = pan gets set to 0
+			tmp16 = 0;
 
+		ch->outPan = (uint8_t)tmp16;
 		ch->status |= IS_Pan;
 	}
 
@@ -1703,12 +1759,11 @@
 	// pan slide right
 	else if ((ch->volKolVol & 0xF0) == 0xE0)
 	{
-		// unsigned clamp
-		if (ch->outPan <= 255-(ch->volKolVol & 0x0F))
-			ch->outPan += ch->volKolVol & 0x0F;
-		else
-			ch->outPan = 255;
+		tmp16 = (int16_t)ch->outPan + (ch->volKolVol & 0x0F);
+		if (tmp16 > 255)
+			tmp16 = 255;
 
+		ch->outPan = (uint8_t)tmp16;
 		ch->status |= IS_Pan;
 	}
 
@@ -1722,13 +1777,7 @@
 	// 0xy - Arpeggio
 	if (ch->effTyp == 0)
 	{
-		tick = song.timer;
-
-		// FT2 'out of boundary LUT read' arp simulation
-		     if (tick < 16) tick %= 3;
-		else if (tick == 16) tick = 0;
-		else tick = 2;
-
+		tick = arpTab[song.timer & 0x1F]; // 8bitbubsy: AND it for security
 		if (tick == 0)
 		{
 			ch->outPeriod = ch->realPeriod;
@@ -1738,7 +1787,7 @@
 			if (tick == 1)
 				note = ch->eff >> 4;
 			else
-				note = ch->eff & 0xF; // tick 2
+				note = ch->eff & 0x0F; // tick 2
 
 			ch->outPeriod = relocateTon(ch->realPeriod, note, ch);
 		}
@@ -1755,8 +1804,8 @@
 
 		ch->portaUpSpeed = tmpEff;
 
-		ch->realPeriod -= tmpEff * 4;
-		if (ch->realPeriod < 1)
+		ch->realPeriod -= tmpEff << 2;
+		if ((int16_t)ch->realPeriod < 1)
 			ch->realPeriod = 1;
 
 		ch->outPeriod = ch->realPeriod;
@@ -1772,8 +1821,8 @@
 
 		ch->portaDownSpeed = tmpEff;
 
-		ch->realPeriod += tmpEff * 4;
-		if (ch->realPeriod > 32000-1)
+		ch->realPeriod += tmpEff << 2;
+		if ((int16_t)ch->realPeriod > 32000-1) // FT2 bug, should've been unsigned comparison
 			ch->realPeriod = 32000-1;
 
 		ch->outPeriod = ch->realPeriod;
@@ -1806,11 +1855,16 @@
 		tmpEff = ch->eff;
 		if (tmpEff > 0)
 		{
-			if ((tmpEff & 0x0F) > 0) ch->tremDepth = tmpEff & 0x0F;
-			if ((tmpEff & 0xF0) > 0) ch->tremSpeed = (tmpEff >> 4) * 4;
+			tmp8 = tmpEff & 0x0F;
+			if (tmp8 > 0)
+				ch->tremDepth = tmp8;
+
+			tmp8 = (tmpEff & 0xF0) >> 2;
+			if (tmp8 > 0)
+				ch->tremSpeed = tmp8;
 		}
 
-		tmpTrem = (ch->tremPos / 4) & 0x1F;
+		tmpTrem = (ch->tremPos >> 2) & 0x1F;
 		switch ((ch->waveCtrl >> 4) & 3)
 		{
 			// 0: sine
@@ -1819,8 +1873,9 @@
 			// 1: ramp
 			case 1:
 			{
-				tmpTrem *= 8;
-				if (ch->vibPos >= 128) tmpTrem ^= 0xFF; // FT2 bug, should've been TremPos
+				tmpTrem <<= 3;
+				if ((int8_t)ch->vibPos < 0) // FT2 bug, should've been ch->tremPos
+					tmpTrem = ~tmpTrem;
 			}
 			break;
 
@@ -1827,9 +1882,9 @@
 			// 2/3: square
 			default: tmpTrem = 255; break;
 		}
-		tmpTrem = (tmpTrem * ch->tremDepth) / 64;
+		tmpTrem = (tmpTrem * ch->tremDepth) >> 6; // logical shift (unsigned calc.), not arithmetic shift
 
-		if (ch->tremPos >= 128)
+		if ((int8_t)ch->tremPos < 0)
 		{
 			tremVol = ch->realVol - tmpTrem;
 			if (tremVol < 0)
@@ -1842,9 +1897,9 @@
 				tremVol = 64;
 		}
 
-		ch->outVol = tremVol & 0xFF;
-		ch->tremPos += ch->tremSpeed;
+		ch->outVol = (uint8_t)tremVol;
 		ch->status |= IS_Vol;
+		ch->tremPos += ch->tremSpeed;
 	}
 
 	// Axy - volume slide
@@ -1891,7 +1946,7 @@
 
 				if (ch->volKolVol >= 0x10 && ch->volKolVol <= 0x50)
 				{
-					ch->outVol  = ch->volKolVol - 16;
+					ch->outVol = ch->volKolVol - 16;
 					ch->realVol = ch->outVol;
 				}
 				else if (ch->volKolVol >= 0xC0 && ch->volKolVol <= 0xCF)
@@ -1913,18 +1968,16 @@
 
 		if ((tmpEff & 0xF0) == 0)
 		{
-			// unsigned clamp
-			if (song.globVol >= tmpEff)
-				song.globVol -= tmpEff;
-			else
+			song.globVol -= tmpEff;
+			if ((int8_t)song.globVol < 0)
 				song.globVol = 0;
 		}
 		else
 		{
-			// unsigned clamp
-			if (song.globVol <= 64-(tmpEff >> 4))
-				song.globVol += tmpEff >> 4;
-			else
+			tmpEff >>= 4;
+
+			song.globVol += tmpEff;
+			if (song.globVol > 64)
 				song.globVol = 64;
 		}
 
@@ -1950,23 +2003,20 @@
 
 		if ((tmpEff & 0xF0) == 0)
 		{
-			// unsigned clamp
-			if (ch->outPan >= tmpEff)
-				ch->outPan -= tmpEff;
-			else
-				ch->outPan = 0;
+			tmp16 = (int16_t)ch->outPan - tmpEff;
+			if (tmp16 < 0)
+				tmp16 = 0;
 		}
 		else
 		{
 			tmpEff >>= 4;
 
-			// unsigned clamp
-			if (ch->outPan <= 255-tmpEff)
-				ch->outPan += tmpEff;
-			else
-				ch->outPan = 255;
+			tmp16 = (int16_t)ch->outPan + tmpEff;
+			if (tmp16 > 255)
+				tmp16 = 255;
 		}
-
+		
+		ch->outPan = (uint8_t)tmp16;
 		ch->status |= IS_Pan;
 	}
 
@@ -1986,7 +2036,7 @@
 		tremorData = ch->tremorPos & 0x7F;
 
 		tremorData--;
-		if ((tremorData & 0x80) > 0)
+		if ((int8_t)tremorData < 0)
 		{
 			if (tremorSign == 0x80)
 			{
@@ -2000,9 +2050,9 @@
 			}
 		}
 
-		ch->tremorPos = tremorData | tremorSign;
+		ch->tremorPos = tremorSign | tremorData;
 
-		ch->outVol = tremorSign ? ch->realVol : 0;
+		ch->outVol = (tremorSign == 0x80) ? ch->realVol : 0;
 		ch->status |= (IS_Vol + IS_QuickVol);
 	}
 }
@@ -2055,7 +2105,6 @@
 			}
 
 			assert(song.songPos <= 255);
-
 			song.pattNr = song.songTab[song.songPos & 0xFF];
 			song.pattLen = pattLens[song.pattNr & 0xFF];
 		}
@@ -2075,7 +2124,7 @@
 
 static void noNewAllChannels(void)
 {
-	for (uint8_t i = 0; i < song.antChn; i++)
+	for (int32_t i = 0; i < song.antChn; i++)
 	{
 		doEffects(&stm[i]);
 		fixaEnvelopeVibrato(&stm[i]);
@@ -2084,8 +2133,8 @@
 
 void mainPlayer(void) // periodically called from audio callback
 {
-	uint8_t i;
 	bool readNewNote;
+	int32_t i;
 
 	if (musicPaused || !songPlaying)
 	{
@@ -2095,8 +2144,8 @@
 		return;
 	}
 
-	if (song.speed > 0)
-		song.musicTime += 65536 / song.speed; // for playback counter
+	assert(song.speed >= 32 && song.speed <= 2);
+	song.musicTime64 += musicTimeTab[song.speed-32]; // for playback counter
 
 	readNewNote = false;
 	if (--song.timer == 0)
@@ -2106,9 +2155,9 @@
 	}
 
 	// for visuals
-	song.curReplayerTimer   = (uint8_t)song.timer;
+	song.curReplayerTimer = (uint8_t)song.timer;
 	song.curReplayerPattPos = (uint8_t)song.pattPos;
-	song.curReplayerPattNr  = (uint8_t)song.pattNr;
+	song.curReplayerPattNr = (uint8_t)song.pattNr;
 	song.curReplayerSongPos = (uint8_t)song.songPos;
 
 	if (readNewNote)
@@ -2720,7 +2769,9 @@
 	editor.globalVol = song.globVol = 64;
 	song.initialTempo = song.tempo;
 
-	setFrqTab(true);
+	audio.linearFreqTable = true;
+	note2Period = linearPeriods;
+
 	setPos(0, 0, true);
 
 	if (!allocateInstr(0))
@@ -2764,10 +2815,11 @@
 	playMode = mode;
 	songPlaying = true;
 	song.globVol = 64;
-	song.musicTime = 0;
 	song.pattDelTime2 = 0;
 	song.pattDelTime = 0;
 
+	resetPlaybackTime();
+
 	// non-FT2 fix: If song speed was 0, set it back to initial speed on play
 	if (song.tempo == 0)
 		song.tempo = song.initialTempo;
@@ -3057,7 +3109,9 @@
 
 	stopAllScopes();
 	resetAudioDither();
-	resetCachedFrequencyVars();
+#if !defined __amd64__ && !defined _WIN64
+	resetCachedMixerVars();
+#endif
 
 	// wait for scope thread to finish, so that we know pointers aren't deprecated
 	while (editor.scopeThreadMutex);
--- a/src/ft2_replayer.h
+++ b/src/ft2_replayer.h
@@ -49,7 +49,8 @@
 #define PROG_NAME_STR "Fasttracker II clone"
 
 /* Some of the following structs must be packed (e.g. not padded) since they
-** are loaded directly into with fread and stuff. */
+** are loaded directly into with fread and stuff.
+*/
 
 #ifdef _MSC_VER
 #pragma pack(push)
@@ -198,8 +199,8 @@
 	uint8_t portaUpSpeed, portaDownSpeed, retrigSpeed, retrigCnt, retrigVol;
 	uint8_t volKolVol, tonNr, envPPos, eVibPos, envVPos, realVol, oldVol, outVol;
 	uint8_t oldPan, outPan, finalPan;
-	int16_t midiPitch, realPeriod, envVIPValue, envPIPValue;
-	uint16_t finalVol, outPeriod, finalPeriod, tonTyp, wantPeriod, portaSpeed;
+	int16_t midiPitch, envVIPValue, envPIPValue;
+	uint16_t finalVol, outPeriod, realPeriod, finalPeriod, tonTyp, wantPeriod, portaSpeed;
 	uint16_t envVCnt, envVAmp, envPCnt, envPAmp, eVibAmp, eVibSweep;
 	uint16_t fadeOutAmp, fadeOutSpeed, midiVibDepth;
 	int32_t smpStartPos;
@@ -216,7 +217,7 @@
 	int16_t songPos, pattNr, pattPos, pattLen;
 	int32_t antChn;
 	uint16_t len, repS, speed, tempo, globVol, timer, ver, initialTempo;
-	uint32_t musicTime;
+	uint64_t musicTime64;
 } songTyp;
 
 typedef struct tonTyp_t
@@ -231,7 +232,6 @@
 	uint8_t status, sampleNr, instrNr;
 	uint16_t finalPeriod, finalVol;
 	int32_t smpStartPos;
-	uint32_t voiceDelta;
 } syncedChannel_t;
 
 void fixSongName(void); // removes spaces from right side of song name
@@ -238,10 +238,18 @@
 void fixSampleName(int16_t nr); // removes spaces from right side of ins/smp names
 
 void calcReplayRate(int32_t rate);
-void resetCachedFrequencyVars(void);
 void tuneSample(sampleTyp *s, int32_t midCFreq);
+
+
+#if defined _WIN64 || defined __amd64__
+uint64_t getFrequenceValue(uint16_t period);
+#else
 uint32_t getFrequenceValue(uint16_t period);
+#endif
 
+uint64_t getScopeFrequenceValue(uint16_t period);
+int32_t getPianoKey(uint16_t period, int32_t finetune, int32_t relativeNote); // for piano in Instr. Ed.
+
 bool allocateInstr(int16_t nr);
 void freeInstr(int32_t nr);
 void freeAllInstr(void);
@@ -291,9 +299,9 @@
 
 // ft2_replayer.c
 extern int8_t playMode;
-extern bool linearFrqTab, songPlaying, audioPaused, musicPaused;
+extern bool songPlaying, audioPaused, musicPaused;
 extern volatile bool replayerBusy;
-extern const int16_t *note2Period;
+extern const uint16_t *note2Period;
 extern int16_t pattLens[MAX_PATTERNS];
 extern stmTyp stm[MAX_VOICES];
 extern songTyp song;
--- a/src/ft2_sample_ed_features.c
+++ b/src/ft2_sample_ed_features.c
@@ -23,6 +23,7 @@
 #include "ft2_inst_ed.h"
 #include "ft2_sample_ed.h"
 #include "ft2_keyboard.h"
+#include "ft2_tables.h"
 
 static volatile bool stopThread;
 
@@ -661,20 +662,17 @@
 
 	assert(echo_nEcho <= 1024);
 
-	charOut(315 + (0 * 7), 226, PAL_FORGRND, '0' + (echo_nEcho / 1000) % 10);
+	charOut(315 + (0 * 7), 226, PAL_FORGRND, '0' + (char)(echo_nEcho / 1000));
 	charOut(315 + (1 * 7), 226, PAL_FORGRND, '0' + (echo_nEcho / 100) % 10);
 	charOut(315 + (2 * 7), 226, PAL_FORGRND, '0' + (echo_nEcho / 10) % 10);
 	charOut(315 + (3 * 7), 226, PAL_FORGRND, '0' + (echo_nEcho % 10));
 
-	assert((echo_Distance * 16) <= 262144);
+	assert(echo_Distance <= 0x4000);
+	hexOut(308, 240, PAL_FORGRND, (uint32_t)echo_Distance << 4, 5);
 
-	hexOut(308, 240, PAL_FORGRND, echo_Distance * 16, 5);
-
 	assert(echo_VolChange <= 100);
+	textOutFixed(312, 254, PAL_FORGRND, PAL_BUTTONS, dec3StrTab[echo_VolChange]);
 
-	charOut(312 + (0 * 7), 254, PAL_FORGRND, '0' + (echo_VolChange / 100) % 10);
-	charOut(312 + (1 * 7), 254, PAL_FORGRND, '0' + (echo_VolChange / 10) % 10);
-	charOut(312 + (2 * 7), 254, PAL_FORGRND, '0' + (echo_VolChange % 10));
 	charOutShadow(313 + (3 * 7), 254, PAL_FORGRND, PAL_BUTTON2, '%');
 }
 
@@ -1085,10 +1083,7 @@
 	textOutShadow(198, 246, PAL_FORGRND, PAL_BUTTON2, "Mixing balance");
 
 	assert((mix_Balance >= 0) && (mix_Balance <= 100));
-
-	charOut(299 + (0 * 7), 246, PAL_FORGRND, '0' + ((mix_Balance / 100) % 10));
-	charOut(299 + (1 * 7), 246, PAL_FORGRND, '0' + ((mix_Balance / 10) % 10));
-	charOut(299 + (2 * 7), 246, PAL_FORGRND, '0' + (mix_Balance % 10));
+	textOutFixed(299, 246, PAL_FORGRND, PAL_BUTTONS, dec3StrTab[mix_Balance]);
 }
 
 static void setupMixBoxWidgets(void)
@@ -1260,9 +1255,10 @@
 
 static int32_t SDLCALL applyVolumeThread(void *ptr)
 {
+#define AMP_BITS 15
 	int8_t *ptr8;
 	int16_t *ptr16;
-	int32_t vol1, vol2, tmp32, x1, x2, len, i;
+	int32_t amp32, x1, x2, len, i;
 	sampleTyp *s;
 
 	if (instr[editor.curInstr] == NULL)
@@ -1270,8 +1266,6 @@
 
 	s = &instr[editor.curInstr]->samp[editor.curSmp];
 
-	(void)ptr;
-
 	if (smpEd_Rx1 < smpEd_Rx2)
 	{
 		x1 = smpEd_Rx1;
@@ -1300,8 +1294,8 @@
 
 	if (s->typ & 16)
 	{
-		x1 /= 2;
-		x2 /= 2;
+		x1 >>= 1;
+		x2 >>= 1;
 	}
 
 	len = x2 - x1;
@@ -1308,22 +1302,28 @@
 	if (len <= 0)
 		goto applyVolumeExit;
 
-	pauseAudio();
-	restoreSample(s);
+	const double dVol1 = vol_StartVol * ((1 << AMP_BITS) / 100.0);
+	const double dVol2 = vol_EndVol * ((1 << AMP_BITS) / 100.0);
 
-	// scale values for faster math and suitable rounding for PCM waveforms (DIV -> arithmetic bitshift right)
-	vol1 = (int32_t)round((vol_StartVol * 256) / 100.0);
-	vol2 = (int32_t)round((vol_EndVol * 256) / 100.0) - vol1;
+	/* 8bitbubsy: Rewritten to use 64-bit deltas instead, to
+	** prevent having to do a 64-bit mul for every output sample.
+	*/
+	const int64_t delta64 = (int64_t)round(((dVol2 - dVol1) * (UINT32_MAX+1.0)) / len);
+	int64_t pos64 = (int64_t)dVol1 << 32;
 
+	pauseAudio();
+	restoreSample(s);
 	if (s->typ & 16)
 	{
 		ptr16 = (int16_t *)s->pek;
 		for (i = x1; i < x2; i++)
 		{
-			tmp32 = vol1 + (int32_t)(((int64_t)(i - x1) * vol2) / len);
-			tmp32 = (ptr16[i] * tmp32) >> 8;
-			CLAMP16(tmp32);
-			ptr16[i] = (int16_t)tmp32;
+			amp32 = (int32_t)(pos64 >> 32);
+			pos64 += delta64;
+
+			amp32 = (ptr16[i] * amp32) >> AMP_BITS;
+			CLAMP16(amp32);
+			ptr16[i] = (int16_t)amp32;
 		}
 	}
 	else
@@ -1331,20 +1331,24 @@
 		ptr8 = s->pek;
 		for (i = x1; i < x2; i++)
 		{
-			tmp32 = vol1 + (int32_t)(((int64_t)(i - x1) * vol2) / len);
-			tmp32 = (ptr8[i] * tmp32) >> 8;
-			CLAMP8(tmp32);
-			ptr8[i] = (int8_t)tmp32;
+			amp32 = (int32_t)(pos64 >> 32);
+			pos64 += delta64;
+
+			amp32 = (ptr8[i] * amp32) >> AMP_BITS;
+			CLAMP8(amp32);
+			ptr8[i] = (int8_t)amp32;
 		}
 	}
 	fixSample(s);
-
 	resumeAudio();
+
 	setSongModifiedFlag();
 
 applyVolumeExit:
 	setMouseBusy(false);
 	editor.ui.sysReqShown = false;
+
+	(void)ptr;
 	return true;
 }
 
@@ -1517,7 +1521,7 @@
 	if (val > 99)
 	{
 		charOut(253, 236, PAL_FORGRND, sign);
-		charOut(260, 236, PAL_FORGRND, '0' + ((val / 100) % 10));
+		charOut(260, 236, PAL_FORGRND, '0' + (char)(val / 100));
 		charOut(267, 236, PAL_FORGRND, '0' + ((val / 10) % 10));
 		charOut(274, 236, PAL_FORGRND, '0' + (val % 10));
 	}
@@ -1524,13 +1528,13 @@
 	else if (val > 9)
 	{
 		charOut(260, 236, PAL_FORGRND, sign);
-		charOut(267, 236, PAL_FORGRND, '0' + ((val / 10) % 10));
+		charOut(267, 236, PAL_FORGRND, '0' + (char)(val / 10));
 		charOut(274, 236, PAL_FORGRND, '0' + (val % 10));
 	}
 	else
 	{
 		charOut(267, 236, PAL_FORGRND, sign);
-		charOut(274, 236, PAL_FORGRND, '0' + (val % 10));
+		charOut(274, 236, PAL_FORGRND, '0' + (char)val);
 	}
 
 	     if (vol_EndVol == 0) sign = ' ';
@@ -1541,7 +1545,7 @@
 	if (val > 99)
 	{
 		charOut(253, 250, PAL_FORGRND, sign);
-		charOut(260, 250, PAL_FORGRND, '0' + ((val / 100) % 10));
+		charOut(260, 250, PAL_FORGRND, '0' + (char)(val / 100));
 		charOut(267, 250, PAL_FORGRND, '0' + ((val / 10) % 10));
 		charOut(274, 250, PAL_FORGRND, '0' + (val % 10));
 	}
@@ -1548,13 +1552,13 @@
 	else if (val > 9)
 	{
 		charOut(260, 250, PAL_FORGRND, sign);
-		charOut(267, 250, PAL_FORGRND, '0' + ((val / 10) % 10));
+		charOut(267, 250, PAL_FORGRND, '0' + (char)(val / 10));
 		charOut(274, 250, PAL_FORGRND, '0' + (val % 10));
 	}
 	else
 	{
 		charOut(267, 250, PAL_FORGRND, sign);
-		charOut(274, 250, PAL_FORGRND, '0' + (val % 10));
+		charOut(274, 250, PAL_FORGRND, '0' + (char)val);
 	}
 }
 
--- a/src/ft2_scopedraw.c
+++ b/src/ft2_scopedraw.c
@@ -7,65 +7,105 @@
 /*                          SCOPE DRAWING MACROS                           */
 /* ----------------------------------------------------------------------- */
 
-#define SCOPE_REGS \
+#define SCOPE_REGS_NO_LOOP \
+	const int8_t vol = s->SVol; \
+	const int32_t SLen = s->SLen; \
+	const uint32_t scopeDrawDelta = s->DFrq; \
+	const uint32_t scopePixelColor = video.palette[PAL_PATTEXT]; \
+	const uint32_t drawLen = x + w; \
 	int32_t sample; \
 	int32_t scopeDrawPos = s->SPos; \
 	int32_t scopeDrawFrac = 0; \
-	uint32_t scopePixelColor = video.palette[PAL_PATTEXT]; \
-	uint32_t len = x + w; \
 
+#define SCOPE_REGS_LOOP \
+	const int8_t vol = s->SVol; \
+	const int32_t SLen = s->SLen; \
+	const int32_t SRepS = s->SRepS; \
+	const int32_t SRepL = s->SRepL; \
+	const uint32_t scopeDrawDelta = s->DFrq; \
+	const uint32_t scopePixelColor = video.palette[PAL_PATTEXT]; \
+	const uint32_t drawLen = x + w; \
+	int32_t sample; \
+	int32_t scopeDrawPos = s->SPos; \
+	int32_t scopeDrawFrac = 0; \
+
 #define SCOPE_REGS_PINGPONG \
+	const int8_t vol = s->SVol; \
+	const int32_t SLen = s->SLen; \
+	const int32_t SRepS = s->SRepS; \
+	const int32_t SRepL = s->SRepL; \
+	const uint32_t scopeDrawDelta = s->DFrq; \
+	const uint32_t scopePixelColor = video.palette[PAL_PATTEXT]; \
+	const uint32_t drawLen = x + w; \
 	int32_t sample; \
 	int32_t scopeDrawPos = s->SPos; \
 	int32_t scopeDrawFrac = 0; \
-	int32_t drawPosDir = s->SPosDir; \
-	uint32_t scopePixelColor = video.palette[PAL_PATTEXT]; \
-	uint32_t len = x + w; \
+	int32_t drawPosDir = s->backwards ? -1 : 1; \
 
-#define LINED_SCOPE_REGS \
+#define LINED_SCOPE_REGS_NO_LOOP \
+	const int8_t vol = s->SVol; \
+	const int32_t SLen = s->SLen; \
+	const uint32_t scopeDrawDelta = s->DFrq; \
+	const uint32_t drawLen = (x + w) - 1; \
 	int32_t sample; \
 	int32_t y1, y2; \
 	int32_t scopeDrawPos = s->SPos; \
 	int32_t scopeDrawFrac = 0; \
-	uint32_t len = (x + w) - 1; \
 
+#define LINED_SCOPE_REGS_LOOP \
+	const int8_t vol = s->SVol; \
+	const int32_t SLen = s->SLen; \
+	const int32_t SRepS = s->SRepS; \
+	const int32_t SRepL = s->SRepL; \
+	const uint32_t scopeDrawDelta = s->DFrq; \
+	const uint32_t drawLen = (x + w) - 1; \
+	int32_t sample; \
+	int32_t y1, y2; \
+	int32_t scopeDrawPos = s->SPos; \
+	int32_t scopeDrawFrac = 0; \
+
 #define LINED_SCOPE_REGS_PINGPONG \
+	const int8_t vol = s->SVol; \
+	const int32_t SLen = s->SLen; \
+	const int32_t SRepS = s->SRepS; \
+	const int32_t SRepL = s->SRepL; \
+	const uint32_t scopeDrawDelta = s->DFrq; \
+	const uint32_t drawLen = (x + w) - 1; \
 	int32_t sample; \
 	int32_t y1, y2; \
 	int32_t scopeDrawPos = s->SPos; \
 	int32_t scopeDrawFrac = 0; \
-	int32_t drawPosDir = s->SPosDir; \
-	uint32_t len = (x + w) - 1; \
+	int32_t drawPosDir = s->backwards ? -1 : 1; \
 
 #define SCOPE_GET_SMP8 \
-	if (!s->active) \
+	if (s->active) \
 	{ \
-		sample = 0; \
+		assert(scopeDrawPos >= 0 && scopeDrawPos < SLen); \
+		sample = (s->sampleData8[scopeDrawPos] * vol) >> 8; \
 	} \
 	else \
 	{ \
-		assert(scopeDrawPos >= 0 && scopeDrawPos < s->SLen); \
-		sample = (s->sampleData8[scopeDrawPos] * s->SVol) >> 8; \
+		sample = 0; \
 	} \
 
 #define SCOPE_GET_SMP16 \
-	if (!s->active) \
+	if (s->active) \
 	{ \
-		sample = 0; \
+		assert(scopeDrawPos >= 0 && scopeDrawPos < SLen); \
+		sample = (int8_t)((s->sampleData16[scopeDrawPos] * vol) >> 16); \
 	} \
 	else \
 	{ \
-		assert(scopeDrawPos >= 0 && scopeDrawPos < s->SLen); \
-		sample = (int8_t)((s->sampleData16[scopeDrawPos] * s->SVol) >> 16); \
+		sample = 0; \
 	} \
 
 #define SCOPE_UPDATE_DRAWPOS \
-	scopeDrawFrac += (uint32_t)(s->SFrq >> (SCOPE_FRAC_BITS - 10)); \
+	scopeDrawFrac += scopeDrawDelta; \
 	scopeDrawPos += scopeDrawFrac >> 16; \
 	scopeDrawFrac &= 0xFFFF; \
 
 #define SCOPE_UPDATE_DRAWPOS_PINGPONG \
-	scopeDrawFrac += (uint32_t)(s->SFrq >> (SCOPE_FRAC_BITS - 10)); \
+	scopeDrawFrac += scopeDrawDelta; \
 	scopeDrawPos += (scopeDrawFrac >> 16) * drawPosDir; \
 	scopeDrawFrac &= 0xFFFF; \
 
@@ -88,72 +128,69 @@
 	y1 = y2; \
 
 #define SCOPE_HANDLE_POS_NO_LOOP \
-	if (scopeDrawPos >= s->SLen) \
+	if (scopeDrawPos >= SLen) \
 		s->active = false; \
 
 #define SCOPE_HANDLE_POS_LOOP \
-	if (scopeDrawPos >= s->SLen) \
+	if (scopeDrawPos >= SLen) \
 	{ \
-		if (s->SRepL < 2) \
-			scopeDrawPos = s->SRepS; \
+		if (SRepL >= 2) \
+			scopeDrawPos = SRepS + ((scopeDrawPos - SLen) % SRepL); \
 		else \
-			scopeDrawPos = s->SRepS + ((scopeDrawPos - s->SLen) % s->SRepL); \
+			scopeDrawPos = SRepS; \
 		\
-		assert(scopeDrawPos >= s->SRepS && scopeDrawPos < s->SLen); \
+		assert(scopeDrawPos >= SRepS && scopeDrawPos < SLen); \
 	} \
 
 #define SCOPE_HANDLE_POS_PINGPONG \
-	if (drawPosDir == -1 && scopeDrawPos < s->SRepS) \
+	if (drawPosDir == -1 && scopeDrawPos < SRepS) \
 	{ \
 		drawPosDir = 1; /* change direction to forwards */ \
 		\
-		if (s->SRepL < 2) \
-			scopeDrawPos = s->SRepS; \
+		if (SRepL >= 2) \
+			scopeDrawPos = SRepS + ((SRepS - scopeDrawPos - 1) % SRepL); \
 		else \
-			scopeDrawPos = s->SRepS + ((s->SRepS - scopeDrawPos - 1) % s->SRepL); \
+			scopeDrawPos = SRepS; \
 		\
-		assert(scopeDrawPos >= s->SRepS && scopeDrawPos < s->SLen); \
+		assert(scopeDrawPos >= SRepS && scopeDrawPos < SLen); \
 	} \
-	else if (scopeDrawPos >= s->SLen) \
+	else if (scopeDrawPos >= SLen) \
 	{ \
 		drawPosDir = -1; /* change direction to backwards */ \
 		\
-		if (s->SRepL < 2) \
-			scopeDrawPos = s->SLen - 1; \
+		if (SRepL >= 2) \
+			scopeDrawPos = (SLen - 1) - ((scopeDrawPos - SLen) % SRepL); \
 		else \
-			scopeDrawPos = (s->SLen - 1) - ((scopeDrawPos - s->SLen) % s->SRepL); \
+			scopeDrawPos = SLen - 1; \
 		\
-		assert(scopeDrawPos >= s->SRepS && scopeDrawPos < s->SLen); \
+		assert(scopeDrawPos >= SRepS && scopeDrawPos < SLen); \
 	} \
 	assert(scopeDrawPos >= 0); \
 
 static void scopeLine(int32_t x1, int32_t y1, int32_t y2)
 {
-	int32_t pitch, d, sy, dy;
-	uint32_t ay, pixVal, *dst32;
+	const int32_t dy = y2 - y1;
+	const int32_t sy = SGN(dy);
+	const uint32_t color = video.palette[PAL_PATTEXT];
+	const int32_t pitch = sy * SCREEN_W;
 
-	dy = y2 - y1;
-	ay = ABS(dy);
-	sy = SGN(dy);
+	uint32_t *dst32 = &video.frameBuffer[(y1 * SCREEN_W) + x1];
 
-	pixVal = video.palette[PAL_PATTEXT];
-	pitch = sy * SCREEN_W;
+	*dst32 = color; // set first pixel
 
-	dst32 = &video.frameBuffer[(y1 * SCREEN_W) + x1];
-	*dst32 = pixVal;
-
+	int32_t ay = ABS(dy);
 	if (ay <= 1)
 	{
 		if (ay != 0)
 			dst32 += pitch;
 
-		*++dst32 = pixVal;
+		*++dst32 = color;
 		return;
 	}
 
-	d = 2 - ay;
+	int32_t d = 1 - ay;
 
-	ay *= 2;
+	ay <<= 1;
 	while (y1 != y2)
 	{
 		if (d >= 0)
@@ -166,7 +203,7 @@
 		d += 2;
 
 		dst32 += pitch;
-		*dst32 = pixVal;
+		*dst32 = color;
 	}
 }
 
@@ -176,9 +213,9 @@
 
 static void scopeDrawNoLoop_8bit(scope_t *s, uint32_t x, uint32_t lineY, uint32_t w)
 {
-	SCOPE_REGS
+	SCOPE_REGS_NO_LOOP
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP8
 		SCOPE_DRAW_SMP
@@ -189,9 +226,9 @@
 
 static void scopeDrawLoop_8bit(scope_t *s, uint32_t x, uint32_t lineY, uint32_t w)
 {
-	SCOPE_REGS
+	SCOPE_REGS_LOOP
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP8
 		SCOPE_DRAW_SMP
@@ -204,7 +241,7 @@
 {
 	SCOPE_REGS_PINGPONG
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP8
 		SCOPE_DRAW_SMP
@@ -215,9 +252,9 @@
 
 static void scopeDrawNoLoop_16bit(scope_t *s, uint32_t x, uint32_t lineY, uint32_t w)
 {
-	SCOPE_REGS
+	SCOPE_REGS_NO_LOOP
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP16
 		SCOPE_DRAW_SMP
@@ -228,9 +265,9 @@
 
 static void scopeDrawLoop_16bit(scope_t *s, uint32_t x, uint32_t lineY, uint32_t w)
 {
-	SCOPE_REGS
+	SCOPE_REGS_LOOP
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP16
 		SCOPE_DRAW_SMP
@@ -243,7 +280,7 @@
 {
 	SCOPE_REGS_PINGPONG
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP16
 		SCOPE_DRAW_SMP
@@ -258,11 +295,11 @@
 
 static void linedScopeDrawNoLoop_8bit(scope_t *s, uint32_t x, uint32_t lineY, uint32_t w)
 {
-	LINED_SCOPE_REGS
+	LINED_SCOPE_REGS_NO_LOOP
 	LINED_SCOPE_PREPARE_SMP8
 	SCOPE_HANDLE_POS_NO_LOOP
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP8
 		LINED_SCOPE_DRAW_SMP
@@ -273,11 +310,11 @@
 
 static void linedScopeDrawLoop_8bit(scope_t *s, uint32_t x, uint32_t lineY, uint32_t w)
 {
-	LINED_SCOPE_REGS
+	LINED_SCOPE_REGS_LOOP
 	LINED_SCOPE_PREPARE_SMP8
 	SCOPE_HANDLE_POS_LOOP
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP8
 		LINED_SCOPE_DRAW_SMP
@@ -292,7 +329,7 @@
 	LINED_SCOPE_PREPARE_SMP8
 	SCOPE_HANDLE_POS_PINGPONG
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP8
 		LINED_SCOPE_DRAW_SMP
@@ -303,11 +340,11 @@
 
 static void linedScopeDrawNoLoop_16bit(scope_t *s, uint32_t x, uint32_t lineY, uint32_t w)
 {
-	LINED_SCOPE_REGS
+	LINED_SCOPE_REGS_NO_LOOP
 	LINED_SCOPE_PREPARE_SMP16
 	SCOPE_HANDLE_POS_NO_LOOP
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP16
 		LINED_SCOPE_DRAW_SMP
@@ -318,11 +355,11 @@
 
 static void linedScopeDrawLoop_16bit(scope_t *s, uint32_t x, uint32_t lineY, uint32_t w)
 {
-	LINED_SCOPE_REGS
+	LINED_SCOPE_REGS_LOOP
 	LINED_SCOPE_PREPARE_SMP16
 	SCOPE_HANDLE_POS_LOOP
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP16
 		LINED_SCOPE_DRAW_SMP
@@ -337,7 +374,7 @@
 	LINED_SCOPE_PREPARE_SMP16
 	SCOPE_HANDLE_POS_PINGPONG
 
-	for (; x < len; x++)
+	for (; x < drawLen; x++)
 	{
 		SCOPE_GET_SMP16
 		LINED_SCOPE_DRAW_SMP
--- a/src/ft2_scopes.c
+++ b/src/ft2_scopes.c
@@ -22,10 +22,6 @@
 #include "ft2_scopedraw.h"
 #include "ft2_tables.h"
 
-#if SCOPE_HZ != 64
-#error The SCOPE_HZ definition in ft2_header.h must be 2^n!
-#endif
-
 enum
 {
 	LOOP_NONE = 0,
@@ -44,9 +40,8 @@
 } scopeState_t;
 
 static volatile bool scopesUpdatingFlag, scopesDisplayingFlag;
-static int32_t oldPeriod;
 static uint32_t scopeTimeLen, scopeTimeLenFrac;
-static uint64_t timeNext64, timeNext64Frac, oldSFrq;
+static uint64_t timeNext64, timeNext64Frac;
 static volatile scope_t scope[MAX_VOICES];
 static SDL_Thread *scopeThread;
 static uint8_t *scopeMuteBMP_Ptrs[16];
@@ -53,12 +48,6 @@
 
 lastChInstr_t lastChInstr[MAX_VOICES]; // global
 
-void resetCachedScopeVars(void)
-{
-	oldPeriod = -1;
-	oldSFrq = 0;
-}
-
 int32_t getSamplePosition(uint8_t ch)
 {
 	volatile bool active, sample16Bit;
@@ -363,7 +352,7 @@
 	tempState.sample16Bit = sampleIs16Bit;
 	tempState.loopType = loopType;
 
-	tempState.SPosDir = 1; // forwards
+	tempState.backwards = false;
 	tempState.SLen = (loopType > 0) ? (loopBegin + loopLength) : length;
 	tempState.SRepS = loopBegin;
 	tempState.SRepL = loopLength;
@@ -381,6 +370,7 @@
 	tempState.active = true;
 	tempState.wasCleared = sc->wasCleared;
 	tempState.SFrq = sc->SFrq;
+	tempState.DFrq = sc->DFrq;
 	tempState.SVol = sc->SVol;
 
 	/* Update live scope now.
@@ -410,28 +400,34 @@
 		// scope position update
 
 		tempState.SPosDec += tempState.SFrq;
-		tempState.SPos += ((int32_t)(tempState.SPosDec >> SCOPE_FRAC_BITS) * tempState.SPosDir);
+
+		const uint32_t posAdd = tempState.SPosDec >> SCOPE_FRAC_BITS;
+		if (tempState.backwards)
+			tempState.SPos -= posAdd;
+		else
+			tempState.SPos += posAdd;
+
 		tempState.SPosDec &= SCOPE_FRAC_MASK;
 
 		// handle loop wrapping or sample end
 
-		if (tempState.SPosDir == -1 && tempState.SPos < tempState.SRepS) // sampling backwards (definitely pingpong loop)
+		if (tempState.backwards && tempState.SPos < tempState.SRepS) // sampling backwards (definitely pingpong loop)
 		{
-			tempState.SPosDir = 1; // change direction to forwards
+			tempState.backwards = false; // change direction to forwards
 
-			if (tempState.SRepL < 2)
-				tempState.SPos = tempState.SRepS;
-			else
+			if (tempState.SRepL >= 2)
 				tempState.SPos = tempState.SRepS + ((tempState.SRepS - tempState.SPos - 1) % tempState.SRepL);
+			else
+				tempState.SPos = tempState.SRepS;
 
 			assert(tempState.SPos >= tempState.SRepS && tempState.SPos < tempState.SLen);
 		}
 		else if (tempState.SPos >= tempState.SLen)
 		{
-			if (tempState.SRepL < 2)
-				loopOverflowVal = 0;
-			else
+			if (tempState.SRepL >= 2)
 				loopOverflowVal = (tempState.SPos - tempState.SLen) % tempState.SRepL;
+			else
+				loopOverflowVal = 0;
 
 			if (tempState.loopType == LOOP_NONE)
 			{
@@ -444,7 +440,7 @@
 			}
 			else // pingpong loop
 			{
-				tempState.SPosDir = -1; // change direction to backwards
+				tempState.backwards = true; // change direction to backwards
 				tempState.SPos = (tempState.SLen - 1) - loopOverflowVal;
 				assert(tempState.SPos >= tempState.SRepS && tempState.SPos < tempState.SLen);
 			}
@@ -548,7 +544,6 @@
 	uint8_t status;
 	syncedChannel_t *ch;
 	volatile scope_t *sc;
-	sampleTyp *smpPtr;
 
 	sc = scope;
 	ch = chSyncData->channels;
@@ -556,31 +551,22 @@
 	{
 		status = scopeUpdateStatus[i];
 
-		// set scope volume
 		if (status & IS_Vol)
 			sc->SVol = (int8_t)(((ch->finalVol * SCOPE_HEIGHT) + (1 << 15)) >> 16); // rounded
 
-		// set scope frequency
 		if (status & IS_Period)
 		{
-			if (ch->finalPeriod != oldPeriod)
-			{
-				oldPeriod = ch->finalPeriod;
-				oldSFrq = (uint64_t)ch->voiceDelta * audio.freq; // this can very well be higher than 2^32
-			}
-
-			sc->SFrq = oldSFrq;
+			sc->SFrq = getScopeFrequenceValue(ch->finalPeriod);
+			sc->DFrq = (uint32_t)(sc->SFrq >> (SCOPE_FRAC_BITS - 10)); // amount of samples to skip after drawing a pixel
 		}
 
-		// start scope sample
 		if (status & IS_NyTon)
 		{
 			if (instr[ch->instrNr] != NULL)
 			{
-				smpPtr = &instr[ch->instrNr]->samp[ch->sampleNr];
-				scopeTrigger(i, smpPtr, ch->smpStartPos);
+				scopeTrigger(i, &instr[ch->instrNr]->samp[ch->sampleNr], ch->smpStartPos);
 
-				// set stuff used by Smp. Ed. for sampling position line
+				// set some stuff used by Smp. Ed. for sampling position line
 
 				if (ch->instrNr == 130 || (ch->instrNr == editor.curInstr && ch->sampleNr == editor.curSmp))
 					editor.curSmpChannel = (uint8_t)i;
@@ -598,8 +584,6 @@
 	uint32_t diff32;
 	uint64_t time64;
 
-	(void)ptr;
-
 	// this is needed for scope stability (confirmed)
 	SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
 
@@ -637,6 +621,7 @@
 		}
 	}
 
+	(void)ptr;
 	return true;
 }
 
@@ -648,11 +633,15 @@
 	dFrac = modf(editor.dPerfFreq / SCOPE_HZ, &dInt);
 
 	// integer part
-	scopeTimeLen = (uint32_t)dInt;
+	scopeTimeLen = (int32_t)dInt;
 
 	// fractional part (scaled to 0..2^32-1)
 	dFrac *= UINT32_MAX;
-	scopeTimeLenFrac = (uint32_t)(dFrac + 0.5);
+	dFrac += 0.5;
+	if (dFrac > UINT32_MAX)
+		dFrac = UINT32_MAX;
+
+	scopeTimeLenFrac = (uint32_t)dFrac;
 
 	// setup scope mute BMP pointers
 	assert(bmp.scopeMute != NULL);
--- a/src/ft2_scopes.h
+++ b/src/ft2_scopes.h
@@ -5,13 +5,10 @@
 #include "ft2_header.h"
 #include "ft2_audio.h"
 
-// 6 = log2(SCOPE_HZ) where SCOPE_HZ is 2^n
-#define SCOPE_FRAC_BITS (MIXER_FRAC_BITS+6)
-
-#define SCOPE_FRAC_SCALE (1L << SCOPE_FRAC_BITS)
+#define SCOPE_FRAC_BITS 32
+#define SCOPE_FRAC_SCALE (1ULL << SCOPE_FRAC_BITS)
 #define SCOPE_FRAC_MASK (SCOPE_FRAC_SCALE-1)
 
-void resetCachedScopeVars(void);
 int32_t getSamplePosition(uint8_t ch);
 void stopAllScopes(void);
 void refreshScopes(void);
@@ -27,9 +24,10 @@
 	const int8_t *sampleData8;
 	const int16_t *sampleData16;
 	int8_t SVol;
-	bool wasCleared, sample16Bit;
+	bool wasCleared, sample16Bit, backwards;
 	uint8_t loopType;
-	int32_t SPosDir, SRepS, SRepL, SLen, SPos;
+	int32_t SRepS, SRepL, SLen, SPos;
+	uint32_t DFrq;
 	uint64_t SFrq, SPosDec;
 } scope_t;
 
--- a/src/ft2_tables.c
+++ b/src/ft2_tables.c
@@ -10,6 +10,14 @@
 /*                             REPLAYER TABLES                             */
 /* ----------------------------------------------------------------------- */
 
+const uint8_t arpTab[32] =
+{
+	0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,
+	// the following are overflown values from vibTab in the FT2 replayer code
+	0,24,49,74,97,120,141,161,180,
+	197,212,224,235,244,250,253
+};
+
 const int8_t vibSineTab[256] = // for auto-vibrato
 {
 	  0,  -2,  -3,  -5,  -6,  -8,  -9, -11, -12, -14, -16, -17, -19, -20, -22, -23,
@@ -60,7 +68,7 @@
 	494, 491, 487, 484, 480, 477, 474, 470, 467, 463, 460, 457
 };
 
-const int16_t linearPeriods[1936] = // bit-exact to FT2 table
+const uint16_t linearPeriods[1936] = // bit-exact to FT2 table
 {
 	7744, 7740, 7736, 7732, 7728, 7724, 7720, 7716, 7712, 7708, 7704, 7700, 7696, 7692, 7688, 7684,
 	7680, 7676, 7672, 7668, 7664, 7660, 7656, 7652, 7648, 7644, 7640, 7636, 7632, 7628, 7624, 7620,
@@ -185,7 +193,7 @@
 	  64,   60,   56,   52,   48,   44,   40,   36,   32,   28,   24,   20,   16,   12,    8,    4
 };
 
-const int16_t amigaPeriods[1936] = // bit-exact to FT2 table
+const uint16_t amigaPeriods[1936] = // bit-exact to FT2 table
 {
 	29024, 28912, 28800, 28704, 28608, 28496, 28384, 28288, 28192, 28096, 28000, 27888, 27776, 27680, 27584, 27488,
 	27392, 27296, 27200, 27104, 27008, 26912, 26816, 26720, 26624, 26528, 26432, 26336, 26240, 26144, 26048, 25952,
@@ -339,6 +347,37 @@
 /* ----------------------------------------------------------------------- */
 /*                               GUI TABLES                                */
 /* ----------------------------------------------------------------------- */
+
+const char *dec2StrTab[100] =
+{
+	"00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15",
+	"16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31",
+	"32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47",
+	"48","49","50","51","52","53","54","55","56","57","58","59","60","61","62","63",
+	"64","65","66","67","68","69","70","71","72","73","74","75","76","77","78","79",
+	"80","81","82","83","84","85","86","87","88","89","90","91","92","93","94","95",
+	"96","97","98","99"
+};
+
+const char *dec3StrTab[256] =
+{
+	"000","001","002","003","004","005","006","007","008","009","010","011","012","013","014","015",
+	"016","017","018","019","020","021","022","023","024","025","026","027","028","029","030","031",
+	"032","033","034","035","036","037","038","039","040","041","042","043","044","045","046","047",
+	"048","049","050","051","052","053","054","055","056","057","058","059","060","061","062","063",
+	"064","065","066","067","068","069","070","071","072","073","074","075","076","077","078","079",
+	"080","081","082","083","084","085","086","087","088","089","090","091","092","093","094","095",
+	"096","097","098","099","100","101","102","103","104","105","106","107","108","109","110","111",
+	"112","113","114","115","116","117","118","119","120","121","122","123","124","125","126","127",
+	"128","129","130","131","132","133","134","135","136","137","138","139","140","141","142","143",
+	"144","145","146","147","148","149","150","151","152","153","154","155","156","157","158","159",
+	"160","161","162","163","164","165","166","167","168","169","170","171","172","173","174","175",
+	"176","177","178","179","180","181","182","183","184","185","186","187","188","189","190","191",
+	"192","193","194","195","196","197","198","199","200","201","202","203","204","205","206","207",
+	"208","209","210","211","212","213","214","215","216","217","218","219","220","221","222","223",
+	"224","225","226","227","228","229","230","231","232","233","234","235","236","237","238","239",
+	"240","241","242","243","244","245","246","247","248","249","250","251","252","253","254","255"
+};
 
 const uint8_t font1Widths[128] = // normal font
 {
--- a/src/ft2_tables.h
+++ b/src/ft2_tables.h
@@ -10,14 +10,18 @@
 #define KEY2EFX_ENTRIES (signed)(sizeof (key2EfxTab) / sizeof (SDL_Keycode))
 #define KEY2HEX_ENTRIES (signed)(sizeof (key2HexTab) / sizeof (SDL_Keycode))
 
+extern const uint8_t arpTab[32];
 extern const int8_t vibSineTab[256]; // for auto-vibrato
 extern const uint8_t vibTab[32];
 extern const uint16_t amigaPeriod[12 * 8];
 extern const uint16_t amigaFinePeriod[12 * 8];
-extern const int16_t linearPeriods[1936];
-extern const int16_t amigaPeriods[1936];
+extern const uint16_t linearPeriods[1936];
+extern const uint16_t amigaPeriods[1936];
 
 extern const uint32_t panningTab[257];
+
+extern const char *dec2StrTab[100];
+extern const char *dec3StrTab[256];
 
 extern const uint8_t font1Widths[128];
 extern const uint8_t font2Widths[128];
--- a/src/ft2_video.c
+++ b/src/ft2_video.c
@@ -49,7 +49,7 @@
 
 // for FPS counter
 #define FPS_SCAN_FRAMES 60
-#define FPS_RENDER_W 280
+#define FPS_RENDER_W 285
 #define FPS_RENDER_H (((FONT1_CHAR_H + 1) * 8) + 1)
 #define FPS_RENDER_X 2
 #define FPS_RENDER_Y 2
@@ -1134,11 +1134,8 @@
 		if (editor.ui.drawReplayerPianoFlag)
 		{
 			editor.ui.drawReplayerPianoFlag = false;
-			if (editor.ui.instEditorShown)
-			{
-				if (chSyncEntry != NULL)
-					drawPiano(chSyncEntry);
-			}
+			if (editor.ui.instEditorShown && chSyncEntry != NULL)
+				drawPiano(chSyncEntry);
 		}
 
 		drawPosText = true;
--- a/src/ft2_wav_renderer.c
+++ b/src/ft2_wav_renderer.c
@@ -38,7 +38,11 @@
 static char WAV_SysReqText[192];
 static uint8_t WDBitDepth = 16, WDStartPos, WDStopPos, *wavRenderBuffer;
 static int16_t WDAmp;
+#if defined __amd64__ || defined _WIN64
+static uint32_t WDFrequency = 96000;
+#else
 static uint32_t WDFrequency = 48000;
+#endif
 static SDL_Thread *thread;
 
 static void updateWavRenderer(void)
@@ -47,8 +51,13 @@
 
 	fillRect(209, 116, 41, 51, PAL_DESKTOP);
 
+#if defined __amd64__ || defined _WIN64
 	sprintf(str, "%06d", WDFrequency);
 	textOut(209, 116, PAL_FORGRND, str);
+#else
+	sprintf(str, "%05d", WDFrequency);
+	textOut(216, 116, PAL_FORGRND, str);
+#endif
 
 	sprintf(str, "%02d", WDAmp);
 	textOut(237, 130, PAL_FORGRND, str);
@@ -70,7 +79,7 @@
 
 	textOutShadow(4,   96, PAL_FORGRND, PAL_DSKTOP2, "Harddisk recording:");
 	textOutShadow(156, 96, PAL_FORGRND, PAL_DSKTOP2, "16-bit");
-	textOutShadow(221, 96, PAL_FORGRND, PAL_DSKTOP2, "24-bit float");
+	textOutShadow(221, 96, PAL_FORGRND, PAL_DSKTOP2, "32-bit float");
 
 	textOutShadow(85, 116, PAL_FORGRND, PAL_DSKTOP2, "Frequency");
 	textOutShadow(85, 130, PAL_FORGRND, PAL_DSKTOP2, "Amplification");
@@ -180,7 +189,7 @@
 	song.globVol = 64;
 	setSpeed(song.speed);
 
-	song.musicTime = 0;
+	resetPlaybackTime();
 	return true;
 }
 
@@ -239,7 +248,7 @@
 
 	setBackOldAudioFreq();
 	setSpeed(song.speed);
-	setAudioAmp(config.boostLevel, config.masterVol, config.specialFlags & BITDEPTH_24);
+	setAudioAmp(config.boostLevel, config.masterVol, config.specialFlags & BITDEPTH_32);
 	editor.wavIsRendering = false;
 
 	setMouseBusy(false);
@@ -280,12 +289,14 @@
 	editor.globalVol = song.globVol;
 
 	editor.ui.drawPosEdFlag = true;
-	editor.ui.drawPattNumLenFlag = true; 
+	editor.ui.drawPattNumLenFlag = true;
 	editor.ui.drawReplayerPianoFlag = true;
 	editor.ui.drawBPMFlag = true;
 	editor.ui.drawSpeedFlag = true;
 	editor.ui.drawGlobVolFlag = true;
 	editor.ui.updatePatternEditor = true;
+
+	drawPlaybackTime();
 }
 
 static int32_t SDLCALL renderWavThread(void *ptr)
@@ -358,7 +369,6 @@
 
 	updateVisuals();
 	dump_Close(f, sampleCounter);
-
 	resumeAudio();
 
 	editor.diskOpReadOnOpen = true;
@@ -432,15 +442,15 @@
 {
 	if (WDFrequency < MAX_WAV_RENDER_FREQ)
 	{
-		     if (WDFrequency == 8000)  WDFrequency = 11025;
-		else if (WDFrequency == 11025) WDFrequency = 16000;
-		else if (WDFrequency == 16000) WDFrequency = 22050;
-		else if (WDFrequency == 22050) WDFrequency = 32000;
-		else if (WDFrequency == 32000) WDFrequency = 44100;
-		else if (WDFrequency == 44100) WDFrequency = 48000;
+		
+#if defined __amd64__ || defined _WIN64
+		     if (WDFrequency == 44100) WDFrequency = 48000;
 		else if (WDFrequency == 48000) WDFrequency = 96000;
 		else if (WDFrequency == 96000) WDFrequency = 192000;
-
+#else
+		     if (WDFrequency == 44100) WDFrequency = 48000;
+		else if (WDFrequency == 48000) WDFrequency = 96000;
+#endif
 		updateWavRenderer();
 	}
 }
@@ -449,9 +459,13 @@
 {
 	if (WDFrequency > MIN_WAV_RENDER_FREQ)
 	{
+#if defined __amd64__ || defined _WIN64
 		     if (WDFrequency == 192000) WDFrequency = 96000;
 		else if (WDFrequency == 96000) WDFrequency = 48000;
 		else if (WDFrequency == 48000) WDFrequency = 44100;
+#else
+		if (WDFrequency == 48000) WDFrequency = 44100;
+#endif
 
 		updateWavRenderer();
 	}
--- a/src/ft2_wav_renderer.h
+++ b/src/ft2_wav_renderer.h
@@ -4,7 +4,17 @@
 #include "ft2_header.h"
 
 #define MIN_WAV_RENDER_FREQ 44100
+
+#if defined __amd64__ || defined _WIN64
+
 #define MAX_WAV_RENDER_FREQ 192000
+
+#else
+
+#define MAX_WAV_RENDER_FREQ 48000
+
+#endif
+
 #define MAX_WAV_RENDER_SAMPLES_PER_TICK (((MAX_WAV_RENDER_FREQ * 5) / 2) / MIN_BPM)
 
 void updateWavRendererSettings(void);
--- a/src/helpdata/FT2.HLP
+++ b/src/helpdata/FT2.HLP
@@ -785,8 +785,7 @@
 >@X060@C002
 Works for 16-bit audio mode only.
 Applies random scaled values to the mixed samples before truncating to 16-bit.
-This should in theory lower the quantization noise. 16-bit already has
-a pretty low noise floor, so don't expect any audible difference here.
+This should in theory lower the quantization noise.
 Also applies for WAV rendering.
 
 >@X040@C001Amplification:
@@ -913,6 +912,8 @@
 >@X010
 >@C001Video:
 >@C002
+>@X010- Fullscreen mode can be unbearably slow on a Raspberry Pi (even an RPi 4)
+>
 >@X010- The scopes can mildly flicker depending on the waveform and pitch.
 >@X021This is because their frequency is not clocked to exactly the same rate
 >at which the scopes are rendered. It's close, which causes a flicker effect.
--- a/src/helpdata/ft2_help_data.h
+++ b/src/helpdata/ft2_help_data.h
@@ -3,9 +3,9 @@
 
 #include <stdint.h>
 
-#define HELP_DATA_LEN 27305
+#define HELP_DATA_LEN 27298
 
-const uint8_t helpData[27305] =
+const uint8_t helpData[27298] =
 {
 	0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
@@ -1796,493 +1796,492 @@
 	0x68,0x65,0x20,0x6D,0x69,0x78,0x65,0x64,0x20,0x73,0x61,0x6D,
 	0x70,0x6C,0x65,0x73,0x20,0x62,0x65,0x66,0x6F,0x72,0x65,0x20,
 	0x74,0x72,0x75,0x6E,0x63,0x61,0x74,0x69,0x6E,0x67,0x20,0x74,
-	0x6F,0x20,0x31,0x36,0x2D,0x62,0x69,0x74,0x2E,0x46,0x54,0x68,
+	0x6F,0x20,0x31,0x36,0x2D,0x62,0x69,0x74,0x2E,0x33,0x54,0x68,
 	0x69,0x73,0x20,0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,0x69,0x6E,
 	0x20,0x74,0x68,0x65,0x6F,0x72,0x79,0x20,0x6C,0x6F,0x77,0x65,
 	0x72,0x20,0x74,0x68,0x65,0x20,0x71,0x75,0x61,0x6E,0x74,0x69,
 	0x7A,0x61,0x74,0x69,0x6F,0x6E,0x20,0x6E,0x6F,0x69,0x73,0x65,
-	0x2E,0x20,0x31,0x36,0x2D,0x62,0x69,0x74,0x20,0x61,0x6C,0x72,
-	0x65,0x61,0x64,0x79,0x20,0x68,0x61,0x73,0x46,0x61,0x20,0x70,
-	0x72,0x65,0x74,0x74,0x79,0x20,0x6C,0x6F,0x77,0x20,0x6E,0x6F,
-	0x69,0x73,0x65,0x20,0x66,0x6C,0x6F,0x6F,0x72,0x2C,0x20,0x73,
-	0x6F,0x20,0x64,0x6F,0x6E,0x27,0x74,0x20,0x65,0x78,0x70,0x65,
-	0x63,0x74,0x20,0x61,0x6E,0x79,0x20,0x61,0x75,0x64,0x69,0x62,
-	0x6C,0x65,0x20,0x64,0x69,0x66,0x66,0x65,0x72,0x65,0x6E,0x63,
-	0x65,0x20,0x68,0x65,0x72,0x65,0x2E,0x1F,0x41,0x6C,0x73,0x6F,
-	0x20,0x61,0x70,0x70,0x6C,0x69,0x65,0x73,0x20,0x66,0x6F,0x72,
-	0x20,0x57,0x41,0x56,0x20,0x72,0x65,0x6E,0x64,0x65,0x72,0x69,
-	0x6E,0x67,0x2E,0x00,0x19,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,
-	0x43,0x30,0x30,0x31,0x41,0x6D,0x70,0x6C,0x69,0x66,0x69,0x63,
-	0x61,0x74,0x69,0x6F,0x6E,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,
-	0x30,0x40,0x43,0x30,0x30,0x32,0x46,0x41,0x6D,0x70,0x6C,0x69,
-	0x66,0x69,0x65,0x73,0x20,0x74,0x68,0x65,0x20,0x76,0x6F,0x6C,
-	0x75,0x6D,0x65,0x20,0x77,0x68,0x65,0x6E,0x20,0x6D,0x69,0x78,
-	0x69,0x6E,0x67,0x2E,0x20,0x49,0x66,0x20,0x79,0x6F,0x75,0x20,
-	0x73,0x65,0x74,0x20,0x74,0x68,0x69,0x73,0x20,0x6F,0x6E,0x65,
-	0x20,0x74,0x6F,0x6F,0x20,0x68,0x69,0x67,0x68,0x2C,0x20,0x79,
-	0x6F,0x75,0x27,0x6C,0x6C,0x3A,0x67,0x65,0x74,0x20,0x64,0x69,
-	0x73,0x74,0x6F,0x72,0x74,0x69,0x6F,0x6E,0x2E,0x20,0x33,0x32,
-	0x58,0x20,0x65,0x71,0x75,0x61,0x6C,0x73,0x20,0x66,0x75,0x6C,
-	0x6C,0x20,0x61,0x6D,0x70,0x6C,0x69,0x74,0x75,0x64,0x65,0x20,
-	0x66,0x6F,0x72,0x20,0x6F,0x6E,0x65,0x20,0x63,0x68,0x61,0x6E,
-	0x6E,0x65,0x6C,0x2E,0x00,0x1B,0x3E,0x40,0x58,0x30,0x34,0x30,
-	0x40,0x43,0x30,0x30,0x31,0x46,0x72,0x65,0x71,0x75,0x65,0x6E,
-	0x63,0x79,0x20,0x74,0x61,0x62,0x6C,0x65,0x3A,0x0B,0x3E,0x40,
-	0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x40,0x54,0x68,
-	0x65,0x20,0x6C,0x69,0x6E,0x65,0x61,0x72,0x20,0x66,0x72,0x65,
-	0x71,0x75,0x65,0x6E,0x63,0x79,0x20,0x74,0x61,0x62,0x6C,0x65,
-	0x20,0x6D,0x61,0x6B,0x65,0x73,0x20,0x61,0x6C,0x6C,0x20,0x70,
-	0x69,0x74,0x63,0x68,0x20,0x62,0x65,0x6E,0x64,0x73,0x20,0x72,
-	0x75,0x6E,0x20,0x69,0x6E,0x20,0x63,0x6F,0x6E,0x73,0x74,0x61,
-	0x6E,0x74,0x3F,0x73,0x70,0x65,0x65,0x64,0x2C,0x20,0x69,0x6E,
-	0x64,0x65,0x70,0x65,0x6E,0x64,0x65,0x6E,0x74,0x20,0x6F,0x66,
-	0x20,0x74,0x68,0x65,0x20,0x63,0x75,0x72,0x72,0x65,0x6E,0x74,
-	0x20,0x66,0x72,0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x2E,0x20,
-	0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x73,0x77,0x69,0x74,0x63,
-	0x68,0x20,0x74,0x68,0x69,0x73,0x41,0x6F,0x6E,0x65,0x2C,0x20,
-	0x6F,0x6E,0x20,0x61,0x20,0x66,0x69,0x6E,0x69,0x73,0x68,0x65,
-	0x64,0x20,0x73,0x6F,0x6E,0x67,0x2C,0x20,0x69,0x74,0x20,0x6D,
-	0x69,0x67,0x68,0x74,0x20,0x73,0x6F,0x75,0x6E,0x64,0x20,0x73,
-	0x74,0x72,0x61,0x6E,0x67,0x65,0x20,0x69,0x66,0x20,0x74,0x68,
-	0x65,0x20,0x73,0x6F,0x75,0x6E,0x64,0x20,0x75,0x73,0x65,0x73,
-	0x0D,0x70,0x6F,0x72,0x74,0x61,0x6D,0x65,0x6E,0x74,0x6F,0x65,
-	0x73,0x2E,0x00,0x20,0x40,0x58,0x30,0x32,0x30,0x40,0x43,0x30,
-	0x30,0x31,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,
-	0x69,0x6F,0x6E,0x2C,0x20,0x4C,0x61,0x79,0x6F,0x75,0x74,0x3A,
-	0x01,0x3E,0x29,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,
-	0x30,0x31,0x50,0x61,0x74,0x74,0x65,0x72,0x6E,0x20,0x6C,0x61,
-	0x79,0x6F,0x75,0x74,0x2C,0x20,0x68,0x65,0x78,0x20,0x6E,0x75,
-	0x6D,0x62,0x65,0x72,0x69,0x6E,0x67,0x3A,0x0B,0x3E,0x40,0x58,
-	0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x41,0x49,0x66,0x20,
-	0x79,0x6F,0x75,0x20,0x75,0x73,0x65,0x20,0x70,0x61,0x74,0x74,
-	0x65,0x72,0x6E,0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x61,0x72,
-	0x65,0x20,0x6C,0x6F,0x6E,0x67,0x65,0x72,0x20,0x74,0x68,0x61,
-	0x6E,0x20,0x39,0x39,0x20,0x6C,0x69,0x6E,0x65,0x73,0x2C,0x20,
-	0x79,0x6F,0x75,0x20,0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,0x75,
-	0x73,0x65,0x45,0x68,0x65,0x78,0x20,0x63,0x6F,0x75,0x6E,0x74,
-	0x69,0x6E,0x67,0x20,0x73,0x69,0x6E,0x63,0x65,0x20,0x74,0x68,
-	0x65,0x72,0x65,0x20,0x61,0x72,0x65,0x20,0x6F,0x6E,0x6C,0x79,
-	0x20,0x32,0x20,0x64,0x69,0x67,0x69,0x74,0x73,0x20,0x69,0x6E,
-	0x20,0x74,0x68,0x65,0x20,0x6C,0x69,0x6E,0x65,0x20,0x6E,0x75,
-	0x6D,0x62,0x65,0x72,0x20,0x63,0x6F,0x6C,0x75,0x6D,0x6E,0x2E,
-	0x00,0x12,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,
-	0x31,0x53,0x63,0x6F,0x70,0x65,0x73,0x3A,0x0B,0x3E,0x40,0x58,
-	0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x43,0x22,0x53,0x74,
-	0x64,0x2E,0x22,0x20,0x28,0x73,0x74,0x61,0x6E,0x64,0x61,0x72,
-	0x64,0x29,0x20,0x77,0x69,0x6C,0x6C,0x20,0x73,0x68,0x6F,0x77,
-	0x20,0x74,0x68,0x65,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,
-	0x70,0x6F,0x69,0x6E,0x74,0x73,0x20,0x61,0x73,0x20,0x70,0x69,
-	0x78,0x65,0x6C,0x73,0x20,0x28,0x6C,0x69,0x6B,0x65,0x20,0x46,
-	0x54,0x32,0x29,0x2E,0x41,0x22,0x4C,0x69,0x6E,0x65,0x64,0x22,
-	0x20,0x77,0x69,0x6C,0x6C,0x20,0x64,0x72,0x61,0x77,0x20,0x6C,
-	0x69,0x6E,0x65,0x73,0x20,0x62,0x65,0x74,0x77,0x65,0x65,0x6E,
-	0x20,0x74,0x68,0x65,0x20,0x70,0x6F,0x69,0x6E,0x74,0x73,0x2C,
-	0x20,0x6C,0x69,0x6B,0x65,0x20,0x61,0x6E,0x20,0x6F,0x73,0x63,
-	0x69,0x6C,0x6C,0x6F,0x73,0x63,0x6F,0x70,0x65,0x2E,0x00,0x27,
-	0x40,0x58,0x30,0x32,0x30,0x40,0x43,0x30,0x30,0x31,0x43,0x6F,
-	0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x2C,
-	0x20,0x4D,0x69,0x73,0x63,0x65,0x6C,0x6C,0x61,0x6E,0x65,0x6F,
-	0x75,0x73,0x3A,0x01,0x3E,0x15,0x3E,0x40,0x58,0x30,0x34,0x30,
-	0x40,0x43,0x30,0x30,0x31,0x56,0x53,0x79,0x6E,0x63,0x20,0x6F,
-	0x66,0x66,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,
-	0x30,0x30,0x32,0x3F,0x54,0x65,0x6C,0x6C,0x73,0x20,0x74,0x68,
-	0x65,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x74,0x6F,
-	0x20,0x6E,0x6F,0x74,0x20,0x75,0x73,0x65,0x20,0x56,0x53,0x79,
-	0x6E,0x63,0x20,0x66,0x6F,0x72,0x20,0x76,0x69,0x64,0x65,0x6F,
-	0x2E,0x20,0x49,0x66,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,
-	0x6E,0x69,0x74,0x6F,0x72,0x27,0x73,0x40,0x72,0x65,0x66,0x72,
-	0x65,0x73,0x68,0x20,0x72,0x61,0x74,0x65,0x20,0x69,0x73,0x20,
-	0x6E,0x6F,0x74,0x20,0x36,0x30,0x48,0x7A,0x20,0x28,0x6F,0x72,
-	0x20,0x35,0x39,0x48,0x7A,0x29,0x2C,0x20,0x74,0x68,0x65,0x6E,
-	0x20,0x56,0x53,0x79,0x6E,0x63,0x20,0x69,0x73,0x20,0x61,0x6C,
-	0x77,0x61,0x79,0x73,0x20,0x6F,0x66,0x66,0x20,0x66,0x6F,0x72,
-	0x45,0x74,0x68,0x69,0x73,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,
-	0x6D,0x2E,0x20,0x4E,0x6F,0x74,0x20,0x68,0x61,0x76,0x69,0x6E,
-	0x67,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,0x77,0x69,0x6C,0x6C,
-	0x20,0x72,0x65,0x73,0x75,0x6C,0x74,0x20,0x69,0x6E,0x20,0x6C,
-	0x65,0x73,0x73,0x20,0x69,0x6E,0x70,0x75,0x74,0x2F,0x76,0x69,
-	0x64,0x65,0x6F,0x20,0x64,0x65,0x6C,0x61,0x79,0x2C,0x1E,0x62,
-	0x75,0x74,0x20,0x61,0x6C,0x73,0x6F,0x20,0x70,0x6F,0x74,0x65,
-	0x6E,0x74,0x69,0x61,0x6C,0x20,0x73,0x74,0x75,0x74,0x74,0x65,
-	0x72,0x69,0x6E,0x67,0x2E,0x01,0x20,0x18,0x3E,0x40,0x58,0x30,
-	0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x50,0x69,0x78,0x65,0x6C,
-	0x20,0x66,0x69,0x6C,0x74,0x65,0x72,0x3A,0x0B,0x3E,0x40,0x58,
-	0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x43,0x41,0x70,0x70,
-	0x6C,0x69,0x65,0x73,0x20,0x61,0x20,0x73,0x75,0x62,0x70,0x69,
-	0x78,0x65,0x6C,0x20,0x66,0x69,0x6C,0x74,0x65,0x72,0x20,0x74,
-	0x68,0x61,0x74,0x20,0x69,0x73,0x20,0x75,0x73,0x65,0x64,0x20,
-	0x77,0x68,0x65,0x6E,0x20,0x74,0x68,0x65,0x20,0x77,0x69,0x6E,
-	0x64,0x6F,0x77,0x20,0x69,0x73,0x20,0x75,0x70,0x73,0x63,0x61,
-	0x6C,0x65,0x64,0x2E,0x43,0x54,0x68,0x69,0x73,0x20,0x61,0x6C,
-	0x73,0x6F,0x20,0x6D,0x61,0x6B,0x65,0x73,0x20,0x66,0x75,0x6C,
-	0x6C,0x73,0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,
-	0x20,0x63,0x6F,0x6D,0x70,0x6C,0x65,0x74,0x65,0x6C,0x79,0x20,
-	0x73,0x74,0x72,0x65,0x74,0x63,0x68,0x20,0x6F,0x75,0x74,0x20,
-	0x69,0x66,0x20,0x69,0x74,0x20,0x64,0x69,0x64,0x6E,0x27,0x74,
-	0x44,0x61,0x6C,0x72,0x65,0x61,0x64,0x79,0x2E,0x20,0x50,0x6C,
-	0x65,0x61,0x73,0x65,0x20,0x6B,0x65,0x65,0x70,0x20,0x69,0x6E,
-	0x20,0x6D,0x69,0x6E,0x64,0x20,0x74,0x68,0x61,0x74,0x20,0x74,
-	0x68,0x69,0x73,0x20,0x77,0x69,0x6C,0x6C,0x20,0x6D,0x61,0x6B,
-	0x65,0x20,0x70,0x69,0x78,0x65,0x6C,0x73,0x20,0x6C,0x6F,0x6F,
-	0x6B,0x20,0x62,0x6C,0x75,0x72,0x72,0x79,0x2E,0x00,0x23,0x40,
-	0x58,0x30,0x32,0x30,0x40,0x43,0x30,0x30,0x31,0x41,0x64,0x76,
-	0x61,0x6E,0x63,0x65,0x64,0x20,0x65,0x64,0x69,0x74,0x20,0x66,
-	0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x73,0x3A,0x20,0x01,0x3E,
-	0x1E,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,
-	0x43,0x6F,0x70,0x79,0x2F,0x50,0x61,0x73,0x74,0x65,0x20,0x6D,
-	0x61,0x73,0x6B,0x69,0x6E,0x67,0x3A,0x0B,0x3E,0x40,0x58,0x30,
-	0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x37,0x54,0x68,0x65,0x20,
-	0x6D,0x61,0x73,0x6B,0x69,0x6E,0x67,0x20,0x69,0x73,0x20,0x75,
-	0x73,0x65,0x64,0x20,0x66,0x6F,0x72,0x20,0x63,0x6F,0x70,0x79,
-	0x69,0x6E,0x67,0x2F,0x70,0x61,0x73,0x74,0x69,0x6E,0x67,0x20,
-	0x6F,0x6E,0x6C,0x79,0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x6F,
-	0x66,0x20,0x61,0x46,0x22,0x6E,0x6F,0x74,0x65,0x2D,0x63,0x65,
-	0x6C,0x6C,0x22,0x2E,0x20,0x54,0x68,0x65,0x20,0x64,0x69,0x66,
-	0x66,0x65,0x72,0x65,0x6E,0x74,0x20,0x70,0x61,0x72,0x74,0x73,
-	0x20,0x6F,0x66,0x20,0x61,0x20,0x22,0x6E,0x6F,0x74,0x65,0x2D,
-	0x63,0x65,0x6C,0x6C,0x22,0x20,0x69,0x73,0x20,0x4E,0x6F,0x74,
-	0x65,0x2C,0x20,0x49,0x6E,0x73,0x74,0x72,0x2E,0x20,0x6E,0x72,
-	0x2E,0x2C,0x20,0x56,0x6F,0x6C,0x75,0x6D,0x65,0x2C,0x20,0x45,
-	0x66,0x66,0x65,0x63,0x74,0x20,0x6E,0x72,0x20,0x26,0x20,0x45,
-	0x66,0x66,0x65,0x63,0x74,0x20,0x64,0x61,0x74,0x61,0x2E,0x34,
-	0x3E,0x41,0x73,0x20,0x79,0x6F,0x75,0x20,0x63,0x61,0x6E,0x20,
-	0x73,0x65,0x65,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x77,
-	0x69,0x6E,0x64,0x6F,0x77,0x20,0x74,0x68,0x65,0x72,0x65,0x20,
-	0x61,0x72,0x65,0x20,0x33,0x20,0x63,0x6F,0x6C,0x75,0x6D,0x6E,
-	0x73,0x20,0x6F,0x66,0x3D,0x22,0x65,0x6E,0x61,0x62,0x6C,0x65,
-	0x2F,0x64,0x69,0x73,0x61,0x62,0x6C,0x65,0x20,0x62,0x75,0x74,
-	0x74,0x6F,0x6E,0x73,0x22,0x20,0x77,0x68,0x69,0x63,0x68,0x20,
-	0x68,0x61,0x73,0x20,0x74,0x68,0x65,0x20,0x6C,0x65,0x74,0x74,
-	0x65,0x72,0x73,0x20,0x43,0x2C,0x50,0x20,0x26,0x20,0x54,0x20,
-	0x61,0x62,0x6F,0x76,0x65,0x2E,0x45,0x3E,0x43,0x20,0x6D,0x65,
-	0x61,0x6E,0x73,0x20,0x63,0x6F,0x70,0x79,0x2C,0x20,0x69,0x74,
-	0x20,0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x73,0x20,0x77,0x68,
-	0x69,0x63,0x68,0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x74,0x68,
-	0x61,0x74,0x20,0x67,0x6F,0x65,0x73,0x20,0x69,0x6E,0x74,0x6F,
-	0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x70,0x79,0x62,0x75,0x66,
-	0x66,0x65,0x72,0x2E,0x3E,0x3E,0x50,0x20,0x6D,0x65,0x61,0x6E,
-	0x73,0x20,0x70,0x61,0x73,0x74,0x65,0x20,0x61,0x6E,0x64,0x20,
-	0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x73,0x20,0x77,0x68,0x69,
-	0x63,0x68,0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x74,0x68,0x61,
-	0x74,0x20,0x67,0x6F,0x65,0x73,0x20,0x6F,0x75,0x74,0x20,0x66,
-	0x72,0x6F,0x6D,0x20,0x74,0x68,0x65,0x0B,0x63,0x6F,0x70,0x79,
-	0x62,0x75,0x66,0x66,0x65,0x72,0x2E,0x45,0x3E,0x54,0x20,0x6D,
-	0x65,0x61,0x6E,0x73,0x20,0x74,0x72,0x61,0x6E,0x73,0x70,0x61,
-	0x72,0x65,0x6E,0x63,0x79,0x2E,0x20,0x49,0x66,0x20,0x69,0x74,
-	0x27,0x73,0x20,0x65,0x6E,0x61,0x62,0x6C,0x65,0x64,0x2C,0x20,
-	0x74,0x68,0x65,0x20,0x70,0x61,0x73,0x74,0x69,0x6E,0x67,0x20,
-	0x64,0x6F,0x65,0x73,0x6E,0x27,0x74,0x20,0x6F,0x76,0x65,0x72,
-	0x77,0x72,0x69,0x74,0x65,0x3D,0x64,0x61,0x74,0x61,0x20,0x77,
-	0x69,0x74,0x68,0x20,0x6E,0x69,0x6C,0x2D,0x69,0x6E,0x66,0x6F,
-	0x72,0x6D,0x61,0x74,0x69,0x6F,0x6E,0x2C,0x20,0x6F,0x6E,0x6C,
-	0x79,0x20,0x77,0x69,0x74,0x68,0x20,0x61,0x20,0x6E,0x6F,0x74,
-	0x65,0x20,0x6F,0x72,0x20,0x61,0x20,0x6E,0x75,0x6D,0x62,0x65,
-	0x72,0x20,0x3C,0x3E,0x20,0x30,0x2E,0x01,0x3E,0x40,0x3E,0x54,
-	0x68,0x65,0x20,0x63,0x75,0x74,0x20,0x66,0x75,0x6E,0x63,0x74,
-	0x69,0x6F,0x6E,0x73,0x20,0x77,0x6F,0x72,0x6B,0x73,0x20,0x6C,
-	0x69,0x6B,0x65,0x20,0x70,0x61,0x73,0x74,0x69,0x6E,0x67,0x20,
-	0x77,0x69,0x74,0x68,0x20,0x7A,0x65,0x72,0x6F,0x2D,0x64,0x61,
-	0x74,0x61,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,0x6D,0x65,0x61,
-	0x6E,0x73,0x3B,0x74,0x68,0x61,0x74,0x20,0x74,0x68,0x65,0x20,
-	0x63,0x75,0x74,0x74,0x69,0x6E,0x67,0x20,0x69,0x73,0x20,0x63,
-	0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x6C,0x65,0x64,0x20,0x77,0x69,
-	0x74,0x68,0x20,0x50,0x2D,0x63,0x6F,0x6C,0x75,0x6D,0x6E,0x20,
-	0x28,0x6F,0x72,0x20,0x54,0x2D,0x63,0x6F,0x6C,0x75,0x6D,0x6E,
-	0x29,0x2E,0x3C,0x3E,0x57,0x68,0x65,0x6E,0x20,0x79,0x6F,0x75,
-	0x20,0x63,0x6F,0x70,0x79,0x20,0x64,0x61,0x74,0x61,0x20,0x77,
-	0x69,0x74,0x68,0x20,0x6D,0x61,0x73,0x6B,0x69,0x6E,0x67,0x2C,
-	0x20,0x74,0x68,0x65,0x20,0x64,0x69,0x73,0x61,0x62,0x6C,0x65,
-	0x64,0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x61,0x72,0x65,0x20,
-	0x6E,0x6F,0x74,0x43,0x63,0x6C,0x65,0x61,0x72,0x65,0x64,0x20,
-	0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x70,0x79,0x62,
-	0x75,0x66,0x66,0x65,0x72,0x2E,0x20,0x28,0x4D,0x61,0x6B,0x69,
-	0x6E,0x67,0x20,0x69,0x74,0x20,0x70,0x6F,0x73,0x73,0x69,0x62,
-	0x6C,0x65,0x20,0x74,0x6F,0x20,0x63,0x6F,0x6C,0x6C,0x65,0x63,
-	0x74,0x20,0x64,0x61,0x74,0x61,0x20,0x66,0x72,0x6F,0x6D,0x27,
-	0x73,0x65,0x76,0x65,0x72,0x61,0x6C,0x20,0x6C,0x6F,0x63,0x61,
-	0x74,0x69,0x6F,0x6E,0x73,0x20,0x69,0x6E,0x74,0x6F,0x20,0x74,
-	0x68,0x65,0x20,0x63,0x6F,0x70,0x79,0x62,0x75,0x66,0x66,0x65,
-	0x72,0x2E,0x29,0x00,0x03,0x45,0x4E,0x44,0x4C,0x3B,0x2A,0x2A,
+	0x2E,0x1F,0x41,0x6C,0x73,0x6F,0x20,0x61,0x70,0x70,0x6C,0x69,
+	0x65,0x73,0x20,0x66,0x6F,0x72,0x20,0x57,0x41,0x56,0x20,0x72,
+	0x65,0x6E,0x64,0x65,0x72,0x69,0x6E,0x67,0x2E,0x00,0x19,0x3E,
+	0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x41,0x6D,
+	0x70,0x6C,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x3A,
+	0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,
+	0x46,0x41,0x6D,0x70,0x6C,0x69,0x66,0x69,0x65,0x73,0x20,0x74,
+	0x68,0x65,0x20,0x76,0x6F,0x6C,0x75,0x6D,0x65,0x20,0x77,0x68,
+	0x65,0x6E,0x20,0x6D,0x69,0x78,0x69,0x6E,0x67,0x2E,0x20,0x49,
+	0x66,0x20,0x79,0x6F,0x75,0x20,0x73,0x65,0x74,0x20,0x74,0x68,
+	0x69,0x73,0x20,0x6F,0x6E,0x65,0x20,0x74,0x6F,0x6F,0x20,0x68,
+	0x69,0x67,0x68,0x2C,0x20,0x79,0x6F,0x75,0x27,0x6C,0x6C,0x3A,
+	0x67,0x65,0x74,0x20,0x64,0x69,0x73,0x74,0x6F,0x72,0x74,0x69,
+	0x6F,0x6E,0x2E,0x20,0x33,0x32,0x58,0x20,0x65,0x71,0x75,0x61,
+	0x6C,0x73,0x20,0x66,0x75,0x6C,0x6C,0x20,0x61,0x6D,0x70,0x6C,
+	0x69,0x74,0x75,0x64,0x65,0x20,0x66,0x6F,0x72,0x20,0x6F,0x6E,
+	0x65,0x20,0x63,0x68,0x61,0x6E,0x6E,0x65,0x6C,0x2E,0x00,0x1B,
+	0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x46,
+	0x72,0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x20,0x74,0x61,0x62,
+	0x6C,0x65,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,
+	0x30,0x30,0x32,0x40,0x54,0x68,0x65,0x20,0x6C,0x69,0x6E,0x65,
+	0x61,0x72,0x20,0x66,0x72,0x65,0x71,0x75,0x65,0x6E,0x63,0x79,
+	0x20,0x74,0x61,0x62,0x6C,0x65,0x20,0x6D,0x61,0x6B,0x65,0x73,
+	0x20,0x61,0x6C,0x6C,0x20,0x70,0x69,0x74,0x63,0x68,0x20,0x62,
+	0x65,0x6E,0x64,0x73,0x20,0x72,0x75,0x6E,0x20,0x69,0x6E,0x20,
+	0x63,0x6F,0x6E,0x73,0x74,0x61,0x6E,0x74,0x3F,0x73,0x70,0x65,
+	0x65,0x64,0x2C,0x20,0x69,0x6E,0x64,0x65,0x70,0x65,0x6E,0x64,
+	0x65,0x6E,0x74,0x20,0x6F,0x66,0x20,0x74,0x68,0x65,0x20,0x63,
+	0x75,0x72,0x72,0x65,0x6E,0x74,0x20,0x66,0x72,0x65,0x71,0x75,
+	0x65,0x6E,0x63,0x79,0x2E,0x20,0x49,0x66,0x20,0x79,0x6F,0x75,
+	0x20,0x73,0x77,0x69,0x74,0x63,0x68,0x20,0x74,0x68,0x69,0x73,
+	0x41,0x6F,0x6E,0x65,0x2C,0x20,0x6F,0x6E,0x20,0x61,0x20,0x66,
+	0x69,0x6E,0x69,0x73,0x68,0x65,0x64,0x20,0x73,0x6F,0x6E,0x67,
+	0x2C,0x20,0x69,0x74,0x20,0x6D,0x69,0x67,0x68,0x74,0x20,0x73,
+	0x6F,0x75,0x6E,0x64,0x20,0x73,0x74,0x72,0x61,0x6E,0x67,0x65,
+	0x20,0x69,0x66,0x20,0x74,0x68,0x65,0x20,0x73,0x6F,0x75,0x6E,
+	0x64,0x20,0x75,0x73,0x65,0x73,0x0D,0x70,0x6F,0x72,0x74,0x61,
+	0x6D,0x65,0x6E,0x74,0x6F,0x65,0x73,0x2E,0x00,0x20,0x40,0x58,
+	0x30,0x32,0x30,0x40,0x43,0x30,0x30,0x31,0x43,0x6F,0x6E,0x66,
+	0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x2C,0x20,0x4C,
+	0x61,0x79,0x6F,0x75,0x74,0x3A,0x01,0x3E,0x29,0x3E,0x40,0x58,
+	0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x50,0x61,0x74,0x74,
+	0x65,0x72,0x6E,0x20,0x6C,0x61,0x79,0x6F,0x75,0x74,0x2C,0x20,
+	0x68,0x65,0x78,0x20,0x6E,0x75,0x6D,0x62,0x65,0x72,0x69,0x6E,
+	0x67,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,
+	0x30,0x32,0x41,0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x75,0x73,
+	0x65,0x20,0x70,0x61,0x74,0x74,0x65,0x72,0x6E,0x73,0x20,0x74,
+	0x68,0x61,0x74,0x20,0x61,0x72,0x65,0x20,0x6C,0x6F,0x6E,0x67,
+	0x65,0x72,0x20,0x74,0x68,0x61,0x6E,0x20,0x39,0x39,0x20,0x6C,
+	0x69,0x6E,0x65,0x73,0x2C,0x20,0x79,0x6F,0x75,0x20,0x73,0x68,
+	0x6F,0x75,0x6C,0x64,0x20,0x75,0x73,0x65,0x45,0x68,0x65,0x78,
+	0x20,0x63,0x6F,0x75,0x6E,0x74,0x69,0x6E,0x67,0x20,0x73,0x69,
+	0x6E,0x63,0x65,0x20,0x74,0x68,0x65,0x72,0x65,0x20,0x61,0x72,
+	0x65,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x32,0x20,0x64,0x69,0x67,
+	0x69,0x74,0x73,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x6C,
+	0x69,0x6E,0x65,0x20,0x6E,0x75,0x6D,0x62,0x65,0x72,0x20,0x63,
+	0x6F,0x6C,0x75,0x6D,0x6E,0x2E,0x00,0x12,0x3E,0x40,0x58,0x30,
+	0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x53,0x63,0x6F,0x70,0x65,
+	0x73,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,
+	0x30,0x32,0x43,0x22,0x53,0x74,0x64,0x2E,0x22,0x20,0x28,0x73,
+	0x74,0x61,0x6E,0x64,0x61,0x72,0x64,0x29,0x20,0x77,0x69,0x6C,
+	0x6C,0x20,0x73,0x68,0x6F,0x77,0x20,0x74,0x68,0x65,0x20,0x73,
+	0x61,0x6D,0x70,0x6C,0x65,0x20,0x70,0x6F,0x69,0x6E,0x74,0x73,
+	0x20,0x61,0x73,0x20,0x70,0x69,0x78,0x65,0x6C,0x73,0x20,0x28,
+	0x6C,0x69,0x6B,0x65,0x20,0x46,0x54,0x32,0x29,0x2E,0x41,0x22,
+	0x4C,0x69,0x6E,0x65,0x64,0x22,0x20,0x77,0x69,0x6C,0x6C,0x20,
+	0x64,0x72,0x61,0x77,0x20,0x6C,0x69,0x6E,0x65,0x73,0x20,0x62,
+	0x65,0x74,0x77,0x65,0x65,0x6E,0x20,0x74,0x68,0x65,0x20,0x70,
+	0x6F,0x69,0x6E,0x74,0x73,0x2C,0x20,0x6C,0x69,0x6B,0x65,0x20,
+	0x61,0x6E,0x20,0x6F,0x73,0x63,0x69,0x6C,0x6C,0x6F,0x73,0x63,
+	0x6F,0x70,0x65,0x2E,0x00,0x27,0x40,0x58,0x30,0x32,0x30,0x40,
+	0x43,0x30,0x30,0x31,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,
+	0x61,0x74,0x69,0x6F,0x6E,0x2C,0x20,0x4D,0x69,0x73,0x63,0x65,
+	0x6C,0x6C,0x61,0x6E,0x65,0x6F,0x75,0x73,0x3A,0x01,0x3E,0x15,
+	0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,0x31,0x56,
+	0x53,0x79,0x6E,0x63,0x20,0x6F,0x66,0x66,0x3A,0x0B,0x3E,0x40,
+	0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,0x32,0x3F,0x54,0x65,
+	0x6C,0x6C,0x73,0x20,0x74,0x68,0x65,0x20,0x70,0x72,0x6F,0x67,
+	0x72,0x61,0x6D,0x20,0x74,0x6F,0x20,0x6E,0x6F,0x74,0x20,0x75,
+	0x73,0x65,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,0x66,0x6F,0x72,
+	0x20,0x76,0x69,0x64,0x65,0x6F,0x2E,0x20,0x49,0x66,0x20,0x79,
+	0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27,
+	0x73,0x40,0x72,0x65,0x66,0x72,0x65,0x73,0x68,0x20,0x72,0x61,
+	0x74,0x65,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,0x36,0x30,
+	0x48,0x7A,0x20,0x28,0x6F,0x72,0x20,0x35,0x39,0x48,0x7A,0x29,
+	0x2C,0x20,0x74,0x68,0x65,0x6E,0x20,0x56,0x53,0x79,0x6E,0x63,
+	0x20,0x69,0x73,0x20,0x61,0x6C,0x77,0x61,0x79,0x73,0x20,0x6F,
+	0x66,0x66,0x20,0x66,0x6F,0x72,0x45,0x74,0x68,0x69,0x73,0x20,
+	0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x2E,0x20,0x4E,0x6F,0x74,
+	0x20,0x68,0x61,0x76,0x69,0x6E,0x67,0x20,0x56,0x53,0x79,0x6E,
+	0x63,0x20,0x77,0x69,0x6C,0x6C,0x20,0x72,0x65,0x73,0x75,0x6C,
+	0x74,0x20,0x69,0x6E,0x20,0x6C,0x65,0x73,0x73,0x20,0x69,0x6E,
+	0x70,0x75,0x74,0x2F,0x76,0x69,0x64,0x65,0x6F,0x20,0x64,0x65,
+	0x6C,0x61,0x79,0x2C,0x1E,0x62,0x75,0x74,0x20,0x61,0x6C,0x73,
+	0x6F,0x20,0x70,0x6F,0x74,0x65,0x6E,0x74,0x69,0x61,0x6C,0x20,
+	0x73,0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,0x67,0x2E,0x01,
+	0x20,0x18,0x3E,0x40,0x58,0x30,0x34,0x30,0x40,0x43,0x30,0x30,
+	0x31,0x50,0x69,0x78,0x65,0x6C,0x20,0x66,0x69,0x6C,0x74,0x65,
+	0x72,0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,
+	0x30,0x32,0x43,0x41,0x70,0x70,0x6C,0x69,0x65,0x73,0x20,0x61,
+	0x20,0x73,0x75,0x62,0x70,0x69,0x78,0x65,0x6C,0x20,0x66,0x69,
+	0x6C,0x74,0x65,0x72,0x20,0x74,0x68,0x61,0x74,0x20,0x69,0x73,
+	0x20,0x75,0x73,0x65,0x64,0x20,0x77,0x68,0x65,0x6E,0x20,0x74,
+	0x68,0x65,0x20,0x77,0x69,0x6E,0x64,0x6F,0x77,0x20,0x69,0x73,
+	0x20,0x75,0x70,0x73,0x63,0x61,0x6C,0x65,0x64,0x2E,0x43,0x54,
+	0x68,0x69,0x73,0x20,0x61,0x6C,0x73,0x6F,0x20,0x6D,0x61,0x6B,
+	0x65,0x73,0x20,0x66,0x75,0x6C,0x6C,0x73,0x63,0x72,0x65,0x65,
+	0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,0x63,0x6F,0x6D,0x70,0x6C,
+	0x65,0x74,0x65,0x6C,0x79,0x20,0x73,0x74,0x72,0x65,0x74,0x63,
+	0x68,0x20,0x6F,0x75,0x74,0x20,0x69,0x66,0x20,0x69,0x74,0x20,
+	0x64,0x69,0x64,0x6E,0x27,0x74,0x44,0x61,0x6C,0x72,0x65,0x61,
+	0x64,0x79,0x2E,0x20,0x50,0x6C,0x65,0x61,0x73,0x65,0x20,0x6B,
+	0x65,0x65,0x70,0x20,0x69,0x6E,0x20,0x6D,0x69,0x6E,0x64,0x20,
+	0x74,0x68,0x61,0x74,0x20,0x74,0x68,0x69,0x73,0x20,0x77,0x69,
+	0x6C,0x6C,0x20,0x6D,0x61,0x6B,0x65,0x20,0x70,0x69,0x78,0x65,
+	0x6C,0x73,0x20,0x6C,0x6F,0x6F,0x6B,0x20,0x62,0x6C,0x75,0x72,
+	0x72,0x79,0x2E,0x00,0x23,0x40,0x58,0x30,0x32,0x30,0x40,0x43,
+	0x30,0x30,0x31,0x41,0x64,0x76,0x61,0x6E,0x63,0x65,0x64,0x20,
+	0x65,0x64,0x69,0x74,0x20,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,
+	0x6E,0x73,0x3A,0x20,0x01,0x3E,0x1E,0x3E,0x40,0x58,0x30,0x34,
+	0x30,0x40,0x43,0x30,0x30,0x31,0x43,0x6F,0x70,0x79,0x2F,0x50,
+	0x61,0x73,0x74,0x65,0x20,0x6D,0x61,0x73,0x6B,0x69,0x6E,0x67,
+	0x3A,0x0B,0x3E,0x40,0x58,0x30,0x36,0x30,0x40,0x43,0x30,0x30,
+	0x32,0x37,0x54,0x68,0x65,0x20,0x6D,0x61,0x73,0x6B,0x69,0x6E,
+	0x67,0x20,0x69,0x73,0x20,0x75,0x73,0x65,0x64,0x20,0x66,0x6F,
+	0x72,0x20,0x63,0x6F,0x70,0x79,0x69,0x6E,0x67,0x2F,0x70,0x61,
+	0x73,0x74,0x69,0x6E,0x67,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x70,
+	0x61,0x72,0x74,0x73,0x20,0x6F,0x66,0x20,0x61,0x46,0x22,0x6E,
+	0x6F,0x74,0x65,0x2D,0x63,0x65,0x6C,0x6C,0x22,0x2E,0x20,0x54,
+	0x68,0x65,0x20,0x64,0x69,0x66,0x66,0x65,0x72,0x65,0x6E,0x74,
+	0x20,0x70,0x61,0x72,0x74,0x73,0x20,0x6F,0x66,0x20,0x61,0x20,
+	0x22,0x6E,0x6F,0x74,0x65,0x2D,0x63,0x65,0x6C,0x6C,0x22,0x20,
+	0x69,0x73,0x20,0x4E,0x6F,0x74,0x65,0x2C,0x20,0x49,0x6E,0x73,
+	0x74,0x72,0x2E,0x20,0x6E,0x72,0x2E,0x2C,0x20,0x56,0x6F,0x6C,
+	0x75,0x6D,0x65,0x2C,0x20,0x45,0x66,0x66,0x65,0x63,0x74,0x20,
+	0x6E,0x72,0x20,0x26,0x20,0x45,0x66,0x66,0x65,0x63,0x74,0x20,
+	0x64,0x61,0x74,0x61,0x2E,0x34,0x3E,0x41,0x73,0x20,0x79,0x6F,
+	0x75,0x20,0x63,0x61,0x6E,0x20,0x73,0x65,0x65,0x20,0x69,0x6E,
+	0x20,0x74,0x68,0x65,0x20,0x77,0x69,0x6E,0x64,0x6F,0x77,0x20,
+	0x74,0x68,0x65,0x72,0x65,0x20,0x61,0x72,0x65,0x20,0x33,0x20,
+	0x63,0x6F,0x6C,0x75,0x6D,0x6E,0x73,0x20,0x6F,0x66,0x3D,0x22,
+	0x65,0x6E,0x61,0x62,0x6C,0x65,0x2F,0x64,0x69,0x73,0x61,0x62,
+	0x6C,0x65,0x20,0x62,0x75,0x74,0x74,0x6F,0x6E,0x73,0x22,0x20,
+	0x77,0x68,0x69,0x63,0x68,0x20,0x68,0x61,0x73,0x20,0x74,0x68,
+	0x65,0x20,0x6C,0x65,0x74,0x74,0x65,0x72,0x73,0x20,0x43,0x2C,
+	0x50,0x20,0x26,0x20,0x54,0x20,0x61,0x62,0x6F,0x76,0x65,0x2E,
+	0x45,0x3E,0x43,0x20,0x6D,0x65,0x61,0x6E,0x73,0x20,0x63,0x6F,
+	0x70,0x79,0x2C,0x20,0x69,0x74,0x20,0x63,0x6F,0x6E,0x74,0x72,
+	0x6F,0x6C,0x73,0x20,0x77,0x68,0x69,0x63,0x68,0x20,0x70,0x61,
+	0x72,0x74,0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x67,0x6F,0x65,
+	0x73,0x20,0x69,0x6E,0x74,0x6F,0x20,0x74,0x68,0x65,0x20,0x63,
+	0x6F,0x70,0x79,0x62,0x75,0x66,0x66,0x65,0x72,0x2E,0x3E,0x3E,
+	0x50,0x20,0x6D,0x65,0x61,0x6E,0x73,0x20,0x70,0x61,0x73,0x74,
+	0x65,0x20,0x61,0x6E,0x64,0x20,0x63,0x6F,0x6E,0x74,0x72,0x6F,
+	0x6C,0x73,0x20,0x77,0x68,0x69,0x63,0x68,0x20,0x70,0x61,0x72,
+	0x74,0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x67,0x6F,0x65,0x73,
+	0x20,0x6F,0x75,0x74,0x20,0x66,0x72,0x6F,0x6D,0x20,0x74,0x68,
+	0x65,0x0B,0x63,0x6F,0x70,0x79,0x62,0x75,0x66,0x66,0x65,0x72,
+	0x2E,0x45,0x3E,0x54,0x20,0x6D,0x65,0x61,0x6E,0x73,0x20,0x74,
+	0x72,0x61,0x6E,0x73,0x70,0x61,0x72,0x65,0x6E,0x63,0x79,0x2E,
+	0x20,0x49,0x66,0x20,0x69,0x74,0x27,0x73,0x20,0x65,0x6E,0x61,
+	0x62,0x6C,0x65,0x64,0x2C,0x20,0x74,0x68,0x65,0x20,0x70,0x61,
+	0x73,0x74,0x69,0x6E,0x67,0x20,0x64,0x6F,0x65,0x73,0x6E,0x27,
+	0x74,0x20,0x6F,0x76,0x65,0x72,0x77,0x72,0x69,0x74,0x65,0x3D,
+	0x64,0x61,0x74,0x61,0x20,0x77,0x69,0x74,0x68,0x20,0x6E,0x69,
+	0x6C,0x2D,0x69,0x6E,0x66,0x6F,0x72,0x6D,0x61,0x74,0x69,0x6F,
+	0x6E,0x2C,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x77,0x69,0x74,0x68,
+	0x20,0x61,0x20,0x6E,0x6F,0x74,0x65,0x20,0x6F,0x72,0x20,0x61,
+	0x20,0x6E,0x75,0x6D,0x62,0x65,0x72,0x20,0x3C,0x3E,0x20,0x30,
+	0x2E,0x01,0x3E,0x40,0x3E,0x54,0x68,0x65,0x20,0x63,0x75,0x74,
+	0x20,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x73,0x20,0x77,
+	0x6F,0x72,0x6B,0x73,0x20,0x6C,0x69,0x6B,0x65,0x20,0x70,0x61,
+	0x73,0x74,0x69,0x6E,0x67,0x20,0x77,0x69,0x74,0x68,0x20,0x7A,
+	0x65,0x72,0x6F,0x2D,0x64,0x61,0x74,0x61,0x2E,0x20,0x54,0x68,
+	0x69,0x73,0x20,0x6D,0x65,0x61,0x6E,0x73,0x3B,0x74,0x68,0x61,
+	0x74,0x20,0x74,0x68,0x65,0x20,0x63,0x75,0x74,0x74,0x69,0x6E,
+	0x67,0x20,0x69,0x73,0x20,0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C,
+	0x6C,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x50,0x2D,0x63,
+	0x6F,0x6C,0x75,0x6D,0x6E,0x20,0x28,0x6F,0x72,0x20,0x54,0x2D,
+	0x63,0x6F,0x6C,0x75,0x6D,0x6E,0x29,0x2E,0x3C,0x3E,0x57,0x68,
+	0x65,0x6E,0x20,0x79,0x6F,0x75,0x20,0x63,0x6F,0x70,0x79,0x20,
+	0x64,0x61,0x74,0x61,0x20,0x77,0x69,0x74,0x68,0x20,0x6D,0x61,
+	0x73,0x6B,0x69,0x6E,0x67,0x2C,0x20,0x74,0x68,0x65,0x20,0x64,
+	0x69,0x73,0x61,0x62,0x6C,0x65,0x64,0x20,0x70,0x61,0x72,0x74,
+	0x73,0x20,0x61,0x72,0x65,0x20,0x6E,0x6F,0x74,0x43,0x63,0x6C,
+	0x65,0x61,0x72,0x65,0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,
+	0x20,0x63,0x6F,0x70,0x79,0x62,0x75,0x66,0x66,0x65,0x72,0x2E,
+	0x20,0x28,0x4D,0x61,0x6B,0x69,0x6E,0x67,0x20,0x69,0x74,0x20,
+	0x70,0x6F,0x73,0x73,0x69,0x62,0x6C,0x65,0x20,0x74,0x6F,0x20,
+	0x63,0x6F,0x6C,0x6C,0x65,0x63,0x74,0x20,0x64,0x61,0x74,0x61,
+	0x20,0x66,0x72,0x6F,0x6D,0x27,0x73,0x65,0x76,0x65,0x72,0x61,
+	0x6C,0x20,0x6C,0x6F,0x63,0x61,0x74,0x69,0x6F,0x6E,0x73,0x20,
+	0x69,0x6E,0x74,0x6F,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x70,
+	0x79,0x62,0x75,0x66,0x66,0x65,0x72,0x2E,0x29,0x00,0x03,0x45,
+	0x4E,0x44,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x4C,0x3B,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
-	0x2A,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
-	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x0E,0x40,0x4C,0x50,0x72,0x6F,
-	0x62,0x6C,0x65,0x6D,0x73,0x2F,0x46,0x41,0x51,0x06,0x3E,0x40,
-	0x58,0x30,0x32,0x30,0x41,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,
-	0x3A,0x20,0x43,0x61,0x6E,0x20,0x49,0x20,0x6D,0x61,0x6B,0x65,
-	0x20,0x66,0x75,0x6C,0x6C,0x73,0x63,0x72,0x65,0x65,0x6E,0x20,
-	0x6D,0x6F,0x64,0x65,0x20,0x73,0x74,0x72,0x65,0x74,0x63,0x68,
-	0x20,0x6F,0x75,0x74,0x20,0x74,0x68,0x65,0x20,0x77,0x68,0x6F,
-	0x6C,0x65,0x20,0x73,0x63,0x72,0x65,0x65,0x6E,0x3F,0x3A,0x3E,
-	0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x45,0x6E,0x61,0x62,
-	0x6C,0x65,0x20,0x22,0x50,0x69,0x78,0x65,0x6C,0x20,0x66,0x69,
-	0x6C,0x74,0x65,0x72,0x22,0x20,0x69,0x6E,0x20,0x43,0x6F,0x6E,
-	0x66,0x69,0x67,0x20,0x2D,0x3E,0x20,0x4D,0x69,0x73,0x63,0x65,
-	0x6C,0x6C,0x61,0x6E,0x65,0x6F,0x75,0x73,0x2E,0x4D,0x3E,0x40,
-	0x58,0x30,0x33,0x35,0x49,0x74,0x20,0x77,0x6F,0x6E,0x27,0x74,
-	0x20,0x6C,0x6F,0x6F,0x6B,0x20,0x70,0x72,0x65,0x74,0x74,0x79,
-	0x2C,0x20,0x62,0x75,0x74,0x20,0x74,0x6F,0x20,0x73,0x6F,0x6D,
-	0x65,0x20,0x70,0x65,0x6F,0x70,0x6C,0x65,0x20,0x69,0x74,0x27,
-	0x73,0x20,0x6D,0x75,0x63,0x68,0x20,0x62,0x65,0x74,0x74,0x65,
-	0x72,0x20,0x74,0x68,0x61,0x6E,0x20,0x6E,0x6F,0x74,0x68,0x69,
-	0x6E,0x67,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x27,0x3E,
-	0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x49,0x20,0x63,0x61,
-	0x6E,0x27,0x74,0x20,0x75,0x73,0x65,0x20,0x41,0x4C,0x54,0x2B,
-	0x46,0x34,0x20,0x61,0x6E,0x64,0x20,0x41,0x4C,0x54,0x2B,0x46,
-	0x35,0x21,0x4E,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,
-	0x57,0x69,0x6E,0x64,0x6F,0x77,0x73,0x3A,0x20,0x49,0x66,0x20,
-	0x79,0x6F,0x75,0x20,0x68,0x61,0x76,0x65,0x20,0x47,0x65,0x46,
-	0x6F,0x72,0x63,0x65,0x20,0x45,0x78,0x70,0x65,0x72,0x69,0x65,
-	0x6E,0x63,0x65,0x20,0x69,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x65,
-	0x64,0x2C,0x20,0x79,0x6F,0x75,0x20,0x6E,0x65,0x65,0x64,0x20,
-	0x74,0x6F,0x20,0x63,0x68,0x61,0x6E,0x67,0x65,0x2B,0x3E,0x40,
-	0x58,0x30,0x33,0x35,0x74,0x68,0x65,0x20,0x6B,0x65,0x79,0x62,
-	0x69,0x6E,0x64,0x69,0x6E,0x67,0x73,0x20,0x69,0x6E,0x20,0x69,
-	0x74,0x73,0x20,0x73,0x65,0x74,0x74,0x69,0x6E,0x67,0x73,0x20,
-	0x70,0x61,0x67,0x65,0x2E,0x56,0x6D,0x61,0x63,0x4F,0x53,0x2F,
-	0x4F,0x53,0x20,0x58,0x3A,0x20,0x43,0x68,0x61,0x6E,0x67,0x65,
-	0x20,0x41,0x4C,0x54,0x2B,0x46,0x34,0x2F,0x41,0x4C,0x54,0x2B,
-	0x46,0x35,0x20,0x6B,0x65,0x79,0x73,0x20,0x69,0x6E,0x20,0x74,
-	0x68,0x65,0x20,0x4F,0x53,0x20,0x74,0x6F,0x20,0x73,0x6F,0x6D,
-	0x65,0x74,0x68,0x69,0x6E,0x67,0x20,0x65,0x6C,0x73,0x65,0x2E,
-	0x20,0x41,0x6C,0x73,0x6F,0x20,0x66,0x6F,0x72,0x20,0x47,0x4E,
-	0x55,0x2F,0x4C,0x69,0x6E,0x75,0x78,0x2E,0x06,0x3E,0x40,0x58,
-	0x30,0x32,0x30,0x2B,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,
-	0x20,0x54,0x68,0x65,0x20,0x6D,0x6F,0x75,0x73,0x65,0x20,0x63,
-	0x75,0x72,0x73,0x6F,0x72,0x20,0x69,0x73,0x20,0x64,0x65,0x6C,
-	0x61,0x79,0x65,0x64,0x2F,0x6C,0x61,0x67,0x67,0x79,0x21,0x44,
-	0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x4D,0x61,0x6B,
-	0x65,0x20,0x73,0x75,0x72,0x65,0x20,0x22,0x53,0x6F,0x66,0x74,
-	0x77,0x61,0x72,0x65,0x20,0x6D,0x6F,0x75,0x73,0x65,0x22,0x20,
-	0x69,0x73,0x20,0x64,0x69,0x73,0x61,0x62,0x6C,0x65,0x64,0x20,
+	0x0E,0x40,0x4C,0x50,0x72,0x6F,0x62,0x6C,0x65,0x6D,0x73,0x2F,
+	0x46,0x41,0x51,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x41,0x3E,
+	0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x43,0x61,0x6E,0x20,
+	0x49,0x20,0x6D,0x61,0x6B,0x65,0x20,0x66,0x75,0x6C,0x6C,0x73,
+	0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,0x73,
+	0x74,0x72,0x65,0x74,0x63,0x68,0x20,0x6F,0x75,0x74,0x20,0x74,
+	0x68,0x65,0x20,0x77,0x68,0x6F,0x6C,0x65,0x20,0x73,0x63,0x72,
+	0x65,0x65,0x6E,0x3F,0x3A,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,
+	0x3A,0x20,0x45,0x6E,0x61,0x62,0x6C,0x65,0x20,0x22,0x50,0x69,
+	0x78,0x65,0x6C,0x20,0x66,0x69,0x6C,0x74,0x65,0x72,0x22,0x20,
 	0x69,0x6E,0x20,0x43,0x6F,0x6E,0x66,0x69,0x67,0x20,0x2D,0x3E,
-	0x20,0x4C,0x61,0x79,0x6F,0x75,0x74,0x2E,0x4B,0x3E,0x40,0x58,
-	0x30,0x33,0x35,0x41,0x6C,0x74,0x65,0x72,0x6E,0x61,0x74,0x69,
-	0x76,0x65,0x6C,0x79,0x2C,0x20,0x79,0x6F,0x75,0x20,0x63,0x61,
-	0x6E,0x20,0x65,0x6E,0x61,0x62,0x6C,0x65,0x20,0x22,0x56,0x53,
-	0x79,0x6E,0x63,0x20,0x6F,0x66,0x66,0x22,0x20,0x69,0x6E,0x20,
-	0x43,0x6F,0x6E,0x66,0x69,0x67,0x20,0x2D,0x3E,0x20,0x4D,0x69,
-	0x73,0x63,0x65,0x6C,0x6C,0x61,0x6E,0x65,0x6F,0x75,0x73,0x2E,
-	0x46,0x3E,0x54,0x68,0x69,0x73,0x20,0x68,0x6F,0x77,0x65,0x76,
-	0x65,0x72,0x2C,0x20,0x77,0x69,0x6C,0x6C,0x20,0x69,0x6E,0x74,
-	0x72,0x6F,0x64,0x75,0x63,0x65,0x20,0x73,0x74,0x75,0x74,0x74,
-	0x65,0x72,0x69,0x6E,0x67,0x20,0x62,0x65,0x63,0x61,0x75,0x73,
-	0x65,0x20,0x74,0x68,0x65,0x20,0x72,0x65,0x6E,0x64,0x65,0x72,
-	0x69,0x6E,0x67,0x20,0x72,0x61,0x74,0x65,0x20,0x69,0x73,0x22,
-	0x3E,0x6E,0x6F,0x74,0x20,0x65,0x78,0x61,0x63,0x74,0x20,0x74,
-	0x6F,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,
-	0x6F,0x72,0x27,0x73,0x20,0x72,0x61,0x74,0x65,0x2E,0x06,0x3E,
-	0x40,0x58,0x30,0x32,0x30,0x33,0x3E,0x40,0x43,0x30,0x30,0x31,
-	0x51,0x3A,0x20,0x57,0x69,0x6C,0x6C,0x20,0x79,0x6F,0x75,0x20,
-	0x69,0x6D,0x70,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x20,0x4D,0x49,
-	0x44,0x49,0x20,0x6F,0x75,0x74,0x20,0x66,0x75,0x6E,0x63,0x74,
-	0x69,0x6F,0x6E,0x61,0x6C,0x69,0x74,0x79,0x3F,0x4D,0x3E,0x40,
-	0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x4E,0x6F,0x2C,0x20,0x73,
-	0x6F,0x72,0x72,0x79,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,0x69,
-	0x73,0x20,0x76,0x65,0x72,0x79,0x20,0x64,0x69,0x66,0x66,0x69,
-	0x63,0x75,0x6C,0x74,0x20,0x74,0x6F,0x20,0x69,0x6D,0x70,0x6C,
-	0x65,0x6D,0x65,0x6E,0x74,0x20,0x63,0x6F,0x72,0x72,0x65,0x63,
-	0x74,0x6C,0x79,0x20,0x77,0x68,0x65,0x6E,0x20,0x68,0x61,0x76,
-	0x69,0x6E,0x67,0x3C,0x3E,0x40,0x58,0x30,0x33,0x35,0x68,0x69,
-	0x67,0x68,0x65,0x72,0x20,0x61,0x75,0x64,0x69,0x6F,0x20,0x62,
-	0x75,0x66,0x66,0x65,0x72,0x20,0x73,0x69,0x7A,0x65,0x73,0x20,
-	0x28,0x62,0x75,0x66,0x66,0x65,0x72,0x65,0x64,0x20,0x72,0x65,
-	0x70,0x6C,0x61,0x79,0x65,0x72,0x20,0x74,0x69,0x63,0x6B,0x73,
-	0x29,0x2E,0x2E,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x30,
-	0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x57,0x68,0x65,
-	0x72,0x65,0x20,0x69,0x73,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,
-	0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x20,
-	0x66,0x69,0x6C,0x65,0x20,0x73,0x74,0x6F,0x72,0x65,0x64,0x3F,
-	0x3F,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x57,0x69,
-	0x6E,0x64,0x6F,0x77,0x73,0x3A,0x20,0x5C,0x55,0x73,0x65,0x72,
-	0x73,0x5C,0x55,0x53,0x45,0x52,0x5C,0x41,0x70,0x70,0x44,0x61,
-	0x74,0x61,0x5C,0x52,0x6F,0x61,0x6D,0x69,0x6E,0x67,0x5C,0x46,
-	0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65,0x5C,0x46,0x54,0x32,
-	0x2E,0x43,0x46,0x47,0x45,0x3E,0x40,0x58,0x30,0x33,0x35,0x4F,
-	0x53,0x20,0x58,0x3A,0x20,0x2F,0x55,0x73,0x65,0x72,0x73,0x2F,
-	0x55,0x53,0x45,0x52,0x2F,0x4C,0x69,0x62,0x72,0x61,0x72,0x79,
-	0x2F,0x41,0x70,0x70,0x6C,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,
-	0x20,0x53,0x75,0x70,0x70,0x6F,0x72,0x74,0x2F,0x46,0x54,0x32,
-	0x20,0x63,0x6C,0x6F,0x6E,0x65,0x2F,0x46,0x54,0x32,0x2E,0x43,
-	0x46,0x47,0x2F,0x47,0x4E,0x55,0x2F,0x4C,0x69,0x6E,0x75,0x78,
-	0x3A,0x20,0x2F,0x68,0x6F,0x6D,0x65,0x2F,0x55,0x53,0x45,0x52,
-	0x2F,0x2E,0x63,0x6F,0x6E,0x66,0x69,0x67,0x2F,0x46,0x54,0x32,
-	0x20,0x63,0x6C,0x6F,0x6E,0x65,0x2F,0x46,0x54,0x32,0x2E,0x43,
-	0x46,0x47,0x01,0x3E,0x48,0x49,0x74,0x20,0x77,0x69,0x6C,0x6C,
-	0x20,0x62,0x65,0x20,0x73,0x74,0x6F,0x72,0x65,0x64,0x20,0x69,
-	0x6E,0x20,0x74,0x68,0x65,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,
-	0x6D,0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,0x72,0x79,0x20,
-	0x69,0x66,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x74,0x68,0x20,
-	0x63,0x6F,0x75,0x6C,0x64,0x6E,0x27,0x74,0x20,0x62,0x65,0x20,
-	0x75,0x73,0x65,0x64,0x2E,0x4D,0x49,0x66,0x20,0x79,0x6F,0x75,
-	0x20,0x70,0x75,0x74,0x20,0x74,0x68,0x65,0x20,0x63,0x6F,0x6E,
-	0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x20,0x66,
-	0x69,0x6C,0x65,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x70,
-	0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x64,0x69,0x72,0x65,0x63,
-	0x74,0x6F,0x72,0x79,0x2C,0x20,0x69,0x74,0x20,0x77,0x69,0x6C,
-	0x6C,0x20,0x72,0x65,0x61,0x64,0x20,0x74,0x68,0x61,0x74,0x4A,
-	0x6F,0x6E,0x65,0x20,0x61,0x6E,0x64,0x20,0x6E,0x6F,0x74,0x20,
-	0x61,0x74,0x74,0x65,0x6D,0x70,0x74,0x20,0x74,0x6F,0x20,0x63,
-	0x72,0x65,0x61,0x74,0x65,0x20,0x63,0x6F,0x6E,0x66,0x69,0x67,
-	0x20,0x64,0x69,0x72,0x73,0x20,0x66,0x6F,0x72,0x20,0x74,0x68,
-	0x65,0x20,0x4F,0x53,0x20,0x75,0x73,0x65,0x72,0x2E,0x20,0x28,
-	0x70,0x6F,0x72,0x74,0x61,0x62,0x6C,0x65,0x20,0x6D,0x6F,0x64,
-	0x65,0x29,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x42,0x3E,0x40,
-	0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x43,0x61,0x6E,0x20,0x74,
-	0x68,0x65,0x20,0x63,0x6C,0x6F,0x6E,0x65,0x20,0x72,0x65,0x61,
-	0x64,0x20,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x20,0x66,0x72,
-	0x6F,0x6D,0x20,0x72,0x65,0x61,0x6C,0x20,0x46,0x54,0x32,0x2C,
-	0x20,0x61,0x6E,0x64,0x20,0x76,0x69,0x63,0x65,0x20,0x76,0x65,
-	0x72,0x73,0x61,0x3F,0x4C,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,
-	0x3A,0x20,0x59,0x65,0x73,0x2C,0x20,0x69,0x74,0x20,0x73,0x68,
-	0x6F,0x75,0x6C,0x64,0x20,0x77,0x6F,0x72,0x6B,0x20,0x6A,0x75,
-	0x73,0x74,0x20,0x66,0x69,0x6E,0x65,0x2E,0x20,0x50,0x75,0x74,
-	0x20,0x69,0x74,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x64,
-	0x69,0x72,0x65,0x63,0x74,0x6F,0x72,0x79,0x20,0x73,0x68,0x6F,
-	0x77,0x6E,0x20,0x61,0x62,0x6F,0x76,0x65,0x2E,0x06,0x3E,0x40,
-	0x58,0x30,0x32,0x30,0x52,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,
-	0x3A,0x20,0x53,0x6D,0x70,0x2E,0x20,0x45,0x64,0x2E,0x3A,0x20,
-	0x57,0x68,0x69,0x6C,0x65,0x20,0x7A,0x6F,0x6F,0x6D,0x69,0x6E,
-	0x67,0x20,0x69,0x6E,0x2C,0x20,0x49,0x20,0x73,0x6F,0x6D,0x65,
-	0x74,0x69,0x6D,0x65,0x73,0x20,0x63,0x61,0x6E,0x27,0x74,0x20,
-	0x6D,0x61,0x72,0x6B,0x20,0x74,0x68,0x65,0x20,0x6C,0x61,0x73,
-	0x74,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,0x70,0x6F,0x69,
-	0x6E,0x74,0x21,0x47,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,
-	0x20,0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x6E,0x6F,0x72,
-	0x6D,0x61,0x6C,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,0x69,0x73,
-	0x20,0x61,0x20,0x6C,0x69,0x6D,0x69,0x74,0x61,0x74,0x69,0x6F,
-	0x6E,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x6E,0x61,0x74,
-	0x75,0x72,0x65,0x20,0x6F,0x66,0x20,0x73,0x63,0x61,0x6C,0x69,
-	0x6E,0x67,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x17,0x3E,
-	0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x49,0x20,0x66,0x6F,
-	0x75,0x6E,0x64,0x20,0x61,0x20,0x62,0x75,0x67,0x21,0x4B,0x3E,
-	0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x50,0x6C,0x65,0x61,
-	0x73,0x65,0x20,0x73,0x65,0x6E,0x64,0x20,0x61,0x20,0x6D,0x61,
-	0x69,0x6C,0x20,0x74,0x6F,0x20,0x6F,0x6C,0x61,0x76,0x2E,0x73,
-	0x6F,0x72,0x65,0x6E,0x73,0x65,0x6E,0x40,0x6C,0x69,0x76,0x65,
-	0x2E,0x6E,0x6F,0x20,0x61,0x6E,0x64,0x20,0x74,0x72,0x79,0x20,
-	0x74,0x6F,0x20,0x65,0x78,0x70,0x6C,0x61,0x69,0x6E,0x20,0x69,
-	0x74,0x2E,0x00,0x03,0x45,0x4E,0x44,0x4C,0x3B,0x2A,0x2A,0x2A,
+	0x20,0x4D,0x69,0x73,0x63,0x65,0x6C,0x6C,0x61,0x6E,0x65,0x6F,
+	0x75,0x73,0x2E,0x4D,0x3E,0x40,0x58,0x30,0x33,0x35,0x49,0x74,
+	0x20,0x77,0x6F,0x6E,0x27,0x74,0x20,0x6C,0x6F,0x6F,0x6B,0x20,
+	0x70,0x72,0x65,0x74,0x74,0x79,0x2C,0x20,0x62,0x75,0x74,0x20,
+	0x74,0x6F,0x20,0x73,0x6F,0x6D,0x65,0x20,0x70,0x65,0x6F,0x70,
+	0x6C,0x65,0x20,0x69,0x74,0x27,0x73,0x20,0x6D,0x75,0x63,0x68,
+	0x20,0x62,0x65,0x74,0x74,0x65,0x72,0x20,0x74,0x68,0x61,0x6E,
+	0x20,0x6E,0x6F,0x74,0x68,0x69,0x6E,0x67,0x2E,0x06,0x3E,0x40,
+	0x58,0x30,0x32,0x30,0x27,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,
+	0x3A,0x20,0x49,0x20,0x63,0x61,0x6E,0x27,0x74,0x20,0x75,0x73,
+	0x65,0x20,0x41,0x4C,0x54,0x2B,0x46,0x34,0x20,0x61,0x6E,0x64,
+	0x20,0x41,0x4C,0x54,0x2B,0x46,0x35,0x21,0x4E,0x3E,0x40,0x43,
+	0x30,0x30,0x32,0x41,0x3A,0x20,0x57,0x69,0x6E,0x64,0x6F,0x77,
+	0x73,0x3A,0x20,0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x68,0x61,
+	0x76,0x65,0x20,0x47,0x65,0x46,0x6F,0x72,0x63,0x65,0x20,0x45,
+	0x78,0x70,0x65,0x72,0x69,0x65,0x6E,0x63,0x65,0x20,0x69,0x6E,
+	0x73,0x74,0x61,0x6C,0x6C,0x65,0x64,0x2C,0x20,0x79,0x6F,0x75,
+	0x20,0x6E,0x65,0x65,0x64,0x20,0x74,0x6F,0x20,0x63,0x68,0x61,
+	0x6E,0x67,0x65,0x2B,0x3E,0x40,0x58,0x30,0x33,0x35,0x74,0x68,
+	0x65,0x20,0x6B,0x65,0x79,0x62,0x69,0x6E,0x64,0x69,0x6E,0x67,
+	0x73,0x20,0x69,0x6E,0x20,0x69,0x74,0x73,0x20,0x73,0x65,0x74,
+	0x74,0x69,0x6E,0x67,0x73,0x20,0x70,0x61,0x67,0x65,0x2E,0x56,
+	0x6D,0x61,0x63,0x4F,0x53,0x2F,0x4F,0x53,0x20,0x58,0x3A,0x20,
+	0x43,0x68,0x61,0x6E,0x67,0x65,0x20,0x41,0x4C,0x54,0x2B,0x46,
+	0x34,0x2F,0x41,0x4C,0x54,0x2B,0x46,0x35,0x20,0x6B,0x65,0x79,
+	0x73,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x4F,0x53,0x20,
+	0x74,0x6F,0x20,0x73,0x6F,0x6D,0x65,0x74,0x68,0x69,0x6E,0x67,
+	0x20,0x65,0x6C,0x73,0x65,0x2E,0x20,0x41,0x6C,0x73,0x6F,0x20,
+	0x66,0x6F,0x72,0x20,0x47,0x4E,0x55,0x2F,0x4C,0x69,0x6E,0x75,
+	0x78,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x2B,0x3E,0x40,
+	0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x54,0x68,0x65,0x20,0x6D,
+	0x6F,0x75,0x73,0x65,0x20,0x63,0x75,0x72,0x73,0x6F,0x72,0x20,
+	0x69,0x73,0x20,0x64,0x65,0x6C,0x61,0x79,0x65,0x64,0x2F,0x6C,
+	0x61,0x67,0x67,0x79,0x21,0x44,0x3E,0x40,0x43,0x30,0x30,0x32,
+	0x41,0x3A,0x20,0x4D,0x61,0x6B,0x65,0x20,0x73,0x75,0x72,0x65,
+	0x20,0x22,0x53,0x6F,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x6D,
+	0x6F,0x75,0x73,0x65,0x22,0x20,0x69,0x73,0x20,0x64,0x69,0x73,
+	0x61,0x62,0x6C,0x65,0x64,0x20,0x69,0x6E,0x20,0x43,0x6F,0x6E,
+	0x66,0x69,0x67,0x20,0x2D,0x3E,0x20,0x4C,0x61,0x79,0x6F,0x75,
+	0x74,0x2E,0x4B,0x3E,0x40,0x58,0x30,0x33,0x35,0x41,0x6C,0x74,
+	0x65,0x72,0x6E,0x61,0x74,0x69,0x76,0x65,0x6C,0x79,0x2C,0x20,
+	0x79,0x6F,0x75,0x20,0x63,0x61,0x6E,0x20,0x65,0x6E,0x61,0x62,
+	0x6C,0x65,0x20,0x22,0x56,0x53,0x79,0x6E,0x63,0x20,0x6F,0x66,
+	0x66,0x22,0x20,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x66,0x69,0x67,
+	0x20,0x2D,0x3E,0x20,0x4D,0x69,0x73,0x63,0x65,0x6C,0x6C,0x61,
+	0x6E,0x65,0x6F,0x75,0x73,0x2E,0x46,0x3E,0x54,0x68,0x69,0x73,
+	0x20,0x68,0x6F,0x77,0x65,0x76,0x65,0x72,0x2C,0x20,0x77,0x69,
+	0x6C,0x6C,0x20,0x69,0x6E,0x74,0x72,0x6F,0x64,0x75,0x63,0x65,
+	0x20,0x73,0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,0x67,0x20,
+	0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x74,0x68,0x65,0x20,
+	0x72,0x65,0x6E,0x64,0x65,0x72,0x69,0x6E,0x67,0x20,0x72,0x61,
+	0x74,0x65,0x20,0x69,0x73,0x22,0x3E,0x6E,0x6F,0x74,0x20,0x65,
+	0x78,0x61,0x63,0x74,0x20,0x74,0x6F,0x20,0x79,0x6F,0x75,0x72,
+	0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27,0x73,0x20,0x72,
+	0x61,0x74,0x65,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x33,
+	0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x57,0x69,0x6C,
+	0x6C,0x20,0x79,0x6F,0x75,0x20,0x69,0x6D,0x70,0x6C,0x65,0x6D,
+	0x65,0x6E,0x74,0x20,0x4D,0x49,0x44,0x49,0x20,0x6F,0x75,0x74,
+	0x20,0x66,0x75,0x6E,0x63,0x74,0x69,0x6F,0x6E,0x61,0x6C,0x69,
+	0x74,0x79,0x3F,0x4D,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,0x3A,
+	0x20,0x4E,0x6F,0x2C,0x20,0x73,0x6F,0x72,0x72,0x79,0x2E,0x20,
+	0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x76,0x65,0x72,0x79,
+	0x20,0x64,0x69,0x66,0x66,0x69,0x63,0x75,0x6C,0x74,0x20,0x74,
+	0x6F,0x20,0x69,0x6D,0x70,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x20,
+	0x63,0x6F,0x72,0x72,0x65,0x63,0x74,0x6C,0x79,0x20,0x77,0x68,
+	0x65,0x6E,0x20,0x68,0x61,0x76,0x69,0x6E,0x67,0x3C,0x3E,0x40,
+	0x58,0x30,0x33,0x35,0x68,0x69,0x67,0x68,0x65,0x72,0x20,0x61,
+	0x75,0x64,0x69,0x6F,0x20,0x62,0x75,0x66,0x66,0x65,0x72,0x20,
+	0x73,0x69,0x7A,0x65,0x73,0x20,0x28,0x62,0x75,0x66,0x66,0x65,
+	0x72,0x65,0x64,0x20,0x72,0x65,0x70,0x6C,0x61,0x79,0x65,0x72,
+	0x20,0x74,0x69,0x63,0x6B,0x73,0x29,0x2E,0x2E,0x2E,0x06,0x3E,
+	0x40,0x58,0x30,0x32,0x30,0x30,0x3E,0x40,0x43,0x30,0x30,0x31,
+	0x51,0x3A,0x20,0x57,0x68,0x65,0x72,0x65,0x20,0x69,0x73,0x20,
+	0x74,0x68,0x65,0x20,0x63,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,
+	0x61,0x74,0x69,0x6F,0x6E,0x20,0x66,0x69,0x6C,0x65,0x20,0x73,
+	0x74,0x6F,0x72,0x65,0x64,0x3F,0x3F,0x3E,0x40,0x43,0x30,0x30,
+	0x32,0x41,0x3A,0x20,0x57,0x69,0x6E,0x64,0x6F,0x77,0x73,0x3A,
+	0x20,0x5C,0x55,0x73,0x65,0x72,0x73,0x5C,0x55,0x53,0x45,0x52,
+	0x5C,0x41,0x70,0x70,0x44,0x61,0x74,0x61,0x5C,0x52,0x6F,0x61,
+	0x6D,0x69,0x6E,0x67,0x5C,0x46,0x54,0x32,0x20,0x63,0x6C,0x6F,
+	0x6E,0x65,0x5C,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x45,0x3E,
+	0x40,0x58,0x30,0x33,0x35,0x4F,0x53,0x20,0x58,0x3A,0x20,0x2F,
+	0x55,0x73,0x65,0x72,0x73,0x2F,0x55,0x53,0x45,0x52,0x2F,0x4C,
+	0x69,0x62,0x72,0x61,0x72,0x79,0x2F,0x41,0x70,0x70,0x6C,0x69,
+	0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x75,0x70,0x70,0x6F,
+	0x72,0x74,0x2F,0x46,0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65,
+	0x2F,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x2F,0x47,0x4E,0x55,
+	0x2F,0x4C,0x69,0x6E,0x75,0x78,0x3A,0x20,0x2F,0x68,0x6F,0x6D,
+	0x65,0x2F,0x55,0x53,0x45,0x52,0x2F,0x2E,0x63,0x6F,0x6E,0x66,
+	0x69,0x67,0x2F,0x46,0x54,0x32,0x20,0x63,0x6C,0x6F,0x6E,0x65,
+	0x2F,0x46,0x54,0x32,0x2E,0x43,0x46,0x47,0x01,0x3E,0x48,0x49,
+	0x74,0x20,0x77,0x69,0x6C,0x6C,0x20,0x62,0x65,0x20,0x73,0x74,
+	0x6F,0x72,0x65,0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,
+	0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x64,0x69,0x72,0x65,
+	0x63,0x74,0x6F,0x72,0x79,0x20,0x69,0x66,0x20,0x74,0x68,0x65,
+	0x20,0x70,0x61,0x74,0x68,0x20,0x63,0x6F,0x75,0x6C,0x64,0x6E,
+	0x27,0x74,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x2E,0x4D,
+	0x49,0x66,0x20,0x79,0x6F,0x75,0x20,0x70,0x75,0x74,0x20,0x74,
+	0x68,0x65,0x20,0x63,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,
+	0x74,0x69,0x6F,0x6E,0x20,0x66,0x69,0x6C,0x65,0x20,0x69,0x6E,
+	0x20,0x74,0x68,0x65,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,
+	0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,0x72,0x79,0x2C,0x20,
+	0x69,0x74,0x20,0x77,0x69,0x6C,0x6C,0x20,0x72,0x65,0x61,0x64,
+	0x20,0x74,0x68,0x61,0x74,0x4A,0x6F,0x6E,0x65,0x20,0x61,0x6E,
+	0x64,0x20,0x6E,0x6F,0x74,0x20,0x61,0x74,0x74,0x65,0x6D,0x70,
+	0x74,0x20,0x74,0x6F,0x20,0x63,0x72,0x65,0x61,0x74,0x65,0x20,
+	0x63,0x6F,0x6E,0x66,0x69,0x67,0x20,0x64,0x69,0x72,0x73,0x20,
+	0x66,0x6F,0x72,0x20,0x74,0x68,0x65,0x20,0x4F,0x53,0x20,0x75,
+	0x73,0x65,0x72,0x2E,0x20,0x28,0x70,0x6F,0x72,0x74,0x61,0x62,
+	0x6C,0x65,0x20,0x6D,0x6F,0x64,0x65,0x29,0x06,0x3E,0x40,0x58,
+	0x30,0x32,0x30,0x42,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,0x3A,
+	0x20,0x43,0x61,0x6E,0x20,0x74,0x68,0x65,0x20,0x63,0x6C,0x6F,
+	0x6E,0x65,0x20,0x72,0x65,0x61,0x64,0x20,0x46,0x54,0x32,0x2E,
+	0x43,0x46,0x47,0x20,0x66,0x72,0x6F,0x6D,0x20,0x72,0x65,0x61,
+	0x6C,0x20,0x46,0x54,0x32,0x2C,0x20,0x61,0x6E,0x64,0x20,0x76,
+	0x69,0x63,0x65,0x20,0x76,0x65,0x72,0x73,0x61,0x3F,0x4C,0x3E,
+	0x40,0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x59,0x65,0x73,0x2C,
+	0x20,0x69,0x74,0x20,0x73,0x68,0x6F,0x75,0x6C,0x64,0x20,0x77,
+	0x6F,0x72,0x6B,0x20,0x6A,0x75,0x73,0x74,0x20,0x66,0x69,0x6E,
+	0x65,0x2E,0x20,0x50,0x75,0x74,0x20,0x69,0x74,0x20,0x69,0x6E,
+	0x20,0x74,0x68,0x65,0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,
+	0x72,0x79,0x20,0x73,0x68,0x6F,0x77,0x6E,0x20,0x61,0x62,0x6F,
+	0x76,0x65,0x2E,0x06,0x3E,0x40,0x58,0x30,0x32,0x30,0x52,0x3E,
+	0x40,0x43,0x30,0x30,0x31,0x51,0x3A,0x20,0x53,0x6D,0x70,0x2E,
+	0x20,0x45,0x64,0x2E,0x3A,0x20,0x57,0x68,0x69,0x6C,0x65,0x20,
+	0x7A,0x6F,0x6F,0x6D,0x69,0x6E,0x67,0x20,0x69,0x6E,0x2C,0x20,
+	0x49,0x20,0x73,0x6F,0x6D,0x65,0x74,0x69,0x6D,0x65,0x73,0x20,
+	0x63,0x61,0x6E,0x27,0x74,0x20,0x6D,0x61,0x72,0x6B,0x20,0x74,
+	0x68,0x65,0x20,0x6C,0x61,0x73,0x74,0x20,0x73,0x61,0x6D,0x70,
+	0x6C,0x65,0x20,0x70,0x6F,0x69,0x6E,0x74,0x21,0x47,0x3E,0x40,
+	0x43,0x30,0x30,0x32,0x41,0x3A,0x20,0x54,0x68,0x69,0x73,0x20,
+	0x69,0x73,0x20,0x6E,0x6F,0x72,0x6D,0x61,0x6C,0x2E,0x20,0x54,
+	0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x61,0x20,0x6C,0x69,0x6D,
+	0x69,0x74,0x61,0x74,0x69,0x6F,0x6E,0x20,0x69,0x6E,0x20,0x74,
+	0x68,0x65,0x20,0x6E,0x61,0x74,0x75,0x72,0x65,0x20,0x6F,0x66,
+	0x20,0x73,0x63,0x61,0x6C,0x69,0x6E,0x67,0x2E,0x06,0x3E,0x40,
+	0x58,0x30,0x32,0x30,0x17,0x3E,0x40,0x43,0x30,0x30,0x31,0x51,
+	0x3A,0x20,0x49,0x20,0x66,0x6F,0x75,0x6E,0x64,0x20,0x61,0x20,
+	0x62,0x75,0x67,0x21,0x4B,0x3E,0x40,0x43,0x30,0x30,0x32,0x41,
+	0x3A,0x20,0x50,0x6C,0x65,0x61,0x73,0x65,0x20,0x73,0x65,0x6E,
+	0x64,0x20,0x61,0x20,0x6D,0x61,0x69,0x6C,0x20,0x74,0x6F,0x20,
+	0x6F,0x6C,0x61,0x76,0x2E,0x73,0x6F,0x72,0x65,0x6E,0x73,0x65,
+	0x6E,0x40,0x6C,0x69,0x76,0x65,0x2E,0x6E,0x6F,0x20,0x61,0x6E,
+	0x64,0x20,0x74,0x72,0x79,0x20,0x74,0x6F,0x20,0x65,0x78,0x70,
+	0x6C,0x61,0x69,0x6E,0x20,0x69,0x74,0x2E,0x00,0x03,0x45,0x4E,
+	0x44,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
+	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
-	0x4C,0x3B,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
 	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
-	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
-	0x2A,0x2A,0x2A,0x2A,0x2A,0x0C,0x40,0x4C,0x4B,0x6E,0x6F,0x77,
-	0x6E,0x20,0x62,0x75,0x67,0x73,0x06,0x3E,0x40,0x58,0x30,0x31,
-	0x30,0x14,0x3E,0x40,0x43,0x30,0x30,0x31,0x53,0x61,0x6D,0x70,
-	0x6C,0x65,0x20,0x65,0x64,0x69,0x74,0x6F,0x72,0x3A,0x06,0x3E,
-	0x40,0x43,0x30,0x30,0x32,0x4E,0x3E,0x40,0x58,0x30,0x31,0x30,
-	0x2D,0x20,0x57,0x68,0x65,0x6E,0x20,0x61,0x20,0x6C,0x6F,0x6F,
-	0x70,0x65,0x64,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,0x69,
-	0x73,0x20,0x7A,0x6F,0x6F,0x6D,0x65,0x64,0x20,0x6F,0x75,0x74,
-	0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x73,0x61,0x6D,0x70,
-	0x6C,0x65,0x20,0x65,0x64,0x69,0x74,0x6F,0x72,0x2C,0x20,0x79,
-	0x6F,0x75,0x20,0x63,0x6F,0x75,0x6C,0x64,0x20,0x73,0x65,0x65,
-	0x4D,0x3E,0x40,0x58,0x30,0x32,0x31,0x75,0x6E,0x77,0x61,0x6E,
-	0x74,0x65,0x64,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,0x64,
-	0x61,0x74,0x61,0x20,0x61,0x74,0x20,0x74,0x68,0x65,0x20,0x6C,
-	0x6F,0x6F,0x70,0x2D,0x65,0x6E,0x64,0x20,0x70,0x6F,0x69,0x6E,
-	0x74,0x2E,0x20,0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x62,
-	0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x6F,0x66,0x20,0x61,0x20,
-	0x6B,0x6C,0x75,0x64,0x67,0x65,0x4B,0x66,0x6F,0x72,0x20,0x74,
-	0x68,0x65,0x20,0x72,0x65,0x73,0x61,0x6D,0x70,0x6C,0x69,0x6E,
-	0x67,0x20,0x69,0x6E,0x74,0x65,0x72,0x70,0x6F,0x6C,0x61,0x74,
-	0x69,0x6F,0x6E,0x20,0x74,0x6F,0x20,0x77,0x6F,0x72,0x6B,0x20,
-	0x66,0x61,0x73,0x74,0x65,0x72,0x20,0x69,0x6E,0x20,0x74,0x68,
-	0x65,0x20,0x61,0x75,0x64,0x69,0x6F,0x20,0x6D,0x69,0x78,0x65,
-	0x72,0x2C,0x20,0x61,0x6E,0x64,0x20,0x74,0x68,0x65,0x4B,0x6F,
-	0x72,0x69,0x67,0x69,0x6E,0x61,0x6C,0x20,0x46,0x54,0x32,0x20,
-	0x68,0x61,0x73,0x20,0x74,0x68,0x65,0x20,0x73,0x61,0x6D,0x65,
-	0x20,0x70,0x72,0x6F,0x62,0x6C,0x65,0x6D,0x2E,0x20,0x49,0x20,
-	0x68,0x61,0x76,0x65,0x20,0x6D,0x61,0x64,0x65,0x20,0x69,0x74,
-	0x20,0x73,0x6F,0x20,0x74,0x68,0x61,0x74,0x20,0x69,0x66,0x20,
-	0x79,0x6F,0x75,0x20,0x7A,0x6F,0x6F,0x6D,0x20,0x69,0x6E,0x20,
-	0x74,0x6F,0x3B,0x73,0x65,0x65,0x20,0x74,0x68,0x65,0x20,0x69,
-	0x6E,0x64,0x69,0x76,0x69,0x64,0x75,0x61,0x6C,0x20,0x73,0x61,
-	0x6D,0x70,0x6C,0x65,0x20,0x70,0x6F,0x69,0x6E,0x74,0x73,0x2C,
-	0x20,0x69,0x74,0x20,0x77,0x69,0x6C,0x6C,0x20,0x6C,0x6F,0x6F,
-	0x6B,0x20,0x6C,0x69,0x6B,0x65,0x20,0x6E,0x6F,0x72,0x6D,0x61,
-	0x6C,0x2E,0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x17,0x3E,0x40,
-	0x43,0x30,0x30,0x31,0x4D,0x6F,0x75,0x73,0x65,0x20,0x2F,0x20,
-	0x6B,0x65,0x79,0x62,0x6F,0x61,0x72,0x64,0x3A,0x01,0x3E,0x43,
-	0x3E,0x40,0x43,0x30,0x30,0x32,0x2D,0x20,0x4C,0x69,0x6E,0x75,
-	0x78,0x3A,0x20,0x54,0x68,0x65,0x20,0x6D,0x6F,0x75,0x73,0x65,
-	0x20,0x63,0x75,0x72,0x73,0x6F,0x72,0x20,0x67,0x72,0x61,0x70,
-	0x68,0x69,0x63,0x73,0x20,0x63,0x61,0x6E,0x20,0x62,0x65,0x20,
-	0x67,0x6C,0x69,0x74,0x63,0x68,0x79,0x20,0x61,0x74,0x20,0x74,
-	0x69,0x6D,0x65,0x73,0x2E,0x2E,0x2E,0x06,0x3E,0x40,0x58,0x30,
-	0x31,0x30,0x4B,0x3E,0x40,0x43,0x30,0x30,0x32,0x2D,0x20,0x54,
-	0x68,0x65,0x20,0x22,0x63,0x6C,0x65,0x61,0x72,0x20,0x73,0x61,
-	0x6D,0x70,0x6C,0x65,0x22,0x20,0x73,0x68,0x6F,0x72,0x74,0x63,
-	0x75,0x74,0x20,0x28,0x73,0x68,0x69,0x66,0x74,0x20,0x2B,0x20,
-	0x6E,0x75,0x6D,0x2D,0x70,0x61,0x64,0x20,0x44,0x65,0x6C,0x2F,
-	0x27,0x2C,0x27,0x29,0x20,0x6F,0x6E,0x6C,0x79,0x20,0x77,0x6F,
-	0x72,0x6B,0x73,0x20,0x69,0x66,0x37,0x3E,0x40,0x58,0x30,0x32,
-	0x31,0x6E,0x75,0x6D,0x20,0x6C,0x6F,0x63,0x6B,0x20,0x69,0x73,
-	0x20,0x6F,0x66,0x66,0x2E,0x20,0x54,0x68,0x65,0x72,0x65,0x27,
-	0x73,0x20,0x6E,0x6F,0x20,0x77,0x61,0x79,0x20,0x49,0x20,0x63,
-	0x61,0x6E,0x20,0x66,0x69,0x78,0x20,0x74,0x68,0x69,0x73,0x2E,
-	0x2E,0x2E,0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x0C,0x3E,0x40,
-	0x43,0x30,0x30,0x31,0x56,0x69,0x64,0x65,0x6F,0x3A,0x06,0x3E,
-	0x40,0x43,0x30,0x30,0x32,0x4A,0x3E,0x40,0x58,0x30,0x31,0x30,
-	0x2D,0x20,0x54,0x68,0x65,0x20,0x73,0x63,0x6F,0x70,0x65,0x73,
-	0x20,0x63,0x61,0x6E,0x20,0x6D,0x69,0x6C,0x64,0x6C,0x79,0x20,
-	0x66,0x6C,0x69,0x63,0x6B,0x65,0x72,0x20,0x64,0x65,0x70,0x65,
-	0x6E,0x64,0x69,0x6E,0x67,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,
-	0x20,0x77,0x61,0x76,0x65,0x66,0x6F,0x72,0x6D,0x20,0x61,0x6E,
-	0x64,0x20,0x70,0x69,0x74,0x63,0x68,0x2E,0x4D,0x3E,0x40,0x58,
-	0x30,0x32,0x31,0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x62,
-	0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x74,0x68,0x65,0x69,0x72,
-	0x20,0x66,0x72,0x65,0x71,0x75,0x65,0x6E,0x63,0x79,0x20,0x69,
-	0x73,0x20,0x6E,0x6F,0x74,0x20,0x63,0x6C,0x6F,0x63,0x6B,0x65,
-	0x64,0x20,0x74,0x6F,0x20,0x65,0x78,0x61,0x63,0x74,0x6C,0x79,
-	0x20,0x74,0x68,0x65,0x20,0x73,0x61,0x6D,0x65,0x20,0x72,0x61,
-	0x74,0x65,0x4D,0x3E,0x61,0x74,0x20,0x77,0x68,0x69,0x63,0x68,
-	0x20,0x74,0x68,0x65,0x20,0x73,0x63,0x6F,0x70,0x65,0x73,0x20,
-	0x61,0x72,0x65,0x20,0x72,0x65,0x6E,0x64,0x65,0x72,0x65,0x64,
-	0x2E,0x20,0x49,0x74,0x27,0x73,0x20,0x63,0x6C,0x6F,0x73,0x65,
-	0x2C,0x20,0x77,0x68,0x69,0x63,0x68,0x20,0x63,0x61,0x75,0x73,
-	0x65,0x73,0x20,0x61,0x20,0x66,0x6C,0x69,0x63,0x6B,0x65,0x72,
-	0x20,0x65,0x66,0x66,0x65,0x63,0x74,0x2E,0x01,0x3E,0x52,0x3E,
-	0x40,0x58,0x30,0x31,0x30,0x2D,0x20,0x4E,0x6F,0x74,0x20,0x61,
-	0x20,0x62,0x75,0x67,0x2C,0x20,0x62,0x75,0x74,0x20,0x69,0x66,
-	0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,
-	0x72,0x27,0x73,0x20,0x72,0x65,0x66,0x72,0x65,0x73,0x68,0x20,
-	0x72,0x61,0x74,0x65,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,
-	0x73,0x65,0x74,0x20,0x74,0x6F,0x20,0x36,0x30,0x48,0x7A,0x20,
-	0x28,0x6F,0x72,0x20,0x35,0x39,0x48,0x7A,0x29,0x4F,0x3E,0x40,
-	0x58,0x30,0x32,0x31,0x79,0x6F,0x75,0x20,0x6D,0x61,0x79,0x20,
-	0x65,0x78,0x70,0x65,0x72,0x69,0x65,0x6E,0x63,0x65,0x20,0x76,
-	0x69,0x73,0x75,0x61,0x6C,0x20,0x73,0x74,0x75,0x74,0x74,0x65,
-	0x72,0x69,0x6E,0x67,0x20,0x62,0x65,0x63,0x61,0x75,0x73,0x65,
-	0x20,0x56,0x53,0x79,0x6E,0x63,0x20,0x77,0x69,0x6C,0x6C,0x20,
-	0x6E,0x6F,0x74,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,
-	0x74,0x68,0x65,0x6E,0x2E,0x49,0x49,0x20,0x68,0x69,0x67,0x68,
-	0x6C,0x79,0x20,0x72,0x65,0x63,0x6F,0x6D,0x6D,0x65,0x6E,0x64,
-	0x20,0x72,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x79,0x6F,0x75,
-	0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x20,0x61,0x74,
-	0x20,0x36,0x30,0x48,0x7A,0x20,0x69,0x66,0x20,0x79,0x6F,0x75,
-	0x27,0x72,0x65,0x20,0x61,0x20,0x68,0x61,0x72,0x64,0x63,0x6F,
-	0x72,0x65,0x20,0x75,0x73,0x65,0x72,0x10,0x6F,0x66,0x20,0x74,
-	0x68,0x69,0x73,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x2E,
-	0x00,0x03,0x45,0x4E,0x44
+	0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x0C,
+	0x40,0x4C,0x4B,0x6E,0x6F,0x77,0x6E,0x20,0x62,0x75,0x67,0x73,
+	0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x14,0x3E,0x40,0x43,0x30,
+	0x30,0x31,0x53,0x61,0x6D,0x70,0x6C,0x65,0x20,0x65,0x64,0x69,
+	0x74,0x6F,0x72,0x3A,0x06,0x3E,0x40,0x43,0x30,0x30,0x32,0x4E,
+	0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,0x57,0x68,0x65,0x6E,
+	0x20,0x61,0x20,0x6C,0x6F,0x6F,0x70,0x65,0x64,0x20,0x73,0x61,
+	0x6D,0x70,0x6C,0x65,0x20,0x69,0x73,0x20,0x7A,0x6F,0x6F,0x6D,
+	0x65,0x64,0x20,0x6F,0x75,0x74,0x20,0x69,0x6E,0x20,0x74,0x68,
+	0x65,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,0x65,0x64,0x69,
+	0x74,0x6F,0x72,0x2C,0x20,0x79,0x6F,0x75,0x20,0x63,0x6F,0x75,
+	0x6C,0x64,0x20,0x73,0x65,0x65,0x4D,0x3E,0x40,0x58,0x30,0x32,
+	0x31,0x75,0x6E,0x77,0x61,0x6E,0x74,0x65,0x64,0x20,0x73,0x61,
+	0x6D,0x70,0x6C,0x65,0x20,0x64,0x61,0x74,0x61,0x20,0x61,0x74,
+	0x20,0x74,0x68,0x65,0x20,0x6C,0x6F,0x6F,0x70,0x2D,0x65,0x6E,
+	0x64,0x20,0x70,0x6F,0x69,0x6E,0x74,0x2E,0x20,0x54,0x68,0x69,
+	0x73,0x20,0x69,0x73,0x20,0x62,0x65,0x63,0x61,0x75,0x73,0x65,
+	0x20,0x6F,0x66,0x20,0x61,0x20,0x6B,0x6C,0x75,0x64,0x67,0x65,
+	0x4B,0x66,0x6F,0x72,0x20,0x74,0x68,0x65,0x20,0x72,0x65,0x73,
+	0x61,0x6D,0x70,0x6C,0x69,0x6E,0x67,0x20,0x69,0x6E,0x74,0x65,
+	0x72,0x70,0x6F,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x20,0x74,0x6F,
+	0x20,0x77,0x6F,0x72,0x6B,0x20,0x66,0x61,0x73,0x74,0x65,0x72,
+	0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x61,0x75,0x64,0x69,
+	0x6F,0x20,0x6D,0x69,0x78,0x65,0x72,0x2C,0x20,0x61,0x6E,0x64,
+	0x20,0x74,0x68,0x65,0x4B,0x6F,0x72,0x69,0x67,0x69,0x6E,0x61,
+	0x6C,0x20,0x46,0x54,0x32,0x20,0x68,0x61,0x73,0x20,0x74,0x68,
+	0x65,0x20,0x73,0x61,0x6D,0x65,0x20,0x70,0x72,0x6F,0x62,0x6C,
+	0x65,0x6D,0x2E,0x20,0x49,0x20,0x68,0x61,0x76,0x65,0x20,0x6D,
+	0x61,0x64,0x65,0x20,0x69,0x74,0x20,0x73,0x6F,0x20,0x74,0x68,
+	0x61,0x74,0x20,0x69,0x66,0x20,0x79,0x6F,0x75,0x20,0x7A,0x6F,
+	0x6F,0x6D,0x20,0x69,0x6E,0x20,0x74,0x6F,0x3B,0x73,0x65,0x65,
+	0x20,0x74,0x68,0x65,0x20,0x69,0x6E,0x64,0x69,0x76,0x69,0x64,
+	0x75,0x61,0x6C,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x20,0x70,
+	0x6F,0x69,0x6E,0x74,0x73,0x2C,0x20,0x69,0x74,0x20,0x77,0x69,
+	0x6C,0x6C,0x20,0x6C,0x6F,0x6F,0x6B,0x20,0x6C,0x69,0x6B,0x65,
+	0x20,0x6E,0x6F,0x72,0x6D,0x61,0x6C,0x2E,0x06,0x3E,0x40,0x58,
+	0x30,0x31,0x30,0x17,0x3E,0x40,0x43,0x30,0x30,0x31,0x4D,0x6F,
+	0x75,0x73,0x65,0x20,0x2F,0x20,0x6B,0x65,0x79,0x62,0x6F,0x61,
+	0x72,0x64,0x3A,0x01,0x3E,0x43,0x3E,0x40,0x43,0x30,0x30,0x32,
+	0x2D,0x20,0x4C,0x69,0x6E,0x75,0x78,0x3A,0x20,0x54,0x68,0x65,
+	0x20,0x6D,0x6F,0x75,0x73,0x65,0x20,0x63,0x75,0x72,0x73,0x6F,
+	0x72,0x20,0x67,0x72,0x61,0x70,0x68,0x69,0x63,0x73,0x20,0x63,
+	0x61,0x6E,0x20,0x62,0x65,0x20,0x67,0x6C,0x69,0x74,0x63,0x68,
+	0x79,0x20,0x61,0x74,0x20,0x74,0x69,0x6D,0x65,0x73,0x2E,0x2E,
+	0x2E,0x06,0x3E,0x40,0x58,0x30,0x31,0x30,0x4B,0x3E,0x40,0x43,
+	0x30,0x30,0x32,0x2D,0x20,0x54,0x68,0x65,0x20,0x22,0x63,0x6C,
+	0x65,0x61,0x72,0x20,0x73,0x61,0x6D,0x70,0x6C,0x65,0x22,0x20,
+	0x73,0x68,0x6F,0x72,0x74,0x63,0x75,0x74,0x20,0x28,0x73,0x68,
+	0x69,0x66,0x74,0x20,0x2B,0x20,0x6E,0x75,0x6D,0x2D,0x70,0x61,
+	0x64,0x20,0x44,0x65,0x6C,0x2F,0x27,0x2C,0x27,0x29,0x20,0x6F,
+	0x6E,0x6C,0x79,0x20,0x77,0x6F,0x72,0x6B,0x73,0x20,0x69,0x66,
+	0x37,0x3E,0x40,0x58,0x30,0x32,0x31,0x6E,0x75,0x6D,0x20,0x6C,
+	0x6F,0x63,0x6B,0x20,0x69,0x73,0x20,0x6F,0x66,0x66,0x2E,0x20,
+	0x54,0x68,0x65,0x72,0x65,0x27,0x73,0x20,0x6E,0x6F,0x20,0x77,
+	0x61,0x79,0x20,0x49,0x20,0x63,0x61,0x6E,0x20,0x66,0x69,0x78,
+	0x20,0x74,0x68,0x69,0x73,0x2E,0x2E,0x2E,0x06,0x3E,0x40,0x58,
+	0x30,0x31,0x30,0x0C,0x3E,0x40,0x43,0x30,0x30,0x31,0x56,0x69,
+	0x64,0x65,0x6F,0x3A,0x06,0x3E,0x40,0x43,0x30,0x30,0x32,0x50,
+	0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,0x46,0x75,0x6C,0x6C,
+	0x73,0x63,0x72,0x65,0x65,0x6E,0x20,0x6D,0x6F,0x64,0x65,0x20,
+	0x63,0x61,0x6E,0x20,0x62,0x65,0x20,0x75,0x6E,0x62,0x65,0x61,
+	0x72,0x61,0x62,0x6C,0x79,0x20,0x73,0x6C,0x6F,0x77,0x20,0x6F,
+	0x6E,0x20,0x61,0x20,0x52,0x61,0x73,0x70,0x62,0x65,0x72,0x72,
+	0x79,0x20,0x50,0x69,0x20,0x28,0x65,0x76,0x65,0x6E,0x20,0x61,
+	0x6E,0x20,0x52,0x50,0x69,0x20,0x34,0x29,0x01,0x3E,0x4A,0x3E,
+	0x40,0x58,0x30,0x31,0x30,0x2D,0x20,0x54,0x68,0x65,0x20,0x73,
+	0x63,0x6F,0x70,0x65,0x73,0x20,0x63,0x61,0x6E,0x20,0x6D,0x69,
+	0x6C,0x64,0x6C,0x79,0x20,0x66,0x6C,0x69,0x63,0x6B,0x65,0x72,
+	0x20,0x64,0x65,0x70,0x65,0x6E,0x64,0x69,0x6E,0x67,0x20,0x6F,
+	0x6E,0x20,0x74,0x68,0x65,0x20,0x77,0x61,0x76,0x65,0x66,0x6F,
+	0x72,0x6D,0x20,0x61,0x6E,0x64,0x20,0x70,0x69,0x74,0x63,0x68,
+	0x2E,0x4D,0x3E,0x40,0x58,0x30,0x32,0x31,0x54,0x68,0x69,0x73,
+	0x20,0x69,0x73,0x20,0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20,
+	0x74,0x68,0x65,0x69,0x72,0x20,0x66,0x72,0x65,0x71,0x75,0x65,
+	0x6E,0x63,0x79,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,0x63,
+	0x6C,0x6F,0x63,0x6B,0x65,0x64,0x20,0x74,0x6F,0x20,0x65,0x78,
+	0x61,0x63,0x74,0x6C,0x79,0x20,0x74,0x68,0x65,0x20,0x73,0x61,
+	0x6D,0x65,0x20,0x72,0x61,0x74,0x65,0x4D,0x3E,0x61,0x74,0x20,
+	0x77,0x68,0x69,0x63,0x68,0x20,0x74,0x68,0x65,0x20,0x73,0x63,
+	0x6F,0x70,0x65,0x73,0x20,0x61,0x72,0x65,0x20,0x72,0x65,0x6E,
+	0x64,0x65,0x72,0x65,0x64,0x2E,0x20,0x49,0x74,0x27,0x73,0x20,
+	0x63,0x6C,0x6F,0x73,0x65,0x2C,0x20,0x77,0x68,0x69,0x63,0x68,
+	0x20,0x63,0x61,0x75,0x73,0x65,0x73,0x20,0x61,0x20,0x66,0x6C,
+	0x69,0x63,0x6B,0x65,0x72,0x20,0x65,0x66,0x66,0x65,0x63,0x74,
+	0x2E,0x01,0x3E,0x52,0x3E,0x40,0x58,0x30,0x31,0x30,0x2D,0x20,
+	0x4E,0x6F,0x74,0x20,0x61,0x20,0x62,0x75,0x67,0x2C,0x20,0x62,
+	0x75,0x74,0x20,0x69,0x66,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,
+	0x6F,0x6E,0x69,0x74,0x6F,0x72,0x27,0x73,0x20,0x72,0x65,0x66,
+	0x72,0x65,0x73,0x68,0x20,0x72,0x61,0x74,0x65,0x20,0x69,0x73,
+	0x20,0x6E,0x6F,0x74,0x20,0x73,0x65,0x74,0x20,0x74,0x6F,0x20,
+	0x36,0x30,0x48,0x7A,0x20,0x28,0x6F,0x72,0x20,0x35,0x39,0x48,
+	0x7A,0x29,0x4F,0x3E,0x40,0x58,0x30,0x32,0x31,0x79,0x6F,0x75,
+	0x20,0x6D,0x61,0x79,0x20,0x65,0x78,0x70,0x65,0x72,0x69,0x65,
+	0x6E,0x63,0x65,0x20,0x76,0x69,0x73,0x75,0x61,0x6C,0x20,0x73,
+	0x74,0x75,0x74,0x74,0x65,0x72,0x69,0x6E,0x67,0x20,0x62,0x65,
+	0x63,0x61,0x75,0x73,0x65,0x20,0x56,0x53,0x79,0x6E,0x63,0x20,
+	0x77,0x69,0x6C,0x6C,0x20,0x6E,0x6F,0x74,0x20,0x62,0x65,0x20,
+	0x75,0x73,0x65,0x64,0x20,0x74,0x68,0x65,0x6E,0x2E,0x49,0x49,
+	0x20,0x68,0x69,0x67,0x68,0x6C,0x79,0x20,0x72,0x65,0x63,0x6F,
+	0x6D,0x6D,0x65,0x6E,0x64,0x20,0x72,0x75,0x6E,0x6E,0x69,0x6E,
+	0x67,0x20,0x79,0x6F,0x75,0x72,0x20,0x6D,0x6F,0x6E,0x69,0x74,
+	0x6F,0x72,0x20,0x61,0x74,0x20,0x36,0x30,0x48,0x7A,0x20,0x69,
+	0x66,0x20,0x79,0x6F,0x75,0x27,0x72,0x65,0x20,0x61,0x20,0x68,
+	0x61,0x72,0x64,0x63,0x6F,0x72,0x65,0x20,0x75,0x73,0x65,0x72,
+	0x10,0x6F,0x66,0x20,0x74,0x68,0x69,0x73,0x20,0x70,0x72,0x6F,
+	0x67,0x72,0x61,0x6D,0x2E,0x00,0x03,0x45,0x4E,0x44
 };
 
 #endif