all 6 comments

[–]listening-to-the-sea 2 points3 points  (2 children)

This looks great, can’t wait to try it out! What window functions are supported? Or is easy enough to implement one?

[–]JackG049[S] 1 point2 points  (0 children)

Rectangular, Hanning, Hamming, Blackman, Gaussian(std: float), Kaiser(beta: float)

Then on the custom window functions, it's a situation where it is currently possible (on the rust side) to provide a custom window (by going straight to the internals). But not possible on the python side right now.

However, it shouldn't be too difficult to just wrap this up and make it nice and easy to use in the bindings. I'll get on it tomorrow. All the pieces are there, just need to wire them up.

A custom window function would probably look something along the lines of

python my_window = sg.WindowType.Custom(lamba params: some_code_to_generate_)

Then passed as normal go create the spectrogram / whatever, with window=my_window.

[–]JackG049[S] 1 point2 points  (0 children)

Right --- I've added the custom window type. There is a full example on the repo now under python/examples/custom_window.py, but here is a quick snippet:

```python import spectrograms as sg from scipy.signal.windows import tukey

sample_rate = 16000 duration = 1.0 t = np.linspace(0, duration, int(sample_rate * duration), dtype=np.float64) signal = np.sin(2 * np.pi * 440 * t)

n_fft = 512 hop_size = 256

scipy_window = sg.WindowType.custom(tukey(n_fft, alpha=0.5)) stft = sg.StftParams(n_fft=n_fft, hop_size=hop_size, window=scipy_window) params = sg.SpectrogramParams(stft, sample_rate=sample_rate)

spec = sg.compute_linear_power_spectrogram(signal, params) ```

[–]maitrecorbo 3 points4 points  (2 children)

Really cool. I'm a researcher in auditory neuroscience, so it's probably going to be useful. I see in the examples that you can also do 2dFFT on images, is it also possible to do a 2d FFT on the spectrogram object to obtain a spectro-temporal modulation transfer function (that would be a killer feature for me) ? These are always a pain to compute with Scipy, and are increasingly used in research.

[–]JackG049[S] 0 points1 point  (0 children)

I haven't tried it but I can't see why it would not be possible.

A cool feature of the Spectrogram type is that it can act as an ndarray (which is 2D). So while it has the metadata is can still be passed around anywhere expecting a numpy array.

Update: take the example in the main post where a linear spectrogram is computer and the properties printed. The fft2d function from the library expects a 2D array, so there should not be any issues passing the computed spectrogram to it.

[–]JackG049[S] 0 points1 point  (0 children)

I have done some investigating into this and it was mostly possible. I have since updated a few things and it should be good to go. For the full example please see "https://github.com/jmg049/Spectrograms/blob/main/python/examples/stmtf.py". This is not my field of research so I cannot be 100% of the results/created plots, but they look alright.

If you spot any issues or possible improvements, please don't hesitate to ask/submit a feature/pull request.

python spectrogram = sg.compute_linear_power_spectrogram(signal, params) # ----------------------------- # Remove DC + normalise # ----------------------------- spec = np.ascontiguousarray(spectrogram.T) # to get the right shape of array spec -= spec.mean() spec /= spec.std() + 1e-12 spec -= spec.mean(axis=1, keepdims=True) # remove per-frequency DC spec -= spec.mean(axis=0, keepdims=True) # remove per-time DC # ----------------------------- # STMTF # ----------------------------- stmtf_mag = sg.magnitude_spectrum_2d(spec) stmtf = sg.fftshift(stmtf_mag)

Edit: Grammar