# Calculate RMS SPL of long term acoustic data

47 views (last 30 days)
Louise Wilson on 8 Aug 2019
Commented: Renato SL on 12 Aug 2019
I have a large data set of recordings which are each 2 minutes long. This data is in a matrix of dB values, where each row represents one sound file and each column is a frequency bin. Now I would like to get the root mean squared sound pressure level for each file across the entire frequency range. I understand that this should be done for each row by taking all of the dB measurements and squaring them, then taking the mean of these values, and then the square root of the mean. Can anyone tell me how I do this in matlab? Would the following work?
rmslevel=rms(matrix);
I have existing code from an old colleague which does the following, where A is the matrix:
rmslevel=10*log10(mean(10.^(A/10)));
This code works without errors and gives me a value which looks reasonable but I don't see how it is performing the necessary calculations. Can anyone understand it?
Thanks!!

Renato SL on 8 Aug 2019
For the matlab function rms, I suggest you see
help rms
since it listed how to use that function and apparently it can do an rms calculation column-wise or row-wise, so it should be suitable for you.
Regarding the code from your colleague, as you said with A as the matrix with dB values:
rmslevel=10*log10(mean(10.^(A/10)));
So I would break it down to 3 steps of calculation: The exponent, the mean, and the log operations, respectively.
x = 10.^(A/10); %the exponent
y = mean(x); %the mean
z = 10*log10(y); %the log
Refering to this site, the exponent is a formula to convert dB values back to power ratio (so, gain or attenuation). From this piece of code, you should get all values of A from dB back to the power ratio, which is why it is appropriate to do the second part, the mean. As it is, it computes the mean of the values column-wise, unless A is a vector (only 1 row) then the computation would be row-wise. Finally the log brings that averaged value of power ratio back to dB.
Therefore, I think this code only computes the average of a vector of dB values, not the rms.
I would recommend you to do something like
rms_A = 10*log10(rms(10.^(A/10),2));
which would convert dB values back to power ratio, find the rms of that, and turn the rms to a dB value.
As to why the dB values should be converted to power ratios first, I think this discussion presents good explanations.

Louise Wilson on 11 Aug 2019
Thank you for this awesome explanation!!
I'm sorry that an integral part of my question was worded wrongly, I want to calculate the RMS SPL in each frequency bin across all files, rather than the RMS SPL per file, which doesn't seem very useful? (I want to calculate RMS SPL in each column rather than each row)
So, from what you said, I should do:
rms_A = 10*log10(rms(10.^(A/10)));
i.e. the 2 is not necessary?
Thanks!!
Renato SL on 12 Aug 2019
If you want the computation to be column-wise, then yes, the 2 is not necessary.
Regarding if it is useful or not, I am not sure since I have not discussed the topic in a long time but yes, it doesn't seem very useful. I imagine that you would want to know the statistics (rms in this case) of a file across the frequency range, maybe like to associate a resonance frequency of every file (or something like that).