blargg wrote:
Dwedit wrote:
Turn off interpolation or filters to get that authentic low sample rate sound.
That fails unless your PC's sample rate is an integral multiple of the GBA's rate.
And in many cases, they are the same. The GBA has a pulse-width modulation digital to analog converter (PWM DAC) whose native rate is usually 65536 Hz.[1] VBA sounds OK at 44100 Hz because most games don't use more than 16 kHz, 18 kHz, or 21 kHz for their mixers, and the GBA resamples that to 65536 Hz internally using nearest neighbor. Since Windows 2000, most PC sound cards can resample a 65536 Hz stream down to the 48000 Hz or 96000 Hz that the card expects, whether in hardware or in the driver.
blargg wrote:
So it's a question of how it's resampled. If it's done without interpolation, then you introduce lots of artifacts not present in the original, which I think is what the original poster was trying to eliminate.
Windows already does this resampling from 44100 Hz to 48000 Hz, and it sounds at least cubic if not higher quality.
Drag wrote:
The problem with most interpolation schemes is that it (usually) eliminates the aliasing of the higher frequencies (good), but it turns the lower frequencies into a mushy mess of humming, instead of that really gritty sound (bad).
One common solution when trying to handle old consoles that used nearest-neighbor resampling is to render at 4 times the desired frequency, then low-pass filter and decimate. Sometimes this low-pass filter is a simple box filter (blargg's "merely averaging samples for the output sample period"); sometimes it's more complicated like a Chebyshev IIR low-pass filter.
Blargg has developed a more sophisticated algorithm called Blip Buffer. It involves rendering the waveform at full rate (e.g. 65536 Hz for GBA or 39375000/22 Hz for NES), taking the first difference of the output, and then reintegrating using one of a set of
Heaviside step functions that have been delayed by a fraction of an output sample and then filtered. (This works because there is a closed form formula for a low-pass filtered Heaviside step function, called the
sine integral.) Because this first difference is zero at most points in the waveform, the algorithm is efficient. In fact, it allows adding an equalizer at negligible additional CPU cost because the equalizer would just be run on the Heaviside kernels.
[1] Selectable from 1024*x Hz, where x in [32, 64, 128, 256] Hz, where the PWM DAC has a depth of [9, 8, 7, 6] bits respectively. A lot of games use 65536 Hz because the resulting 8-bit DAC matches the 8-bit output of the game's mixer.