Page 1 of 1
Boosting high frequencies in BRR samples
Posted: Sun Nov 24, 2013 9:38 am
by tepples
That might be useful. I can run the published impulse response of the Super NES DSP's interpolator through NumPy to determine its transfer function and then come up with an FIR preemphasis filter to compensate. Should I try this?
Re: Boosting high frequencies in BRR samples
Posted: Sun Nov 24, 2013 12:20 pm
by Bregalad
Yes, that'd be a neat idea. Keep in mind I just know the basics of signal processing though, so be sure to explain me well your results so I can implement them in the next version of BRRTools.
About the playstation "VAG" format, I can't find info exept in the "STR encoding doccument" where it describes it shortly in the FF8 movie format, because FF8 (and other recent Square games, besides) uses normal VAG sound for its videoes instead of more common CD-XA sound.
I know the data is similar to BRR but with 28 samples blocks (2 bytes header + 14 bytes data) instead of 16 samples blocks (1 byte header + 8 bytes data).
What I don't know is how the 2 bytes header works exactly and what are the filter's coefficients in terms of shifts (you have them in terms of real numbers in the STR doccument but it's not enough for accurate encoding / decoding).
Re: Boosting high frequencies in BRR samples
Posted: Sun Nov 24, 2013 2:17 pm
by tepples
I played around in numpy and found a treble boost FIR filter that should come close to canceling the S-DSP's treble cut:
[0.00417456, -0.017636, 0.03906008, -0.06200069, 0.07113042,
-0.0255472, -0.26998287, 1.52160339, -0.26998287, -0.0255472,
0.07113042, -0.06200069, 0.03906008, -0.017636, 0.00417456]
This kernel has unity response at DC. To prevent pathological samples from clipping, multiply the sample by 0.4.
As for bit-exact VAG decoding, you don't really need that for encoding because you're going to truncate to 4 bits anyway.
Re: Boosting high frequencies in BRR samples
Posted: Sun Nov 24, 2013 2:32 pm
by bazz
VAG Format

Re: Boosting high frequencies in BRR samples
Posted: Mon Nov 25, 2013 4:40 am
by Bregalad
tepples wrote:I played around in numpy and found a treble boost FIR filter that should come close to canceling the S-DSP's treble cut
Is this independant of the playback frequency of the SNES sample ?
Is there a way to do the reverse of it when decoding samples, to "simulate" gaussian filtering ?
What I currently do is that I simply raw decode the sample and let the user select the sample rate.
As for bit-exact VAG decoding, you don't really need that for encoding because you're going to truncate to 4 bits anyway.
I still need to know how the format works. On SNES it's necessarly to do bit shifts with integer values properly and to clamp/clip like the hardware does, else you get an alarm sound instead of wind in Final Fantasy 6.
I wonder if a similar things exists with the playstation, which is probably the case hearing how inaccurate sound is emulated currently (unless I need to upgrade my PS1 emulators).
Re: Boosting high frequencies in BRR samples
Posted: Mon Nov 25, 2013 7:21 am
by tepples
Bregalad wrote:tepples wrote:I played around in numpy and found a treble boost FIR filter that should come close to canceling the S-DSP's treble cut
Is this independant of the playback frequency of the SNES sample ?
Yes.
Is there a way to do the reverse of it when decoding samples, to "simulate" gaussian filtering ?
Yes. Convolve the sample with appropriate elements of the Gauss table as described in
nocash's doc. In the case of applying the filter statically, such as when extracting a sample from a game to a wave file, filter with the FIR kernel [372, 1304, 372]/2048.
On SNES it's necessarly to do bit shifts with integer values properly and to clamp/clip like the hardware does, else you get an alarm sound instead of wind in Final Fantasy 6.
I wonder if a similar things exists with the playstation, which is probably the case hearing how inaccurate sound is emulated currently (unless I need to upgrade my PS1 emulators).
As computing architectures become more advanced and more orthogonal, developers get lazy, start coding in higher-level languages, and rely less on undefined behavior (except in the case of that X-Files game). But I'd bet there are people within the psxdev community who would be willing to run test cases on an actual PS1 so that nocash can update
his PS1 SPU docs.
Re: Boosting high frequencies in BRR samples
Posted: Mon Nov 25, 2013 7:25 am
by Jarhmander
Bregalad wrote:tepples wrote:I played around in numpy and found a treble boost FIR filter that should come close to canceling the S-DSP's treble cut
Is this independant of the playback frequency of the SNES sample ?
I think it is not, unfortunately. Consider the case where VxPITCH of a channel is 0x1000. Then your sample is played at 32kHz, and because the fractionnal part doesn't change (bits 11-0) then it is as if there were no interpolation, and just a filter is applied to your sample. Assuming an initial phase of 0, your sample is delayed by one sample (z^-1) and is filtered by the equivalent of a two tap low-pass FIR. The equivalent filter does not have a spectral null at fs/2 but it still gets attenuated here. However, if the initial phase is 0x800, then there will be (close to) spectral nulls at fs/2 and fs/4, and the gain between fs/2 and fs/4 will be lower than the DC gain. So, with different phases we get different spectrums. And if the playback rate gets lower, then interpolation kicks in, and we now that the pseudo-gaussian window has a poor roll-off caracteristics and the spectrum gets much less flat than the 32kHz, non-interpolated playback.
Re: Boosting high frequencies in BRR samples
Posted: Fri Nov 29, 2013 2:42 pm
by Bregalad
I have completed the implementation of the treble boost of encoding BRR samples (and of the gauss filter when decoding them).
They are enabled by adding the -g option (this will respecively enable treble boosting in brr_encoder and gauss filtering in brr_decoder and spc_decoder).
EDIT : Now the new version 3.1 which has this feature is officially released on romhacking.net