Page 3 of 3

### Re: Gauss Table Creation

Posted: Mon Jun 01, 2020 4:21 pm
Why is it that when I plug the equation into my TI-84 graphing calculator, some of the values differ slightly?

### Re: Gauss Table Creation

Posted: Tue Jun 02, 2020 4:47 am
Rounding? What the values look like?

### Re: Gauss Table Creation

Posted: Wed Jun 03, 2020 5:23 pm
Does anybody have a fourier transform of this? I feel like looking the FFT will explain a lot.

### Re: Gauss Table Creation

Posted: Wed Jun 03, 2020 5:33 pm
Fourier transform of a gaussian curve is another gaussian curve.

If you want to plot the transform of the actual contents of the tables, I'd recommend learning Octave or NumPy.

### Re: Gauss Table Creation

Posted: Thu Jun 04, 2020 1:35 pm
We found out it's not an exact Gaussian.

### Re: Gauss Table Creation

Posted: Sun Jun 07, 2020 9:28 am
I figured out why the top of the "Gaussian" table is 1305. I believe the interpolation table was designed to act like linear interpolation + a smoothing filter. If a you have the wave {0, 1, 0, -1, 0, 1, 0} with linear interpolation, it will come out as triangle wave, but the SNES was probably designed to filter this into a sine wave. If you drew a sine wave on top of the triangle wave, with the same slope at the zero points, the sine wave has 2/pi the height of the original wave.

### Re: Gauss Table Creation

Posted: Wed Jul 01, 2020 1:27 am
I finally got around to this since I needed the PS1 SPU gaussian table.

I noticed functional code for the PS1 was never posted, so here's my code to generate both tables:

Code: Select all

``````int16_t gaussianTable[512];

//Sony DSP (SNES)
//can round with + 0.5 as values are always positive
void DSP::gaussianConstructTable() {
double table[512];
for(uint n : range(512)) {
double k = 0.5 + n;
double s = (sin(M_PI * k * 1.280 / 1024));
double t = (cos(M_PI * k * 2.000 / 1023) - 1) * 0.50;
double u = (cos(M_PI * k * 4.000 / 1023) - 1) * 0.08;
double r = s * (t + u + 1.0) / k;
table[511 - n] = r;
}
for(uint phase : range(128)) {
double sum = 0.0;
sum += table[phase +   0];
sum += table[phase + 256];
sum += table[511 - phase];
sum += table[255 - phase];
double scale = 2048.0 / sum;
gaussianTable[phase +   0] = int16_t(table[phase +   0] * scale + 0.5);
gaussianTable[phase + 256] = int16_t(table[phase + 256] * scale + 0.5);
gaussianTable[511 - phase] = int16_t(table[511 - phase] * scale + 0.5);
gaussianTable[255 - phase] = int16_t(table[255 - phase] * scale + 0.5);
}
}``````

Code: Select all

``````int16_t gaussianTable[512];

//Sony SPU (PS1)
//using nearbyint(FE_TONEAREST) to round negative values correctly
void SPU::gaussianConstructTable() {
fesetround(FE_TONEAREST);
double table[512];
for(uint n : range(512)) {
double k = 0.5 + n;
double s = (sin(M_PI * k * 2.048 / 1024));
double t = (cos(M_PI * k * 2.000 / 1023) - 1) * 0.50;
double u = (cos(M_PI * k * 4.000 / 1023) - 1) * 0.08;
double r = s * (t + u + 1.0) / k;
table[511 - n] = r;
}
double sum = 0.0;
for(uint n : range(512)) sum += table[n];
double scale = 0x7f80 * 128 / sum;
for(uint n : range(512)) table[n] *= scale;
for(uint phase : range(128)) {
double sum = 0.0;
sum += table[phase +   0];
sum += table[phase + 256];
sum += table[511 - phase];
sum += table[255 - phase];
double diff = (sum - 0x7f80) / 4;
gaussianTable[phase +   0] = nearbyint(table[phase +   0] - diff);
gaussianTable[phase + 256] = nearbyint(table[phase + 256] - diff);
gaussianTable[511 - phase] = nearbyint(table[511 - phase] - diff);
gaussianTable[255 - phase] = nearbyint(table[255 - phase] - diff);
}
}``````
Hopefully it'll help someone. Code is public domain, but be sure to credit Ryphecha and nocash for coming up with this, all I did was implement what they figured out.