Avatar

Please consider registering
Guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed sp_TopicIcon
RMS moving average
No permission to create posts
November 5, 2014
3:56 pm
Avatar
JD Young
Leiden, The Netherlands
Admin
Forum Posts: 80
Member Since:
November 5, 2014
sp_UserOfflineSmall Offline

First of all, Will, what a great book and a great piece of software you’ve created. It’s just what I needed:) Thanks so much!

I’ve worked through ‘designing audio effect plug-ins in c++’ and I’m trying to work out some ideas of my own now. I’m working on a compressor at the moment, which works fine, but I’m having trouble making it respond to RMS volume. In CEnvelopeDetector::detect you do have an RMS detection mode, but I guess it will just use 1 sample at a time as a basis for its calculations. I would like to calculate the RMS value over, let’s say, 30 ms (with a moving average). I tried modifying CEnvelopeDetector with a circular buffer. It compiles without problems, but it crashes in RMS mode every time.

Is there anyone who can help me modify CEnvelopeDetector or CEnvelopeDetector::detect to incorporate this functionality? Or is there something I'm missing here?

All the best,

JD

November 5, 2014
5:37 pm
Avatar
Tom
Admin
Forum Posts: 65
Member Since:
April 3, 2014
sp_UserOfflineSmall Offline

If it crashes, it's a programming error - so I'm quite sure I can help you with this ;-)
Can you post your RMS/Circular Buffer code?

November 5, 2014
9:06 pm
Avatar
JD Young
Leiden, The Netherlands
Admin
Forum Posts: 80
Member Since:
November 5, 2014
sp_UserOfflineSmall Offline

Thanks very much for your reply Tom! I’m not very experienced in C++ yet, so I might have made an obvious mistake… Here is my function for the circular buffer (with all irrelevant code deleted) and for getting the RMS value. I hope I didn’t screw up too bad! Any help is welcome:)

CEnvelopeDetector::CEnvelopeDetector(void)
{
m_nIndex = 0;
m_pBuffer = NULL;
m_nBufferSize = 0;

SOM = 0;
RMSvalue = 0;
}

void CEnvelopeDetector::resetBuffer()
{
if(m_pBuffer)
memset(m_pBuffer, 0,m_nBufferSize*sizeof(float));

m_nIndex = 0;
}

void CEnvelopeDetector::prepareForPlay()
{
m_nBufferSize = 30*(m_fSampleRate/1000);
m_pBuffer = new float[m_nBufferSize];

resetBuffer();
}

CEnvelopeDetector::~CEnvelopeDetector(void)
{
delete [] m_pBuffer;
}

float CEnvelopeDetector::getRMSvalue(float sampleNEW)
{
m_pBuffer[m_nIndex] = sampleNEW;

int sampleOLD;
if (m_nIndex = m_nBufferSize) m_nIndex = 0;

return RMSvalue;
}

November 5, 2014
9:08 pm
Avatar
JD Young
Leiden, The Netherlands
Admin
Forum Posts: 80
Member Since:
November 5, 2014
sp_UserOfflineSmall Offline

mmm it deleted the most important function partly. Try again:

float CEnvelopeDetector::getRMSvalue(float sampleNEW)
{
m_pBuffer[m_nIndex] = sampleNEW;

int sampleOLD;
if (m_nIndex = m_nBufferSize) m_nIndex = 0;

return RMSvalue;
}

November 5, 2014
9:09 pm
Avatar
JD Young
Leiden, The Netherlands
Admin
Forum Posts: 80
Member Since:
November 5, 2014
sp_UserOfflineSmall Offline

nope, did it again...

November 5, 2014
9:12 pm
Avatar
JD Young
Leiden, The Netherlands
Admin
Forum Posts: 80
Member Since:
November 5, 2014
sp_UserOfflineSmall Offline

lets try without the braces:

m_pBuffer[m_nIndex] = sampleNEW;

int sampleOLD;
if (m_nIndex = m_nBufferSize) m_nIndex = 0;

return RMSvalue;

November 5, 2014
9:13 pm
Avatar
JD Young
Leiden, The Netherlands
Admin
Forum Posts: 80
Member Since:
November 5, 2014
sp_UserOfflineSmall Offline

Nope, this is frustrating to say the least... haha

November 5, 2014
10:23 pm
Avatar
Tom
Admin
Forum Posts: 65
Member Since:
April 3, 2014
sp_UserOfflineSmall Offline

JD Young said

lets try without the braces:

m_pBuffer[m_nIndex] = sampleNEW;

int sampleOLD;
if (m_nIndex = m_nBufferSize) m_nIndex = 0;

return RMSvalue;

if (m_nIndex = m_nBufferSize)...

I guess this should be m_nIndex == m_nBufferSize?
Or more likely (m_nIndex >= m_nBufferSize-1)

Where do you increment the m_nIndex and where is the RMSValue calculated (or is this just truncated in the post)?
You are currently at least one sample behind with the getRMSValue method (given that the RMSValue is calculated somewhere else but not updated inside getRMSValue).

November 6, 2014
4:14 pm
Avatar
JD Young
Leiden, The Netherlands
Admin
Forum Posts: 80
Member Since:
November 5, 2014
sp_UserOfflineSmall Offline

Thanks Tom, that's a little step further! But parts of my code were deleted somehow, so the most important lines are not there...

November 6, 2014
6:26 pm
Avatar
W Pirkle
Admin
Forum Posts: 143
Member Since:
January 28, 2017
sp_UserOfflineSmall Offline

