-
November 26th, 2009, 07:03 PM
#1
RMS an array
Hello-
I posted on here a couple of weeks ago and your tips helped a great deal but today I have another problem that I'm finding rather vexing, I have an array of ints from a wave file and I'd like to perform RMS on it, this would be easy if I were to do the entire array however the window size for the RMS is dynamic depending on the bit width of the wave file. I've got some psudeo code that I think would work (if I could work out how to implement it):
for(int i = 0; i <= array.size(); i++){
runningWindowCount = array[i];
runningWindowCount += array[i+1];
runningWindowCount += array[i+2];
runningWindowCount += array[i+3];
runningWindowCount += array[i+4]; // do this the amount required by the bit width
windowCountAverage = runningWindowCount / bitWidth;
RMSArray.push_back(sqrt(windowCountAverage));
}
now this should work right? however its possibly the least elegant piece of code ever plus it doesn't deal with a different bit width. any tips on how I could make this better? or make it work if it doesn't already?
thanks.
-
November 26th, 2009, 09:03 PM
#2
Re: RMS an array
Code:
for(int i = 0; i <= array.size(); i++){
runningWindowCount = array[i];
runningWindowCount += array[i+1];
runningWindowCount += array[i+2];
runningWindowCount += array[i+3];
runningWindowCount += array[i+4];
You are overwriting the boundaries of the array in that loop. Look at the value of your loop counter and how you are using it inside the loop.
For a simple case, what if the array had 2 elements? When i == 0, you are writing to array[0], array[1], array[2], array[3], and array[4]. The ones in red are invalid.
Regards,
Paul McKenzie
-
November 26th, 2009, 09:17 PM
#3
Re: RMS an array
Is RMS referring to Root Mean Square? If so, you should multiply each element by itself before summing them. I.e. runningWindowCount = array[i] * array[i]
From you question, I believe you are calculating an array of RMS value within a sliding window and its width is determined by bitWidth. Here's something I quickly put together without checking with a compiler.
Code:
for(int i = 0; i < array.size() - bitWidth; ++i) // Looping till array.size() - bitWidth to avoid running beyond the array for calculating the mean of squares.
{
double runningWindowCount = 0.0;
// Sum and loop through the sliding window within the size of bitWidth
for(int j = 0; j < bitWidth; ++j)
{
runningWindowCount += array[i+j] * array[i+j];
}
windowsCountAverage = runningWindowCount/bitWidth;
RMSArray.push_back(sqrt(windowCountAverage));
}
quoted from C++ Coding Standards:
KISS (Keep It Simple Software):
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
Avoid magic number:
Programming isn't magic, so don't incant it.
-
November 28th, 2009, 04:29 AM
#4
Re: RMS an array
Originally Posted by dommmm
now this should work right? however its possibly the least elegant piece of code ever plus it doesn't deal with a different bit width. any tips on how I could make this better? or make it work if it doesn't already?
There's a massive performance gain lying around in the second for loop. In each iteration of the outer loop you are using (bitWidth - 1) of the same elements for your average. Therefore, keeping a sum of squares and updating this in each loop will reduce the complexity from O(n * bitWidth) to O(n).
I would still advice though, that you first make sure you have the algorithm correct before you begin with such optimizations.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|