[C64] Fix a situation where the SID filter stage would pass through voices selected to be filtered while no filters are actually enabled

This commit is contained in:
saxxonpike 2025-01-04 01:37:04 -06:00 committed by YoshiRulz
parent 9dc3e0cf84
commit 83ea4bfb1c
2 changed files with 54 additions and 29 deletions

View File

@ -6,41 +6,54 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
{
public class RealFFT
{
private readonly int _length;
private readonly int[] _ip;
private readonly double[] _w;
private int _length;
private int[] _ip = Array.Empty<int>();
private double[] _w = Array.Empty<double>();
public readonly double ForwardScaleFactor;
public readonly double ReverseScaleFactor;
public readonly double CorrectionScaleFactor;
public double ForwardScaleFactor { get; private set; }
public double ReverseScaleFactor { get; private set; }
public double CorrectionScaleFactor { get; private set; }
public RealFFT(int length)
{
Resize(length);
}
public void Resize(int length)
{
if (length < 2 || (length & (length - 1)) != 0)
{
throw new ArgumentException("FFT length must be at least 2 and a power of 2.", nameof(length));
}
_length = length;
_ip = new int[2 + (1 << (Convert.ToInt32(Math.Log(Math.Max(length / 4, 1), 2)) / 2))];
_w = new double[length / 2];
ForwardScaleFactor = length;
ReverseScaleFactor = 0.5;
CorrectionScaleFactor = 1.0 / (ForwardScaleFactor * ReverseScaleFactor);
ReverseScaleFactor = 0.5d;
CorrectionScaleFactor = 1.0d / (ForwardScaleFactor * ReverseScaleFactor);
_length = length;
var ipLength = 2 + (1 << (Convert.ToInt32(Math.Log(Math.Max(length / 4, 1), 2)) / 2));
if (_ip.Length < ipLength)
Array.Resize(ref _ip, ipLength);
var wLength = length / 2;
if (_w.Length < wLength)
Array.Resize(ref _w, wLength);
_ip.AsSpan().Clear();
_w.AsSpan().Clear();
}
public void ComputeForward(double[] buff)
public void ComputeForward(Span<double> buff)
{
Compute(buff, false);
}
public void ComputeReverse(double[] buff)
public void ComputeReverse(Span<double> buff)
{
Compute(buff, true);
}
private void Compute(double[] buff, bool reverse)
private void Compute(Span<double> buff, bool reverse)
{
if (buff.Length < _length)
{
@ -50,7 +63,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
rdft(_length, reverse, buff, _ip, _w);
}
private static void rdft(int n, bool rev, double[] a, int[] ip, double[] w)
private static void rdft(int n, bool rev, Span<double> a, Span<int> ip, Span<double> w)
{
int nw, nc;
double xi;
@ -102,7 +115,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
/* -------- initializing routines -------- */
private static void makewt(int nw, int[] ip, double[] w)
private static void makewt(int nw, Span<int> ip, Span<double> w)
{
int j, nwh;
double delta, x, y;
@ -133,7 +146,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
}
}
private static void makect(int nc, int[] ip, double[] c, int nw)
private static void makect(int nc, Span<int> ip, Span<double> c, int nw)
{
int j, nch;
double delta;
@ -155,7 +168,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
/* -------- child routines -------- */
private static void bitrv2(int n, int[] ip, double[] a)
private static void bitrv2(int n, Span<int> ip, Span<double> a)
{
int j, j1, k, k1, l, m, m2;
double xr, xi, yr, yi;
@ -263,7 +276,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
}
}
private static void cftfsub(int n, double[] a, double[] w)
private static void cftfsub(int n, Span<double> a, Span<double> w)
{
int j, j1, j2, j3, l;
double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
@ -319,7 +332,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
}
}
private static void cftbsub(int n, double[] a, double[] w)
private static void cftbsub(int n, Span<double> a, Span<double> w)
{
int j, j1, j2, j3, l;
double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
@ -375,7 +388,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
}
}
private static void cft1st(int n, double[] a, double[] w)
private static void cft1st(int n, Span<double> a, Span<double> w)
{
int j, k1, k2;
double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
@ -480,7 +493,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
}
}
private static void cftmdl(int n, int l, double[] a, double[] w)
private static void cftmdl(int n, int l, Span<double> a, Span<double> w)
{
int j, j1, j2, j3, k, k1, k2, m, m2;
double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
@ -611,7 +624,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
}
}
private static void rftfsub(int n, double[] a, int nc, double[] c, int nw)
private static void rftfsub(int n, Span<double> a, int nc, Span<double> c, int nw)
{
int j, k, kk, ks, m;
double wkr, wki, xr, xi, yr, yi;
@ -636,7 +649,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
}
}
private static void rftbsub(int n, double[] a, int nc, double[] c, int nw)
private static void rftbsub(int n, Span<double> a, int nc, Span<double> c, int nw)
{
int j, k, kk, ks, m;
double wkr, wki, xr, xi, yr, yi;

View File

@ -259,16 +259,28 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
}
}
_fft = new RealFFT(nsamp_2);
if (_fft == null)
_fft = new RealFFT(nsamp_2);
else
_fft.Resize(nsamp_2);
// eventually this will settle on a single buffer size and stop reallocating
if (_fftBuffer.Length < nsamp_2)
Array.Resize(ref _fftBuffer, nsamp_2);
// linearly interpolate the original sample set into the new denser sample set
for (double i = 0; i < nsamp_2; i++)
// If no filters are enabled, filtered output will be silent.
if (!_filterSelectLoPass && !_filterSelectHiPass && !_filterSelectBandPass)
{
_fftBuffer[(int)i] = _outputBufferFiltered[(int)Math.Floor((i / (nsamp_2-1) * (nsamp - 1))) + _filterIndex];
for (var i = 0; i < nsamp_2; i++)
_fftBuffer[i] = 0;
}
else
{
// linearly interpolate the original sample set into the new denser sample set
for (double i = 0; i < nsamp_2; i++)
{
_fftBuffer[(int)i] = _outputBufferFiltered[(int)Math.Floor((i / (nsamp_2-1) * (nsamp - 1))) + _filterIndex];
}
}
// now we have everything we need to perform the FFT