ref: fd5d4165735a0881ef0ccb9e52f22fb0f4f1bcc4
parent: 03d0c96c3f0070c59150c1d53c884ff6db6268c8
author: Olav Sørensen <olav.sorensen@live.no>
date: Sun Oct 10 16:36:04 EDT 2021
Pushed v1.35 code - Implemented a config entry in protracker.ini for disabling the 2x downsample dialog that shows up when attempting to load >22kHz samples (NO_DWNSMP_ON_SMP_LOAD) - Don't attempt to center window after leaving fullscreen mode. This could lead to issues on multi-monitor setups. - Further accuracy changes to the Paula emulator. Read two samples at once into the AUDxDAT buffer. This is a minor change, but it can have a very small impact on sample-changing commands (EFx/E8x).
--- a/release/macos/protracker.ini
+++ b/release/macos/protracker.ini
@@ -80,6 +80,12 @@
HWMOUSE=TRUE
[GENERAL SETTINGS]
+; Don't show downsample dialog after loading a sample whose frequency is >22kHz.
+; Syntax: TRUE or FALSE
+; Default value: FALSE
+;
+NO_DWNSMP_ON_SMP_LOAD=FALSE
+
; Hide last modification dates in Disk Op. to get longer dir/file names
; Syntax: TRUE or FALSE
; Default value: FALSE
--- a/release/other/protracker.ini
+++ b/release/other/protracker.ini
@@ -80,6 +80,12 @@
HWMOUSE=TRUE
[GENERAL SETTINGS]
+; Don't show downsample dialog after loading a sample whose frequency is >22kHz.
+; Syntax: TRUE or FALSE
+; Default value: FALSE
+;
+NO_DWNSMP_ON_SMP_LOAD=FALSE
+
; Hide last modification dates in Disk Op. to get longer dir/file names
; Syntax: TRUE or FALSE
; Default value: FALSE
--- a/release/win32/protracker.ini
+++ b/release/win32/protracker.ini
@@ -80,6 +80,12 @@
HWMOUSE=TRUE
[GENERAL SETTINGS]
+; Don't show downsample dialog after loading a sample whose frequency is >22kHz.
+; Syntax: TRUE or FALSE
+; Default value: FALSE
+;
+NO_DWNSMP_ON_SMP_LOAD=FALSE
+
; Hide last modification dates in Disk Op. to get longer dir/file names
; Syntax: TRUE or FALSE
; Default value: FALSE
--- a/release/win64/protracker.ini
+++ b/release/win64/protracker.ini
@@ -80,6 +80,12 @@
HWMOUSE=TRUE
[GENERAL SETTINGS]
+; Don't show downsample dialog after loading a sample whose frequency is >22kHz.
+; Syntax: TRUE or FALSE
+; Default value: FALSE
+;
+NO_DWNSMP_ON_SMP_LOAD=FALSE
+
; Hide last modification dates in Disk Op. to get longer dir/file names
; Syntax: TRUE or FALSE
; Default value: FALSE
--- a/src/pt2_audio.c
+++ b/src/pt2_audio.c
@@ -277,13 +277,12 @@
v->dOldVoiceDeltaMul = 1.0 / v->dOldVoiceDelta;
}
- v->dNewDelta = v->dOldVoiceDelta;
- if (v->dLastDelta == 0.0) // for BLEP
- v->dLastDelta = v->dNewDelta;
-
- v->dNewDeltaMul = v->dOldVoiceDeltaMul;
- if (v->dLastDeltaMul == 0.0) // for BLEP
- v->dLastDeltaMul = v->dNewDeltaMul;
+ v->AUD_PER_delta = v->dOldVoiceDelta;
+
+ // set BLEP stuff
+ v->dDeltaMul = v->dOldVoiceDeltaMul;
+ if (v->dLastDelta == 0.0)
+ v->dLastDelta = v->AUD_PER_delta;
}
void paulaSetVolume(int32_t ch, uint16_t vol)
@@ -299,7 +298,7 @@
// ------------------------
// multiplying by this also scales the sample from -128..127 -> -1.0 .. ~0.99
- v->dScaledVolume = realVol * (1.0 / (128.0 * 64.0));
+ v->AUD_VOL = realVol * (1.0 / (128.0 * 64.0));
if (editor.songPlaying)
{
@@ -316,26 +315,12 @@
{
paulaVoice_t *v = &paula[ch];
- int32_t realLength = len;
- if (realLength == 0)
- {
- realLength = 1+65535;
- /* Confirmed behavior on real Amiga. We have room for this
- ** even at the last sample slot, so it will never overflow!
- **
- ** PS: I don't really know if it's possible for ProTracker to
- ** set a Paula length of 0, but I fully support this Paula
- ** behavior just in case.
- */
- }
+ v->AUD_LEN = len;
- realLength <<= 1; // we work with bytes, not words
-
- v->newLength = realLength;
if (editor.songPlaying)
v->syncFlags |= SET_SCOPE_LENGTH;
else
- scope[ch].newLength = realLength;
+ scope[ch].newLength = len*2;
}
void paulaSetData(int32_t ch, const int8_t *src)
@@ -345,7 +330,8 @@
if (src == NULL)
src = &song->sampleData[RESERVED_SAMPLE_OFFSET]; // 128K reserved sample
- v->newData = src;
+ v->AUD_LC = src;
+
if (editor.songPlaying)
v->syncFlags |= SET_SCOPE_DATA;
else
@@ -368,34 +354,33 @@
{
paulaVoice_t *v = &paula[ch];
- const int8_t *dat = v->newData;
+ const int8_t *dat = v->AUD_LC;
if (dat == NULL)
dat = &song->sampleData[RESERVED_SAMPLE_OFFSET]; // 128K reserved sample
- int32_t length = v->newLength; // in bytes, not words
- if (length == 0)
- length = 1+65535;
+ /* This is not really accurate to what happens on Paula
+ ** during DMA start, but it's good enough.
+ */
- v->dPhase = v->dLastPhase = 0.0;
- v->pos = 0;
- v->data = dat;
- v->length = length;
- v->dDelta = v->dLastDelta = v->dNewDelta;
- v->dDeltaMul = v->dLastDeltaMul = v->dNewDeltaMul;
+ v->dDelta = v->AUD_PER_delta;
+ v->location = v->AUD_LC;
+ v->lengthCounter = v->AUD_LEN;
- /* Read first sample data point into cache now.
- **
- ** (multiplying by dScaledVolume will also change the scale
- ** from -128..127 to -1.0 .. ~0.99.)
- */
- v->dCachedSamplePoint = v->data[0] * v->dScaledVolume;
+ v->dSample = 0.0;
+ v->sampleCounter = 0; // read new DMA data samples ASAP
+ // set BLEP stuff
+ v->dLastPhase = 0.0;
+ v->dLastDelta = v->dDelta;
+ v->dBlepOffset = 0.0;
+
+ v->dPhase = 0.0;
v->DMA_active = true;
if (editor.songPlaying)
{
v->syncTriggerData = dat;
- v->syncTriggerLength = length;
+ v->syncTriggerLength = v->AUD_LEN * 2;
v->syncFlags |= TRIGGER_SCOPE;
}
else
@@ -402,7 +387,7 @@
{
scope_t *s = &scope[ch];
s->newData = dat;
- s->newLength = length;
+ s->newLength = v->AUD_LEN * 2;
scopeTrigger(ch);
}
}
@@ -448,20 +433,17 @@
** is temporarily forced offline, and its voice pointers are
** cleared to prevent expired pointer addresses.
*/
- if (!v->DMA_active || v->data == NULL)
+ if (!v->DMA_active || v->location == NULL || v->AUD_LC == NULL)
continue;
double *dMixBuf = dMixBufSelect[i]; // what output channel to mix into (L, R, R, L)
for (int32_t j = 0; j < numSamples; j++)
{
- double dSmp = v->dCachedSamplePoint;
+ double dSmp = v->dSample;
if (dSmp != bSmp->dLastValue)
{
if (v->dLastDelta > v->dLastPhase)
- {
- // v->dLastDeltaMul is (1.0 / v->dLastDelta) (pre-computed for speed, div -> mul)
- blepAdd(bSmp, v->dLastPhase * v->dLastDeltaMul, bSmp->dLastValue - dSmp);
- }
+ blepAdd(bSmp, v->dBlepOffset, bSmp->dLastValue - dSmp);
bSmp->dLastValue = dSmp;
}
@@ -476,33 +458,40 @@
{
v->dPhase -= 1.0;
- // Paula only updates period (delta) during sample fetching
- v->dDelta = v->dNewDelta;
- v->dDeltaMul = v->dNewDeltaMul;
- // --------------------------------------------------------
+ // Paula only updates period (delta) during period refetching (this stage)
+ v->dDelta = v->AUD_PER_delta;
- v->dLastPhase = v->dPhase;
- v->dLastDelta = v->dDelta;
- v->dLastDeltaMul = v->dDeltaMul;
-
- if (++v->pos >= v->length)
+ if (v->sampleCounter == 0)
{
- v->pos = 0;
+ // it's time to read new samples from DMA
- // re-fetch new Paula register values now
- v->length = v->newLength;
- v->data = v->newData;
+ if (--v->lengthCounter == 0)
+ {
+ v->lengthCounter = v->AUD_LEN;
+ v->location = v->AUD_LC;
+ }
+
+ // fill DMA data buffer
+ v->AUD_DAT[0] = *v->location++;
+ v->AUD_DAT[1] = *v->location++;
+ v->sampleCounter = 2;
}
- /* Read sample into cache now.
- ** Also change volume here as well. It has recently been
- ** discovered that Paula only updates its volume during period
- ** fetching (when it's reading the next sample point).
- **
- ** (multiplying by dScaledVolume will also change the scale
- ** from -128..127 to -1.0 .. ~0.99.)
+ /* Pre-compute current sample point.
+ ** Output volume is only read from AUDxVOL at this stage,
+ ** and we don't emulate volume PWM anyway, so we can
+ ** pre-multiply by volume at this point.
*/
- v->dCachedSamplePoint = v->data[v->pos] * v->dScaledVolume;
+ v->dSample = v->AUD_DAT[0] * v->AUD_VOL; // -128..127 * 0.0 .. 1.0
+
+ // progress AUD_DAT buffer
+ v->AUD_DAT[0] = v->AUD_DAT[1];
+ v->sampleCounter--;
+
+ // setup BLEP stuff
+ v->dBlepOffset = v->dPhase * v->dDeltaMul;
+ v->dLastPhase = v->dPhase;
+ v->dLastDelta = v->dDelta;
}
}
}
@@ -881,7 +870,6 @@
}
}
}
-
}
}
@@ -910,8 +898,8 @@
s->period = v->syncPeriod;
s->triggerData = v->syncTriggerData;
s->triggerLength = v->syncTriggerLength;
- s->newData = v->newData;
- s->newLength = v->newLength;
+ s->newData = v->AUD_LC;
+ s->newLength = v->AUD_LEN * 2;
s->vuVolume = c->syncVuVolume;
s->analyzerVolume = c->syncAnalyzerVolume;
s->analyzerPeriod = c->syncAnalyzerPeriod;
--- a/src/pt2_audio.h
+++ b/src/pt2_audio.h
@@ -27,11 +27,21 @@
{
volatile bool DMA_active;
- const int8_t *data, *newData;
- int32_t length, newLength, pos;
+ // internal values (don't modify directly!)
+ int8_t AUD_DAT[2]; // DMA data buffer
+ const int8_t* location; // current location
+ uint16_t lengthCounter; // current length
+ int32_t sampleCounter; // how many bytes left in AUD_DAT
+ double dSample; // current sample point
- double dDelta, dDeltaMul, dPhase, dLastDelta, dLastDeltaMul, dLastPhase;
- double dCachedSamplePoint, dScaledVolume, dNewDelta, dNewDeltaMul;
+ // registers modified by Paula functions
+ const int8_t* AUD_LC; // location
+ uint16_t AUD_LEN; // length (in words)
+ double AUD_PER_delta; // delta
+ double AUD_VOL; // volume
+
+ double dBlepOffset, dDelta, dPhase, dLastDelta, dLastPhase;
+ double dScaledVolume, dDeltaMul;
// period cache
int32_t oldPeriod;
--- a/src/pt2_config.c
+++ b/src/pt2_config.c
@@ -42,6 +42,7 @@
FILE *f;
// set default config values first
+ config.noDownsampleOnSmpLoad = false;
config.disableE8xEffect = false;
config.fullScreenStretch = false;
config.pattDots = false;
@@ -191,6 +192,13 @@
{
configLine = strtok(NULL, "\n");
continue;
+ }
+
+ // NO_DWNSMP_ON_SMP_LOAD (no dialog for 2x downsample after >22kHz sample load)
+ else if (!_strnicmp(configLine, "NO_DWNSMP_ON_SMP_LOAD=", 22))
+ {
+ if (!_strnicmp(&configLine[22], "TRUE", 4)) config.noDownsampleOnSmpLoad = true;
+ else if (!_strnicmp(&configLine[22], "FALSE", 5)) config.noDownsampleOnSmpLoad = false;
}
// DISABLE_E8X (Karplus-Strong command)
--- a/src/pt2_config.h
+++ b/src/pt2_config.h
@@ -15,7 +15,7 @@
char *defModulesDir, *defSamplesDir;
bool waveformCenterLine, pattDots, compoMode, autoCloseDiskOp, hideDiskOpDates, hwMouse;
bool transDel, fullScreenStretch, vsyncOff, modDot, blankZeroFlag, realVuMeters, rememberPlayMode;
- bool startInFullscreen, integerScaling, disableE8xEffect;
+ bool startInFullscreen, integerScaling, disableE8xEffect, noDownsampleOnSmpLoad;
int8_t stereoSeparation, videoScaleFactor, accidental;
uint8_t pixelFilter, filterModel;
uint16_t quantizeValue;
--- a/src/pt2_header.h
+++ b/src/pt2_header.h
@@ -14,7 +14,7 @@
#include "pt2_unicode.h"
#include "pt2_palette.h"
-#define PROG_VER_STR "1.34"
+#define PROG_VER_STR "1.35"
#ifdef _WIN32
#define DIR_DELIMITER '\\'
--- a/src/pt2_sample_loader.c
+++ b/src/pt2_sample_loader.c
@@ -239,7 +239,7 @@
return false;
}
- if (sampleRate > 22050)
+ if (sampleRate > 22050 && !config.noDownsampleOnSmpLoad)
{
if (forceDownSampling == -1)
{
@@ -884,7 +884,7 @@
return false;
}
- if (sampleRate > 22050)
+ if (sampleRate > 22050 && !config.noDownsampleOnSmpLoad)
{
if (forceDownSampling == -1)
{
@@ -1322,7 +1322,7 @@
return false;
}
- if (sampleRate > 22050)
+ if (sampleRate > 22050 && !config.noDownsampleOnSmpLoad)
{
if (forceDownSampling == -1)
{
--- a/src/pt2_visuals.c
+++ b/src/pt2_visuals.c
@@ -342,7 +342,7 @@
renderBigAskDialog();
textOutTight(133, 49, "THE SAMPLE'S FREQUENCY IS", video.palette[PAL_BACKGRD]);
- textOutTight(178, 57, "ABOVE 22KHZ.", video.palette[PAL_BACKGRD]);
+ textOutTight(154, 57, "HIGH (ABOVE 22KHZ).", video.palette[PAL_BACKGRD]);
textOutTight(133, 65, "DO YOU WANT TO DOWNSAMPLE", video.palette[PAL_BACKGRD]);
textOutTight(156, 73, "BEFORE LOADING IT?", video.palette[PAL_BACKGRD]);
}
@@ -2304,7 +2304,10 @@
SDL_SetWindowFullscreen(video.window, 0);
SDL_RenderSetLogicalSize(video.renderer, SCREEN_W, SCREEN_H);
SDL_SetWindowSize(video.window, SCREEN_W * config.videoScaleFactor, SCREEN_H * config.videoScaleFactor);
- SDL_SetWindowPosition(video.window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
+
+ // this is not sensible on a multi-monitor setup
+ //SDL_SetWindowPosition(video.window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
+
SDL_SetWindowGrab(video.window, SDL_FALSE);
}
--- a/vs2019_project/pt2-clone/protracker.ini
+++ b/vs2019_project/pt2-clone/protracker.ini
@@ -80,6 +80,12 @@
HWMOUSE=TRUE
[GENERAL SETTINGS]
+; Don't show downsample dialog after loading a sample whose frequency is >22kHz.
+; Syntax: TRUE or FALSE
+; Default value: FALSE
+;
+NO_DWNSMP_ON_SMP_LOAD=FALSE
+
; Hide last modification dates in Disk Op. to get longer dir/file names
; Syntax: TRUE or FALSE
; Default value: FALSE