It looks like you guys are working through the circular buffer issue, and usually circular buffer crashes happen when the index goes out of bounds of the buffer. I agree with Tom; ultimately this is a programming problem.

Meantime, check out this awesome paper on digital compressor design; there is a wealth of knowledge here on RMS detectors and the analog variations:

http://www.eecs.qmul.ac.uk/~jo.....ES2012.pdf

BTW: this paper came from a design tutorial that Joshua Reiss presented at the AES show in NY, 2011 (I think). I was there, and a good chunk of that presentation is in my Compressor chapter (it is referenced properly in the Bibliography). You will also notice several textual references to Reiss in that Chapter.

In this paper he explains why a RMS detector using a window of samples (a buffer as you are attempting) is not really useful for realtime processing. He provides a detector algorithm that only has one sample of storage. It uses a similar strategy as CEnvelopeDetector. I think that might also help you.

Also, CEnvelopedDetector is based very closely on the algorithm here (it is also referenced in the Bibliography):

http://musicdsp.org/archive.ph.....assid=2#97

Scroll down a bit to see more information on that page. You can also see that this algorithm is very similar to the Reiss version.

Dr. Reiss He has done a ton of work bringing this information out to the public so that is awesome. He also has a new book out on Plugins (it is is on a sister-publisher to Focal Press) but I have not checked it out yet.

Hope you get your buffer issues worked out so you can compare the performance with CEnvelopeDetector. You might also want to try to implement the RMS detector(s) in the Reiss paper too.

All the best,

Will

November 6, 2014
8:42 pm
Avatar
JD Young
Leiden, The Netherlands
Admin
Forum Posts: 80
Member Since:
November 5, 2014
sp_UserOfflineSmall Offline

Hi Will,
Thanks for the great tips! I’ve got some more studying to do ;)
Have a good day:) JD

November 11, 2014
5:16 am
Avatar
Tom
Admin
Forum Posts: 65
Member Since:
April 3, 2014
sp_UserOfflineSmall Offline

Will said

In this paper he explains why a RMS detector using a window of samples (a buffer as you are attempting) is not really useful for realtime processing.

Interesting...this may explain why every "RMS Meter" looks different. So most of them actually are no real RMS meters in the mathematically correct sense but some kind of envelope followers which more or less incorporate some "root" values!?

November 11, 2014
5:41 pm
Avatar
W Pirkle
Admin
Forum Posts: 143
Member Since:
January 28, 2017
sp_UserOfflineSmall Offline

Yes and no. The analog detector circuits are based on charging and discharging a capacitor and are mathematical integrators (the C is charged through an R). Studying the RC lowpass filter reveals an integrator in a feedback loop. Digital integration is done with similar feedback loops and you could kind of loosely call that "envelope following" (I'm talking VERY loosely). There is a section on digital integration in Chap 4 of my new book showing the 3 most common integrators and shows a sample-by-sample output of one of them. They are all destined to be only approximations to continuous time integration since they are discretized. So in a way, solving the RMS detection (or peak or mean square) problem is always going to be an approximation. If you were going to use a window-of-samples you would need to ask what is the best size? Analog detectors don't work on windows of samples. They integrate continuously.

Will

November 18, 2014
1:49 am
Avatar
JD Young
Leiden, The Netherlands
Admin
Forum Posts: 80
Member Since:
November 5, 2014
sp_UserOfflineSmall Offline

Hi Will and Tom,

I finally got it to work and I now have a RMS detection mode over a window of 30 ms, which makes the compressor sound just like I wanted. I also read the paper; which was really interesting. I’m going to try their approach as well, although I must admit – being a mastering engineer first – I have some difficulties with getting an intuitive feel for this kind of DSP in combination with C++. I’m so used to judge plug-ins like this by ear:) But your book has me already gotten so much further in about 6 months then I would have expected ever to come! And it’s great that I can bother you with my questions on this forum from time to time…

Thanks so much for both your help!

JD

November 18, 2014
3:21 am
Avatar
W Pirkle
Admin
Forum Posts: 143
Member Since:
January 28, 2017
sp_UserOfflineSmall Offline

Hi JD

Glad to hear you are up and running!! That is a great feeling. I would love to hear some comparisons of your compressor with your new RMS detector vs. the CEnvelopeDetector vs. the Reiss paper detectors; would be interesting to do a blind listening test. And thanks for the kind words about the book - that is exactly why I wrote it - to get musicians with engineering interests up to speed on plug-in programming quickly. Now that the new Synth book is out and the website is up, I can get back to the new RAFX v6.5. Hope to have it ready by Dec 1.

Keep up the hard/great work!

Will

Forum Timezone: America/New_York

Most Users Ever Online: 36

Currently Online:
3 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

Skyler: 47

Peter: 41

Derek: 41

clau_ste: 39

Frodson: 38

Gwen: 32

EZB: 24

lppier: 23

Msaldaña: 18

Jorge: 17

Member Stats:

Guest Posters: 1

Members: 476

Moderators: 1

Admins: 4

Forum Stats:

Groups: 11

Forums: 30

Topics: 482

Posts: 1876

Newest Members:

sam, annaharris, Marie Weaver, kev, Steven, Mr Anderson, mguy, omelc

Moderators: W Pirkle: 143

Administrators: Tom: 65, JD Young: 80, Will Pirkle: 0, W Pirkle: 143