liamtoney / sonify

Sonification of seismic and infrasound signals
https://sonify.rtfd.io
MIT License
32 stars 2 forks source link

Make [up/down]sampling more robust #6

Closed liamtoney closed 2 years ago

liamtoney commented 2 years ago

This line https://github.com/liamtoney/sonify/blob/7999a7cf5abaf52e991286d91e869b5c85b55cbe/sonify/sonify.py#L204 peforms interpolation of the input data waveform to ensure that the output audio WAV file has a 44.1 kHz sampling rate. For a typical speed_up_factor value such as sonify's default of 200, the target sampling rate is 44100 Hz / 200 = 220.5 Hz. Since seismoacoustic data sampling rates are generally (but not always!) lower than this, we're usually upsampling.

However, for higher data sampling rates (even, say, 100 Hz) and larger speed_up_factor values (say, 500), the above line is actually downsampling (44100 Hz / 500 = 88.2 Hz < 100 Hz). Therefore, we need to apply an anti-aliasing filter.

Also, we should use a more advanced interpolation method, like lanczos (docs for the interpolate() method of the Trace object are here).

liamtoney commented 2 years ago

Here are two outputs of sonify, with and without an anti-aliasing lowpass filter applied prior to resampling. Without:

https://user-images.githubusercontent.com/38269494/148474979-76f8a72f-d6ff-4068-bd6e-78f8819c9e75.mp4

With:

https://user-images.githubusercontent.com/38269494/148474988-92766203-3837-4e24-9863-809cce0e748b.mp4

The differences are obvious, with the first video sounding "clicky" and staticky. Note that, because sonify also requires a bandpass filter to be applied, I had to choose a pretty strange combination of bandpass corners and speed_up_factor to get something screwy:

sonify 3E YIF3 CDF 2016-07-31T19:00 2016-07-31T21:00 --freqmin 10 --freqmax 50 --speed_up_factor 1000 --resolution crude

But — it's still possible, so it's a bug that should be fixed.

liamtoney commented 2 years ago

Based on this ObsPy issue, it seems like the most rigorous solution is to use lowpass_cheby_2().

liamtoney commented 2 years ago

Based on this ObsPy issue, it seems like the most rigorous solution is to use lowpass_cheby_2().

Actually, the above is not zero phase! So perhaps the best option long-term is the modified zero phase version here.

liamtoney commented 2 years ago

Opting to use a Butterworth filter with conservative parameters for now. sonify doesn't require a perfect solution as it is not a data analysis tool.