Gauss Table Creation
Moderator: Moderators
Forum rules
 For making cartridges of your Super NES games, see Reproduction.

 Posts: 2935
 Joined: Wed May 19, 2010 6:12 pm
Re: Gauss Table Creation
Why is it that when I plug the equation into my TI84 graphing calculator, some of the values differ slightly?
 Jarhmander
 Formerly ~J@D!~
 Posts: 498
 Joined: Sun Mar 12, 2006 12:36 am
 Location: Rive nord de Montréal

 Posts: 2935
 Joined: Wed May 19, 2010 6:12 pm
Re: Gauss Table Creation
Does anybody have a fourier transform of this? I feel like looking the FFT will explain a lot.
Re: Gauss Table Creation
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.
If you want to plot the transform of the actual contents of the tables, I'd recommend learning Octave or NumPy.

 Posts: 2935
 Joined: Wed May 19, 2010 6:12 pm
Re: Gauss Table Creation
We found out it's not an exact Gaussian.

 Posts: 2935
 Joined: Wed May 19, 2010 6:12 pm
Re: Gauss Table Creation
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
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:
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.
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);
}
}