Balance root-mean-square in audio clips

I read in a paper that audio fragments were energy balanced "so that the root-mean-square power value was equal across clips". How does one balance the RMS power value across audio clips? Thanks.

9 Comments

Hi Tahariet,
Have you calculated the rms value for each audio clip as yet? With those, you simply divide each clip by its rms value to produce a set of normalized audio clips.
What is the difference then with normalizing (dividing by the maximum amplitude value)?
Yes, I have caltulated RMS and many other sound-realated acoustic parameters.
I had intended post the comment above as a comment rather than an answer as I did, so I added the comment and deleted the answer, not realizing that deleting the answer would also delete your second comment that went with it, about amplitude vs. rms.
Anyway, setting max amplitudes to be equal and setting rms power to be equal are two different things. For a simple sine or cosine wave, equal amplitude means equal power, but this is not true in general. For example, take
[1 0 0 -.6 0 0 0 .2 .4 -1] % a)
[1 -1 1 -1 1 -1 1 -1 1 -1] % b)
Both of these have mean value 0 and max amplitude 1. But b) has many more large-value excursions from the mean than does a), so b) has the larger rms power.
Max amplitude has some uses, such as comparison to a voltage threshold to see if you are in danger of shorting something out. But in general it is not the greatest of metrics for a wave.
Thanks so much for taking the time to explain this. Then, in the context of a perceptual experiment where one needs to make sure that the root-mean-square power value is equal across music clips, I should just have to calculate the RMS value (per L/R channel) and divide each of the L/R values by its corresponding RMS value?
Kind of depends. If you divide each L by its rms value and each R by its rms value, then the power of the left and right channels are the same not just clip to clip, but the same as each other. That might be ok a lot of the time, but if you were investigating some phenomenon that depended on different signal strength in L and R, then making the the L and R channels the same would of course not be appropriate . If you want to preserve differences between L and R and have the total power in both channels be the same from clip to clip, then I believe you divide both L and R not by ( rms( L ) + rms( R ) ) / 2 or something similar, but rather divide them both by
sqrt(rms(L)^2 + rms(R)^2)
That's right, I want to preserve the ratio L/R. I couldn't understand why we divide by the sqrt of the sum of squares.
I tried your approach but it doesn't seem to maintain the ratio between left and right. For instance, the RMS= 0.1334 0.1265 (L and R), so the sqrt(rms(L)^2 + rms®^2) = 0.1838. When I plug this into the denominator to divide both L and R, the rms of this resulting quantity is 0.7256 0.0057.
Something must have gone wrong, because it does work
% make two channels with rms value .1334, .1265
a = rand(1,1000);
b = rand(1,1000);
a = .1334*a/rms(a);
b = .1265*b/rms(b);
rms_ab = [rms(a) rms(b)]
% normalize
anorm = a/sqrt(rms(a)^2 + rms(b)^2);
bnorm = b/sqrt(rms(a)^2 + rms(b)^2);
rmsnorm_ab = [rms(anorm) rms(bnorm)]
% same ratio for these two
rat = [rms(a)/rms(b) rms(anorm)/rms(bnorm)]
I shall comment on sum of squares, but right now lunch is calling.

Sign in to comment.

 Accepted Answer

Hi Tahariet,
You would like to normalize R and L so that the sum of R power and L power does not change from clip to clip. The ratio between R power and L power stays the same before and after normalization. Calling the channels a and b rather than R and L, then
anorm = a / sqrt(rms(a)^2 + rms(b)^2);
bnorm = b / sqrt(rms(a)^2 + rms(b)^2);
This works because, first, although people say it all the time (including in your question), the phrase "rms power" is a misnomer. rms is an amplitude.
In terms of voltage, assuming a signal with mean 0 for simplicity (and dropping the factor of 1/R since keeping it around does not change the conclusion), the average power is P = mean(V.^2). Root mean square = sqrt(mean(V.^2)) is linear in V, so it's an amplitude. And
P = rms^2.
You want to normalize so that Panorm + Pbnorm is the same from clip to clip, so
Panorm = Pa/(Pa+Pb)
Pbnorm = Pb/(Pa+Pb)
When you take the square root of both sides and use P = rms^2 everywhere, then you get the anorm and bnorm expressions.

5 Comments

Brilliant. Thank you! I just modified my last question for being irrelevant in this thread (apologies). Now I have normalized the audio clips keeping left/right ratios, but when saving the channels using audiowrite, the audio, I get a warning "Warning: Data clipped when writing file". Indeed, the audio is distorted at points. This is because the range of the values now exceeds [-1 1]. But the problem is how to make values in the signal fall within that range while making them RMS-comparable. I think this is not possible.
I see what you mean. Fortunately there is a remedy.
The normalization rescaled every clip so that its total power (Panorm + Pbnorm) = 1 as implied by the last two equations in the answer above. Taking the square root to get { the rms value that represents the total power }, then the rms value = 1 for normalized clips. The total power of every normalized clip is identical, which was the goal. But the rms value of 1 is too large and leads to clipping as you saw.
All that has to be done is to rescale all of the normalized clips by the same factor to bring them down to the right level.
For a given clip the rms value is
rms_clip = sqrt(rms(a)^2 + rms(b)^2).
In the example you showed,
rms_clip = sqrt(rms(a)^2+rms(b)^2) = .1838.
Presumably the rms value of all the other clips is in the same neighborhood. By surveying all the clips you can come up with an average value rms_clip_ave. One single number for the entire set of clips. Let's say it's somewhere around 0.2 (the normalized rms value is five times this, so no wonder there was clipping). Then the process is the same as before, only with the same constant factor in front of all of them:
anew = rms_clip_ave * (a / sqrt(rms(a)^2 + rms(b)^2));
bnew = rms_clip_ave * (b / sqrt(rms(a)^2 + rms(b)^2));
If there were still any clipping I would think it would not be by much, and you could multiply all the clips by a common factor not too much less than 1 to get rid of it.
p.s. I probably doesn't matter a whole lot if you find rms_clip_ave just by eyeballing all of the individual rms_clips, but it shouldn't be too surprising that for N clips the most formal definition is
rms_clip_ave = sqrt( (rms_clip_1^2 + rms_clip_2^2 + ... rms_clip_N^2) / N)
Thousand thanks. Yes, the factor (rms_clip_ave) that makes all clips to have amplitude within (-1, 1) is .156 (using trial and error). This makes the RMS of both channels added up to be .156.
I was curious and tried your approach to find rms_clip_ave but it returned .534 instead.
r=sqrt(sum(sqrt(RMS(:,1).^2+RMS(:,2).^2))/12)
RMS is a 12x2 matrix containing L and R rms values for each of the 12 clips.
Hope it makes sense!
Hi Nuchto, Well it does not quite make sense. In the expression for r there should be no inner sqrt function. One sqrt on the outside, as in the expression for rms_clip_ave, that's it. Not that the result is going to agree with .156, but at least it will be smaller. The expression for r is not a confidence builder so I hope that in the main calculations you will go back and make sure that there are no extra sqrts floating around. I hope your experiment turns out well.
Thanks for noticing. Using
r=sqrt(mean(RMS(:,1).^2 + RMS(:,2).^2))
It gives .3157, still not quite, but close.

Sign in to comment.

More Answers (0)

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!