|[hatari-devel] Antialiasing the YM2149|
[ Thread Index |
| More lists.tuxfamily.org/hatari-devel Archives
- To: hatari-devel <hatari-devel@xxxxxxxxxxxxxxxxxxx>
- Subject: [hatari-devel] Antialiasing the YM2149
- From: David Savinkoff <dsavnkff@xxxxxxxxx>
- Date: Sun, 1 Aug 2021 15:42:25 -0700
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telus.net; s=google; h=mime-version:from:date:message-id:subject:to; bh=3G6OxBNZJJ5vFuvo3rhTZZxissKespm6Ho7iLozxYCY=; b=TJl4JnEPfwdqhvvz7rcUn7+KMluZYXaZfDnDKoRC4vCMFPjVx3cn4M5WL3+11Gnsnl s4yDn4JG+Akz/YeBqtFy0gjOB7U/hfFFrxEQ2oVa3K3SFF0h26cVCV8aGYOmfofcN9KH G9U8id2ugtMyzZqxvkhheraEdaVuXEpsw7029mfK9o023ebxjH3WylRrmQE6EGaI6Irl 7ujpSbZnnmvV9xzLlaAKqZPe0xvEx91nnQVh77oBaFaZz/rwmQDBmkhvowPp4zefz2bP B8fpMzx+AhVHYo8Zzl5u2h+Yqgic+ENpBPgykdJY5w704FRDAb50Jb5kLcZDA/EP7/HN RVsw==
To resample the YM2149 from 250000 samples per second to 44100 Hz
one can simplify the fitering by not generating frequencies on
the YM2149 that are beyond 17000Hz, yet keep the transient DC
offset that is associated with that high frequency. This was
done on Hatari in the past to eliminate the need to filter high
The following is an explanation on how to efficiently filter any
high frequency made by the YM2149:
Three cascaded half-band FIR filters are used.
The filter coefficients are found by using the Parks-McClellan
algorithm on a low pass filter that covers the fullest pass-band
possible, and without a transistion-band or stop-band
(cutoff frequency fc = 1/2 sampling frequency).
The resultant coefficients are each divided by 2, and the list of
coefficients is made longer by placing zero valued coefficients
between the resultant coefficients. The center coefficient is set
to 0.5 . Then a Kaiser-Bessel window is applied to the coefficients.
A circular buffer is made for each of the three cascaded filters.
The first circular buffer is updated with 250000 samples per second
from the YM2149.
The first filter operates on every other sample it pulls from the
The second circular buffer is updated from the output of the first
filter at 125000 samples per second.
The second filter operates on every other sample it pulls from the
The third circular buffer is updated from the output of the second
filter at 62500 samples per second.
The third filter operates on every sample it pulls from the third
An algorithm pulls the closest samples at 44100 Hz or 48000 Hz.
What is happening is a half-band filter is wider than 1/2 bandwidth,
causing some aliasing when the output is decimated by 2.
However, the second cascaded half-band filter filters the aliasing away.
The second cascaded half-band filter is decimated by 2, causing aliasing.
However, the third cascaded half-band filter filters the aliasing away,
and this filter makes no aliasing because it outputs samples at the same
rate as the second filter (62500 Hz). A sampling rate above 0.6*62500 Hz
and less than 62500 Hz will not alias on the third filter (37500 to
62500 Hz). 44100 Hz and 48000 Hz and 50000 Hz are some usable sample rates.
How many multiplies per second is this? [maybe 2.5 million per second]
Assume the Parks McClellan algorithm generates 22 coefficients. Half of
these coefficients are repeated, so 11 multiplies. Then zeros are
interleaved, no multiplies. Then 0.5 is placed as the center coefficient.
Thus, a 43 tap filter needs 12 multiplies.
However, every other sample is not used. So 12 multiplies is used for
two iterations. [Equals 6 multiplies * 250000 Hz = 1.5 million]
The second cascade runs at half the rate of the first, and uses fewer
coefficients [maybe 0.5 million multiplies per second]
The third cascade is similar to the second [maybe 0.5 million multiplies
per second]. Use 32 bit float, or 32 bit int SIMD instructions.
A fourth order IIR filter uses 2 biquads that each require 5 multiplies
at 250000 samles per second.
2*5*250000 = 2.5 million floating point multiplies per second.