Boosting high frequencies in BRR samples

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.
Post Reply
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Boosting high frequencies in BRR samples

Post by tepples »

In [url=http://forums.nesdev.com/viewtopic.php?p=121406#p121406]this post[/url], Bregalad wrote:Since I added the anti-aliasing pre-filtering function on my BRRTools program when you resample input to an inferior sample rate, might I also add an optional high frequencies boost in the FIR filter as well ?
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?
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Boosting high frequencies in BRR samples

Post 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).
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Boosting high frequencies in BRR samples

Post 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.
User avatar
bazz
Posts: 476
Joined: Fri Sep 02, 2011 8:34 pm
Contact:

Re: Boosting high frequencies in BRR samples

Post by bazz »

VAG Format :lol:
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Boosting high frequencies in BRR samples

Post 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).
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Boosting high frequencies in BRR samples

Post 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.
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 521
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: Boosting high frequencies in BRR samples

Post 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.
((λ (x) (x x)) (λ (x) (x x)))
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Boosting high frequencies in BRR samples

Post 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
Post Reply