View Single Post
Old 09-19-2017, 06:23 PM   #1
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 332
Default Where have I gone wrong with this Peak/RMS code?

Flummoxed by this at the moment! I'm trying to get a Peak/RMS meter going, but it's giving strange results. I'm comparing the output with RMSBuddy and Voxengo Span which both give the same output, but can't get mine to match.

This code is giving me different results everywhere. In Ableton Live on OSX the RMS is about 3db below expected but goes higher and out of range if I increase Ableton's buffer size, and in Logic the RMS comes out around 1db lower than it should, but changing the buffer size didn't seem to affect it. Absolute Peak and Continuous Peak are coming through as expected in both. Using Ableton in Windows gives me both Peak and RMS of about 1300db :-/

Here's the troublesome code:

Code:
     int peakRMSWindowLength, peakRMSWindowCounter;
     double aveRMS, contRMS, absPeak, contPeak, allSamplesReceived;
     unsigned long totalSamples;

void IPlugEffect::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{
     // Mutex is already locked for us.
     
     double* in1 = inputs[0];
     double* in2 = inputs[1];
     double* out1 = outputs[0];
     double* out2 = outputs[1];
     
     // Reset parameters if playback is initiated after playback was stopped
     ITimeInfo ti;
     GetTime(&ti);
     bool isPlaying = ti.mTransportIsRunning;
     if (!m_WasPlaying && isPlaying) {
          allSamplesReceived = 0.0;
          totalSamples = 0;
          peakRMSWindowCounter = 0;
          contPeak = 0.0;
          contRMS = 0.0;
     }
     m_WasPlaying = isPlaying;
     
     // Processing loop
     for (int s = 0; s < nFrames; ++s, ++in1, ++in2, ++out1, ++out2)
     {
          // Increment Peak/RMS Counters
          totalSamples++;
          peakRMSWindowCounter++;
          
          // Square the input and add to the stored values
          double inSquared = in1[s] * in1[s];
          contRMS += inSquared;
          allSamplesReceived += inSquared;
          
          // Update the absolute peak value if the continuous value is higher than the stored value
          if (inSquared > contPeak)
               contPeak = inSquared;
          
          // Output text
          char text[200];
          sprintf(text, "total = %i, peakRMSWindowCounter = %i, windowlength = %i, bufsize = %i", (int)totalSamples, peakRMSWindowCounter, peakRMSWindowLength, nFrames);
          pTextOut->SetTextFromPlug(text);
          
          // Update the Peak/RMS values if the window length has been reached
          if (peakRMSWindowCounter >= peakRMSWindowLength) {
               
               // unsquare the results to get the actual sample value
               contPeak = sqrt(contPeak);
               aveRMS = sqrt(allSamplesReceived / (double)(totalSamples));
               contRMS = sqrt(contRMS / (double)peakRMSWindowLength);
               
               // Check if the Continuous Peak was higher than the Absolute Peak
               if (contPeak > absPeak)
                    absPeak = contPeak;
               
               // Send new values to display meters
               pAverageRMSOutputR->SetValue(ConvertSampleToDB(aveRMS));
               pContRMSOutputR->SetValue(ConvertSampleToDB(contRMS));
               pAbsolutePeakOutputR->SetValue(ConvertSampleToDB(absPeak));
               pContPeakOutputR->SetValue(ConvertSampleToDB(contPeak));
               
               peakRMSWindowCounter = 0;
               contPeak = 0.0;
               contRMS = 0.0;
          }
          
          *out1 = *in1;
          *out2 = *in2;
     } // End of processing loop
Bobflip is offline   Reply With Quote