Skip to content

Commit

Permalink
Pushed v1.35 code
Browse files Browse the repository at this point in the history
- 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).
  • Loading branch information
8bitbubsy committed Oct 10, 2021
1 parent 03d0c96 commit fd5d416
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 85 deletions.
6 changes: 6 additions & 0 deletions release/macos/protracker.ini
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ VSYNCOFF=FALSE
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
Expand Down
6 changes: 6 additions & 0 deletions release/other/protracker.ini
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ VSYNCOFF=FALSE
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
Expand Down
6 changes: 6 additions & 0 deletions release/win32/protracker.ini
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ VSYNCOFF=FALSE
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
Expand Down
6 changes: 6 additions & 0 deletions release/win64/protracker.ini
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ VSYNCOFF=FALSE
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
Expand Down
136 changes: 62 additions & 74 deletions src/pt2_audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,13 +277,12 @@ void paulaSetPeriod(int32_t ch, uint16_t period)
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)
Expand All @@ -299,7 +298,7 @@ void paulaSetVolume(int32_t ch, uint16_t vol)
// ------------------------

// 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)
{
Expand All @@ -316,26 +315,12 @@ void paulaSetLength(int32_t ch, uint16_t len)
{
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.
*/
}

realLength <<= 1; // we work with bytes, not words
v->AUD_LEN = len;

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)
Expand All @@ -345,7 +330,8 @@ void paulaSetData(int32_t ch, const int8_t *src)
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
Expand All @@ -368,41 +354,40 @@ void paulaStartDMA(int32_t ch)
{
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
{
scope_t *s = &scope[ch];
s->newData = dat;
s->newLength = length;
s->newLength = v->AUD_LEN * 2;
scopeTrigger(ch);
}
}
Expand Down Expand Up @@ -448,20 +433,17 @@ void mixChannels(int32_t numSamples)
** 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;
}
Expand All @@ -476,33 +458,40 @@ void mixChannels(int32_t numSamples)
{
v->dPhase -= 1.0;

// Paula only updates period (delta) during sample fetching
v->dDelta = v->dNewDelta;
v->dDeltaMul = v->dNewDeltaMul;
// --------------------------------------------------------

v->dLastPhase = v->dPhase;
v->dLastDelta = v->dDelta;
v->dLastDeltaMul = v->dDeltaMul;
// Paula only updates period (delta) during period refetching (this stage)
v->dDelta = v->AUD_PER_delta;

if (++v->pos >= v->length)
if (v->sampleCounter == 0)
{
v->pos = 0;

// re-fetch new Paula register values now
v->length = v->newLength;
v->data = v->newData;
// it's time to read new samples from DMA

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;
}
}
}
Expand Down Expand Up @@ -881,7 +870,6 @@ void outputAudio(int16_t *target, int32_t numSamples)
}
}
}

}
}

Expand Down Expand Up @@ -910,8 +898,8 @@ static void fillVisualsSyncBuffer(void)
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;
Expand Down
18 changes: 14 additions & 4 deletions src/pt2_audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,21 @@ typedef struct voice_t
{
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;
Expand Down
8 changes: 8 additions & 0 deletions src/pt2_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ void loadConfig(void)
FILE *f;

// set default config values first
config.noDownsampleOnSmpLoad = false;
config.disableE8xEffect = false;
config.fullScreenStretch = false;
config.pattDots = false;
Expand Down Expand Up @@ -193,6 +194,13 @@ static bool loadProTrackerDotIni(FILE *f)
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)
else if (!_strnicmp(configLine, "DISABLE_E8X=", 12))
{
Expand Down
2 changes: 1 addition & 1 deletion src/pt2_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ typedef struct config_t
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;
Expand Down
2 changes: 1 addition & 1 deletion src/pt2_header.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 '\\'
Expand Down
6 changes: 3 additions & 3 deletions src/pt2_sample_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ bool loadWAVSample(UNICHAR *fileName, char *entryName, int8_t forceDownSampling)
return false;
}

if (sampleRate > 22050)
if (sampleRate > 22050 && !config.noDownsampleOnSmpLoad)
{
if (forceDownSampling == -1)
{
Expand Down Expand Up @@ -884,7 +884,7 @@ bool loadIFFSample(UNICHAR *fileName, char *entryName, int8_t forceDownSampling)
return false;
}

if (sampleRate > 22050)
if (sampleRate > 22050 && !config.noDownsampleOnSmpLoad)
{
if (forceDownSampling == -1)
{
Expand Down Expand Up @@ -1322,7 +1322,7 @@ bool loadAIFFSample(UNICHAR *fileName, char *entryName, int8_t forceDownSampling
return false;
}

if (sampleRate > 22050)
if (sampleRate > 22050 && !config.noDownsampleOnSmpLoad)
{
if (forceDownSampling == -1)
{
Expand Down
7 changes: 5 additions & 2 deletions src/pt2_visuals.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ void showDownsampleAskDialog(void)
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]);
}
Expand Down Expand Up @@ -2304,7 +2304,10 @@ void toggleFullScreen(void)
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);
}

Expand Down
Loading

0 comments on commit fd5d416

Please sign in to comment.