Ben Wheeler wrote:
Andreas Pflug <[email protected]> wrote:

Using the outline skin on Debian 5.0, I see mixxx consuming 13 % CPU,
and xorg 32% even when there's no visual change.

Digging a little on the performance issues mentioned in the wiki, I
found that preventing ControlObject from changing unchanged values does
the trick, see attached trivial patch against trunk. It reduces xorg
CPU usage to a minimum when there's no display update.

Blimey. Sometimes the simplest optimisations are staring you in the face. Nice one Andreas. Can I request that this is put into 1.7.0, I know it's late in the day but it looks totally safe to me and definitely worth doing.

As soon as I play, the cpu usage rises again (mostly in xorg, caused by
wVuMeter updates), which I reduced drastically by using repaint()
instead of update() in WWidget::setValue().

I'm not familiar with the difference between repaint() and update(), might there be any side-effects here other than the speed gain? Eg LEDs?
Qt doc claims update() should be preferred because it can optimize calls, but apparently it does so _very_ inefficiently. If in doubt, the effect might be restricted to WVuMeter by calling repaint() from there directly instead of calling WWidget::setValue().

With this fix, the VU-meter display makes my eyes aching because there's no decay. Reviewing the code in EngineVUmeter shows that there's no smoothing applied To VUmeterL and VUmeterR, and after some useless calculation effectively zero on VUmeter.

Attached a patch with a more sensible implentation (and a fix for m_iSamplesCalculated not being int; I know why I'm not a fan of mangling the type into variable names...) Currently, it's _not_ sensible to apply attack smoothing, because this would prevent the peak display from displaying the peak ;-). For the next release, an extended setValue (taking both average and peak) is needed.

Regards,
Andreas

Index: src/engine/enginevumeter.cpp
===================================================================
--- src/engine/enginevumeter.cpp	(revision 2748)
+++ src/engine/enginevumeter.cpp	(working copy)
@@ -59,23 +59,31 @@
     m_iSamplesCalculated += iBufferSize/2;
 
     // Are we ready to update the VU meter?:
-    if (m_iSamplesCalculated*2 > (44100/UPDATE_RATE) )
+    if (m_iSamplesCalculated > (44100/2/UPDATE_RATE) )
     {
-        m_fRMSvolumeL = log10(m_fRMSvolumeSumL/(m_iSamplesCalculated*1000)+1);
-        m_fRMSvolumeR = log10(m_fRMSvolumeSumR/(m_iSamplesCalculated*1000)+1);
-        m_ctrlVuMeterL->set( math_min(1.0, math_max(0.0, m_fRMSvolumeL)) );
-        m_ctrlVuMeterR->set( math_min(1.0, math_max(0.0, m_fRMSvolumeR)) );
+        doSmooth(m_fRMSvolumeL, log10(m_fRMSvolumeSumL/(m_iSamplesCalculated*1000)+1));
+	doSmooth(m_fRMSvolumeR, log10(m_fRMSvolumeSumR/(m_iSamplesCalculated*1000)+1));
 
-        FLOAT_TYPE m_fRMSvolume = (m_fRMSvolumeL + m_fRMSvolumeR) / 2;
-        FLOAT_TYPE m_fRMSvolumePrev = m_fRMSvolume;
-        FLOAT_TYPE smoothFactor;
-        // Smooth the output
-        smoothFactor = (m_fRMSvolumePrev > m_fRMSvolume) ? DECAY_SMOOTHING : ATTACK_SMOOTHING;
-        m_fRMSvolume = m_fRMSvolumePrev + smoothFactor * (m_fRMSvolume - m_fRMSvolumePrev);
-        m_ctrlVuMeter->set( math_min(1.0, math_max(0.0, m_fRMSvolume)) );
-        // Reset calculation:
+	m_ctrlVuMeterL->set(m_fRMSvolumeL);
+        m_ctrlVuMeterR->set(m_fRMSvolumeR);
+        m_ctrlVuMeter->set( (m_fRMSvolumeL + m_fRMSvolumeR) / 2);
+
+	    // Reset calculation:
         m_iSamplesCalculated = 0;
         m_fRMSvolumeSumL = 0;
         m_fRMSvolumeSumR = 0;
     }
 }
+
+
+ void EngineVuMeter::doSmooth(FLOAT_TYPE &currentVolume, FLOAT_TYPE newVolume)
+{
+	if (currentVolume > newVolume)
+		currentVolume -= DECAY_SMOOTHING * (currentVolume - newVolume);
+	else
+		currentVolume += ATTACK_SMOOTHING * (newVolume - currentVolume);
+	if (currentVolume < 0)
+		currentVolume=0;
+	if (currentVolume > 1.0)
+		currentVolume=1.0;
+}
Index: src/engine/enginevumeter.h
===================================================================
--- src/engine/enginevumeter.h	(revision 2748)
+++ src/engine/enginevumeter.h	(working copy)
@@ -24,8 +24,8 @@
 
 //SMOOTHING FACTORS
 //Must be from 0-1 the lower the factor, the more smoothing that is applied
-#define ATTACK_SMOOTHING .85
-#define DECAY_SMOOTHING .4//.16//.4
+#define ATTACK_SMOOTHING 1. // .85
+#define DECAY_SMOOTHING .1  //.16//.4
 
 class ControlPotmeter;
 
@@ -43,7 +43,9 @@
     FLOAT_TYPE m_fRMSvolumeSumL;
     FLOAT_TYPE m_fRMSvolumeR;
     FLOAT_TYPE m_fRMSvolumeSumR;
-    FLOAT_TYPE m_iSamplesCalculated;
+    int m_iSamplesCalculated;
+
+    void doSmooth(FLOAT_TYPE &currentVolume, FLOAT_TYPE newVolume);
 };
 
 #endif
------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations 
Conference from O'Reilly Media. Velocity features a full day of 
expert-led, hands-on workshops and two days of sessions from industry 
leaders in dedicated Performance & Operations tracks. Use code vel09scf 
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
_______________________________________________
Mixxx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mixxx-devel

Reply via email to