Blip_Buffer Frequency Response

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Blip_Buffer Frequency Response
by on (#221674)
Through discussions in a previous thread, I created a 13th-order Elliptic filter consisting of 7 biquad segments. Here's a plot of the frequency response produced by Octave. The cutoff frequency was set to 20000 Hz and the filter attenuates the signal down to -100 dB by 22000 Hz, satisfying the Nyquist criterion for the traditional audio sampling rates of 44100+ Hz. Furthermore, I wrote a test program that records the gain in decibels for a range of frequencies (a very slow Fourier-like Transform) and it reproduced Octave's plot almost perfectly and validated the implementation that I later plugged into Nintaco.

I finally got around to running that test program against Blargg's Blip_Buffer. I set the clock rate to 19687500 / 11 (NES NTSC), rounded to the nearest integer. The sample rate was set to 48000. I set range to 65536 and I generated sine waves with half that amplitude. And Blip_Synth was set to blip_high_quality. Here are the results:

Image

The filter is attenuating frequencies below 20000 Hz, worse than a first-order low-pass filter. But this is the first time that I ever tried using the Blip_Buffer; I assume I screwed something up. Can someone try to reproduce this?
Re: Blip_Buffer Frequency Response
by on (#221675)
Up to roughly 19kHz, that graph looks to me like what I'd expect for a first-order lowpass at -3dB point (corner frequency) of 17500Hz. Namely, in the decade from roughly 1.7kHz to 17kHz, I see very gradual attenuation from 0dB to -3dB, as expected, and the slope between 17kHz and 19kHz looks like a first-order lowpass to me.
Re: Blip_Buffer Frequency Response
by on (#221752)
Blip_Buffer provides treble and bass frequency equalization adjustment. In the original post, the Bode plot shows the default values. Below is flat equalization (bass = 1 Hz, trebel = 0 dB).

Image

It's flat up to 16 kHz. From there, there is gradual attenuation until about 21 kHz, then it plunges to -25 dB by 26 kHz.

That's not bad. Above 26 kHz, it always stays around -25 dB. It would be nice if the attenuation were stronger. -25 dB is what you get when you pop in foam earplugs (though of course ear plugs attenuate all frequencies). It's a significant reduction, but it leaves things audible.

The plot above was produced using the blip_high_quality setting. Blow is the result of blip_low_quality.

Image

This suggests it might be possible to further increase the cutoff steepness with greater performance cost. However, for efficiency, Blip_Buffer appears to fully operate with integer maths. The current high quality option may be pushing that design to the limits already; this is hinted by the fact that the quality constants appear to be precision bits (e.g. blip_high_quality = 16).

I did not test how performant Blip_Buffer is over the double-precision 13th-order Elliptic filter mentioned in the OP. But, assuming it is much more efficient, it's definitely a sensible option for emulation on low-end hardware given its filtering characteristics. On modern desktop hardware, better sound quality could be achieved via more advanced floating point filters.
Re: Blip_Buffer Frequency Response
by on (#221922)
My range of hearing stops at 16.5KHz. How many people who can hear higher tones would notice loss of volume past 16KHz?
Re: Blip_Buffer Frequency Response
by on (#221924)
Dwedit wrote:
My range of hearing stops at 16.5KHz. How many people who can hear higher tones would notice loss of volume past 16KHz?

At age 35 I'm down to somewhere around 17 or 18 kHz but as a teenager I could hear well above 20 kHz. I remember how stuff used to sound and I miss it. ;)

(For the same reason, because I do work in music and sound I really value spectrum analyzers that can give me a visual estimate of things so that I can try to ensure that there's a natural response in that range for people that can hear it... and also spot bad stray tones up there, which happen sometimes.)
Re: Blip_Buffer Frequency Response
by on (#221946)
I am studying the Blip_Buffer code. Does anyone know why a Hamming Window is applied to the sinc approximation?
Re: Blip_Buffer Frequency Response
by on (#221949)
The sinc is an infinite impulse, but this is a finite impulse approximation.

On a broad level, when you cut it to that finite length, the cuts leave "sharp edges". It helps to smooth those edges off, which is what a windowing function does. Any way you cut it there is some tradeoff in error, the windowing function is a way of shaping and managing that error (sort of choosing which frequencies it will be concentrated into). Hamming is a commonly used one.

This article seems to be fairly well written: https://en.wikipedia.org/wiki/Window_function