Gauss Table Creation
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
-
- Posts: 3140
- 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: 569
- Joined: Sun Mar 12, 2006 12:36 am
- Location: Rive nord de Montréal
-
- Posts: 3140
- 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: 3140
- Joined: Wed May 19, 2010 6:12 pm
Re: Gauss Table Creation
We found out it's not an exact Gaussian.
-
- Posts: 3140
- 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);
}
}
-
- Posts: 3140
- Joined: Wed May 19, 2010 6:12 pm
Re: Gauss Table Creation
I think I figured out why when I tried typing this equation in my calculator it didn't work. I didn't notice that besides the math equation for a Sinc*Blackman window, there is code that adjusts the values so that every 256th value adds up to as close to 2048 as possible.