swharden / Spectrogram

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

ReadWAV() returns incorrect sample rate #34

Closed swharden closed 3 years ago

swharden commented 3 years ago

Content originally posted by @shirok1 in #33:


Wrong sampleCount expression in ReadWAV (readme.md)

int sampleCount = (int) (afr.Length / afr.WaveFormat.BitsPerSample / 8);

image

I guess this sampleCount is an estimation of the final size of the List<double> audio. However, 253296 is 64 times smaller than 16210944. So the most reasonable explanation is /8 is a typo of *8.

image

This "typo" causes the birth of garbage twice as large as the audio itself.

swharden commented 3 years ago

To improve readability I refactored this:

using var afr = new NAudio.Wave.AudioFileReader(filePath);
int sampleRate = afr.WaveFormat.SampleRate;
int sampleCount = (int) (afr.Length / afr.WaveFormat.BitsPerSample / 8);

to this:

using var afr = new NAudio.Wave.AudioFileReader(filePath);
int sampleRate = afr.WaveFormat.SampleRate;
int bytesPerSample = afr.WaveFormat.BitsPerSample / 8;
int sampleCount = (int)afr.Length / bytesPerSample;

I don't have a reason to doubt the output. With my test WAV files in the data folder it matches my expectation based on tests using Python's scipy.io.wavfile module. @shirok1 if you can provide a WAV file that fails this test upload it here and I can take a closer look.

from scipy.io import wavfile
samplerate, data = wavfile.read("cant-do-that-44100.wav")

EDIT: Python falls over with obscure formats like 32-bit floating format. I used GoldWave to calculate WAV file data length in this case to get accurate values that match NAudio and ReadWAV()

(#33)