SamiPerttu / fundsp

Library for audio processing and synthesis
Apache License 2.0
800 stars 43 forks source link

Asymmetric Bell Filter at Lower Frequencies #36

Closed ajoklar closed 11 months ago

ajoklar commented 11 months ago

I was playing around with the display() function on peaking bell filters and got these results:

bell_hz(1000.0, 0.3, db_amp(18.0)) ``` 20 dB ------------------------------------------------ 20 dB ...***.. 10 dB -----------------..************..--------------- 10 dB ...********************.. 0 dB .........********************************....... 0 dB ************************************************ -10 dB ************************************************ -10 dB ************************************************ -20 dB ************************************************ -20 dB ************************************************ -30 dB ************************************************ -30 dB ************************************************ -40 dB ************************************************ -40 dB | | | | | | | | | | 10 50 100 200 500 1k 2k 5k 10k 20k Hz ```
bell_hz(10000.0, 0.3, db_amp(18.0)) ``` 20 dB ------------------------------------------------ 20 dB ..**. 10 dB ----------------------------------..********.--- 10 dB ..************** 0 dB ..........................*********************. 0 dB ************************************************ -10 dB ************************************************ -10 dB ************************************************ -20 dB ************************************************ -20 dB ************************************************ -30 dB ************************************************ -30 dB ************************************************ -40 dB ************************************************ -40 dB | | | | | | | | | | 10 50 100 200 500 1k 2k 5k 10k 20k Hz ```

The first curve is symmetrical as expected, the high frequency one is asymmetrical as expected because of cramping at Nyquist. Also oversampling works as expected to get a symmetrical curve at 10 kHz:

oversample(bell_hz(10000.0, 0.3, db_amp(18.0))) ``` 20 dB ------------------------------------------------ 20 dB ...***.. 10 dB ---------------------------------..************. 10 dB ..***************** 0 dB .........................*********************** 0 dB ************************************************ -10 dB ************************************************ -10 dB ************************************************ -20 dB ************************************************ -20 dB ************************************************ -30 dB ************************************************ -30 dB ************************************************ -40 dB ************************************************ -40 dB | | | | | | | | | | 10 50 100 200 500 1k 2k 5k 10k 20k Hz ```

However, I did not expect a filter at 60 Hz to be asymmetrical:

bell_hz(60.0, 0.3, db_amp(18.0)) ``` 20 dB ------------------------------------------------ 20 dB .***... 10 dB -.**********..---------------------------------- 10 dB .***************.. 0 dB **********************.......................... 0 dB ************************************************ -10 dB ************************************************ -10 dB ************************************************ -20 dB ************************************************ -20 dB ************************************************ -30 dB ************************************************ -30 dB ************************************************ -40 dB ************************************************ -40 dB | | | | | | | | | | 10 50 100 200 500 1k 2k 5k 10k 20k Hz ```

My knowledge about signal processing is still pretty rudimentary. I haven't found a theoretical explanation on why that happens, so I tried to recreate these settings with some EQ plugins. Some showed cramping at high frequencies, but none shared the behavior at lower center frequencies. Is this a bug or is it correct and I'm missing something? If this is indeed the intended behavior, could you point out how I can obtain a symmetrical curve at low center frequencies?

SamiPerttu commented 11 months ago

Hi! I believe the bell filter is symmetrical at low frequencies. It just looks asymmetrical in the graph. Note that the frequency axis is linear from 10 to 100 Hz, while the filter is symmetrical in log-space. For example, the values at 10 Hz (60 / 6 = 10) and 360 Hz (60 * 6 = 360) match approximately. I tried to verify this by examining some responses via response_db, and the results appeared to be roughly symmetrical.