Reading in with WAV yields different result from data exported through Audacity

I have a simple program that I want to run on a wav file. To test the algorithm I have used audacity’s export function to generate a CSV file, and everything works exactly as expected.

But when I use WAV:

data, fs = wavread("Test.wav")

I don’t get the same result. Any ideas why this may be?

The output I get from the the wavread function is:

([-0.00024414807580797754; -0.00021362956633198035; … ; 0.00027466658528397473; 0.00027466658528397473], 44100.0f0, 0x0010, WAVChunk[WAVChunk(Symbol("fmt "), UInt8[0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x44, 0xac, 0x00, 0x00, 0x88, 0x58, 0x01, 0x00, 0x02, 0x00, 0x10, 0x00])])

But the audacity sample output is in dB:

-72.2472
-73.40704
-69.48114
-71.22415
-71.22415
-70.309
-68.72537
-70.309
-68.72537
-71.22415

Okay, answering my own question here: It’s because wavread outputs linear samples, not dB, so I will need to figure out to convert between the two.

1 Like

I have successfully converted the scale to dB now as follows, but now I have a another issue:

dataRead, fs = wavread("Test.wav")
data = dataRead[:]
dataLength = length(data)

    for i in 1:dataLength

       data[i] = data[i]^2
       data[i] = 10*log10(data[i])

    end

println(length(data))   #Outputs 699803 , which is the expected result
println(length(dataLength))  # Outputs 1, which is weird.

I am not sure what is causing dataLength to return 1 here. I have tried reassigning it after the for block as well and I get the same result. The dB values in data are correct though, so I am a bit stumped.

Okay, that was silly of me…

I’m still having an incorrect output though, even though the resulting dB vector looks exactly the same as the one from the .CSV

See, e.g., matlab - How to compute dBFS? - Signal Processing Stack Exchange.

The “formulae” seems to be data_in_dB = 20*log10(abs(data)), which is the same as you do.

To me, using dB appears problematic, in that you destroy information about the sign of the signal. In other words: if you have the data in dB (or rather: dB below Full Scale = dBFS), you cannot reverse the information and find the waveform.

1 Like

Yes, that’s a good point. For the moment, though, I am just trying to reproduce a process that works well for the .CSV file (in dB, but not in linear) but doesn’t seem to work for the WAV file even though I have the outputs:

[-72.24693388299511, -73.40677282254885, -69.48087991966948, …]

for the WAV and:

[-72.2472, -73.40704, -69.48114, … ]

for the .CSV

which should be equivalent. The length and types are also the same. It will probably be something silly again, knowing me…

Barring some rounding error, those seem the same to me, with one having a higher/different precision calculation than the other. How was the data in the CSV created?

1 Like

I ended up exporting the data out to CSV to inspect it and it seems there were zeros in there.

using DelimitedFiles
writedlm( "FileName.csv",  data, ',')

I had forgotten that when I originally exported the data using Audacity they were [inf] data points, which I had corrected manually. That’s why it was working up to the squaring step, but not the log step, because obviously log10(0) is undefined.

So the solution is:

dataRead, fs = wavread("FileName.wav")
data = dataRead[:]
dataLength = length(data)

    for i in 1:dataLength
        if data[i] != 0

            data[i] = 10*(log10(data[i]^2)) #converts to dB
           #dataTop[i] = 20*log10(abs(data[i])) #alternative way to convert to dB, see upthread
           else data[i] = 0  #zeros are okay in the dB data for me

         end
     end

That should work as expected now.

Incidentally, I think the thing with periodic high frequency data is that is the sign is not going to matter so much in the end. Perhaps it comes down to the fact that the if you take the absolute values of a sine wave you are going to get a non-smooth breakpoint where it crosses the axis. So, if you were to apply a function to smooth out that non-differentiable point, you would end up back at the sine-wave.

This might be why taking absolute values (and squaring) doesn’t destroy as much information as one would expect. Quite fascinating, really.