This commit is contained in:
LTVA1 2024-08-22 20:26:54 +03:00 committed by tildearrow
parent 8a18f962f9
commit 9f9638931d
5 changed files with 44 additions and 13 deletions

View file

@ -841,6 +841,8 @@ void DivPlatformSNES::reset() {
memcpy(sampleMem,copyOfSampleMem,65536); memcpy(sampleMem,copyOfSampleMem,65536);
dsp.init(sampleMem); dsp.init(sampleMem);
dsp.set_output(NULL,0); dsp.set_output(NULL,0);
dsp.setupInterpolation(interpolationOn);
memset(regPool,0,128); memset(regPool,0,128);
// this can't be 0 or channel 1 won't play // this can't be 0 or channel 1 won't play
// this can't be 0x100 either as that's used by SPC700 page 1 and the stack // this can't be 0x100 either as that's used by SPC700 page 1 and the stack
@ -1023,6 +1025,8 @@ void DivPlatformSNES::setFlags(const DivConfig& flags) {
initEchoFIR[7]=flags.getInt("echoFilter7",0); initEchoFIR[7]=flags.getInt("echoFilter7",0);
initEchoMask=flags.getInt("echoMask",0); initEchoMask=flags.getInt("echoMask",0);
interpolationOn=flags.getBool("interpolationOn",true);
} }
int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {

View file

@ -69,6 +69,7 @@ class DivPlatformSNES: public DivDispatch {
bool writeEcho; bool writeEcho;
bool writeDryVol; bool writeDryVol;
bool echoOn; bool echoOn;
bool interpolationOn;
bool initEchoOn; bool initEchoOn;
signed char initEchoVolL; signed char initEchoVolL;

View file

@ -135,24 +135,39 @@ static short const gauss [512] =
1299,1300,1300,1301,1302,1302,1303,1303,1303,1304,1304,1304,1304,1304,1305,1305, 1299,1300,1300,1301,1302,1302,1303,1303,1303,1304,1304,1304,1304,1304,1305,1305,
}; };
void SPC_DSP::setupInterpolation(bool interpolate)
{
for(int i = 0; i < voice_count; i++)
{
m.voices[i].interpolate = interpolate;
}
}
inline int SPC_DSP::interpolate( voice_t const* v ) inline int SPC_DSP::interpolate( voice_t const* v )
{ {
// Make pointers into gaussian based on fractional position between samples // Make pointers into gaussian based on fractional position between samples
int offset = v->interp_pos >> 4 & 0xFF; if(v->interpolate)
short const* fwd = gauss + 255 - offset; {
short const* rev = gauss + offset; // mirror left half of gaussian int offset = v->interp_pos >> 4 & 0xFF;
short const* fwd = gauss + 255 - offset;
short const* rev = gauss + offset; // mirror left half of gaussian
int const* in = &v->buf [(v->interp_pos >> 12) + v->buf_pos]; int const* in = &v->buf [(v->interp_pos >> 12) + v->buf_pos];
int out; int out;
out = (fwd [ 0] * in [0]) >> 11; out = (fwd [ 0] * in [0]) >> 11;
out += (fwd [256] * in [1]) >> 11; out += (fwd [256] * in [1]) >> 11;
out += (rev [256] * in [2]) >> 11; out += (rev [256] * in [2]) >> 11;
out = (int16_t) out; out = (int16_t) out;
out += (rev [ 0] * in [3]) >> 11; out += (rev [ 0] * in [3]) >> 11;
CLAMP16( out ); CLAMP16( out );
out &= ~1; out &= ~1;
return out; return out;
}
else
{
return v->buf [(v->interp_pos >> 12) + v->buf_pos]; //Furnace addition -- no interpolation
}
} }

View file

@ -27,6 +27,9 @@ public:
// output buffer could hold. // output buffer could hold.
int sample_count() const; int sample_count() const;
// Furnace addition: disable/enable Gaussian interpolation
void setupInterpolation(bool interpolate);
// Emulation // Emulation
// Resets DSP to power-on state // Resets DSP to power-on state
@ -122,6 +125,7 @@ public:
int hidden_env; // used by GAIN mode 7, very obscure quirk int hidden_env; // used by GAIN mode 7, very obscure quirk
uint8_t t_envx_out; uint8_t t_envx_out;
sample_t out[2]; // Furnace addition, for per-channel oscilloscope sample_t out[2]; // Furnace addition, for per-channel oscilloscope
bool interpolate; // Furnace addition, to disable interpolation
}; };
// Furnace addition, gets a voice // Furnace addition, gets a voice

View file

@ -1969,6 +1969,8 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
echoFilter[6]=flags.getInt("echoFilter6",0); echoFilter[6]=flags.getInt("echoFilter6",0);
echoFilter[7]=flags.getInt("echoFilter7",0); echoFilter[7]=flags.getInt("echoFilter7",0);
bool interpolationOn=flags.getBool("interpolationOn",true);
ImGui::Text(_("Volume scale:")); ImGui::Text(_("Volume scale:"));
if (CWSliderInt(_("Left##VolScaleL"),&vsL,0,127)) { if (CWSliderInt(_("Left##VolScaleL"),&vsL,0,127)) {
if (vsL<0) vsL=0; if (vsL<0) vsL=0;
@ -2084,6 +2086,10 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
ImGui::Text(_("sum: %d"),filterSum); ImGui::Text(_("sum: %d"),filterSum);
ImGui::PopStyleColor(); ImGui::PopStyleColor();
if (ImGui::Checkbox(_("Gaussian interpolation"),&interpolationOn)) {
altered=true;
}
if (altered) { if (altered) {
e->lockSave([&]() { e->lockSave([&]() {
flags.set("volScaleL",127-vsL); flags.set("volScaleL",127-vsL);
@ -2102,6 +2108,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
flags.set("echoFilter6",echoFilter[6]); flags.set("echoFilter6",echoFilter[6]);
flags.set("echoFilter7",echoFilter[7]); flags.set("echoFilter7",echoFilter[7]);
flags.set("echoMask",echoMask); flags.set("echoMask",echoMask);
flags.set("interpolationOn",interpolationOn);
}); });
} }