So I am trying to test some code that analyzes the volume of some PCM data. I am getting some weird volume measurements that don't make sense with the data I get from audacity. It seems like my measurements are all over the place.
I am not sure if my error is in the way I am reading the WAV data or if it is in the way I am calculating the volume.
So here is where I read in the data as bytes and convert to shorts since it is PCM 16-bit.
InputStream pcmStream = this.getClass().getClassLoader().getResourceAsStream("Test-16Bit-PCM.wav");
ArrayList<Byte> bytes = new ArrayList<>();
int b = pcmStream.read();
while(b != -1)
{
bytes.add((byte)b);
b = pcmStream.read();
}
// First 44 bytes of WAV file are file info, we already know PCM properties since we recorded test audio
byte [] bytesArray = new byte[bytes.size()-44];
for(int i = 44; i < bytes.size(); i++)
{
bytesArray[i-44] = bytes.get(i);
}
bytes = null;
pcmStream = null;
short [] pcm = new short[bytesArray.length/2];
ByteBuffer bb = ByteBuffer.wrap(bytesArray).asShortBuffer().get(pcm);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.asShortBuffer().get(pcm);
bytesArray = null;
That short []
is then passed directly to my analyzer, I then split data into timesteps of 0.1 seconds and average the volume over each timestep.
Here is where I calculate the RMS and dB
double sumOfSamples = 0;
double numOfSamples = settings.shortsPerTimeStep();
for(int i = start; i < start+settings.shortsPerTimeStep(); i++)
{
sumOfSamples = originalPcm[i]*originalPcm[i];
}
double rms = Math.sqrt(sumOfSamples/numOfSamples);
// Convert to decibels
calculatedVolume = 20*Math.log10(rms/20);
The audio I am reading in was recorded at 44100 MONO and saved as WAV 16 Signed PCM in audacity. Not sure what I am doing wrong.
Any help will be appreciated! Thanks
EDIT: Found out I was reading the WAV data wrong. I fixed it by adding end little endianess. However I am still confused on how to calculate the volume. The values are better but still hard to decipher and I am not sure what units my RMS is in and units the reference value is supposed to be in.