## Gauss Table Creation

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
• For making cartridges of your Super NES games, see Reproduction.
psycopathicteen
Posts: 2943
Joined: Wed May 19, 2010 6:12 pm

### Re: Gauss Table Creation

Why is it that when I plug the equation into my TI-84 graphing calculator, some of the values differ slightly?

Jarhmander
Formerly ~J-@D!~
Posts: 508
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

### Re: Gauss Table Creation

Rounding? What the values look like?
((λ (x) (x x)) (λ (x) (x x)))

psycopathicteen
Posts: 2943
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.

lidnariq
Posts: 9665
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

### 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.

psycopathicteen
Posts: 2943
Joined: Wed May 19, 2010 6:12 pm

### Re: Gauss Table Creation

We found out it's not an exact Gaussian.

psycopathicteen
Posts: 2943
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.

Near
Founder of higan project
Posts: 1550
Joined: Mon Mar 27, 2006 5:23 pm

### 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:

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.