swharden / Spectrogram

.NET library for creating spectrograms (visual representations of frequency spectrum over time)
https://nuget.org/packages/Spectrogram
MIT License
308 stars 56 forks source link

Problem with saving and reading certain SFF files #20

Closed KJ-Waller closed 4 years ago

KJ-Waller commented 4 years ago

Hi Scott,

I'm experiencing some issues with saving SFF files, as some of the SFF files seem to be empty when I read them in Python. There are two ways I have found I can recreate the issue.

First of all, when using SaveData on a spectrogram which does not have a maxFreq value, I get empty spectrograms when reading the SFF file in Python.

C#

(int sampleRate, double[] audio) = WavFile.ReadMono(filename);
spec = Spectrogram.Spectrogram(sampleRate, fttSize: 512, sstepSize: 200);
spec.Add(audio);

spec.SaveData("spectrogram.sff");

Python

sff_spec = sffLib.SpectrogramFile('spectrogram.sff').values

At which point sff_spec is None.

Secondly, I also get the same problem when providing a maxFreq > 7999 in C# when instantiating the spectrogram. Even with setting the maxFreq = 7999, I get some SFF files that still contain no spectrogram data. One such example is this file from the TESS dataset.

Is this a problem with the C# SaveData function or am I doing something wrong saving the SFF files?

Regards, Kevin

swharden commented 4 years ago

I created some code based on your description:

(int sampleRate, double[] audio) = WavFile.ReadMono("../../../../../data/03-02-03-01-02-01-19.wav");
int fftSize = 1 << 12;
var spec = new Spectrogram(sampleRate, fftSize, stepSize: 300, maxFreq: 7999);
spec.Add(audio);
spec.SaveData("testDoor.sff");

This code run on the file you gave (renamed), this C# produces a SFF file that is viewable with the "SFF viewer" program in the dev folder. This means everything on the C#/SFF writing side is working well. I'll take a closer look at the Python side to see if there's an error reading this file...

image

swharden commented 4 years ago

Indeed! Something is wrong with the python reading side...

image

swharden commented 4 years ago

Yeah, setting maxFreq: 3000 produces this. There is definitely something wrong on the python side.

image

swharden commented 4 years ago

got it! Python was reading the image width from the SFF file expecting an Int8 but it's really an Int32 🙈 Use the latest sffLib.py in this repo and let me know if it does the trick!

If you want to fix this manually, repeat my fix in https://github.com/swharden/Spectrogram/commit/38e5bc4eca9814e85a8705e63b13891dd6437c91