Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/engine/enginevumeter.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           enginevumeter.cpp  -  description
00003                              -------------------
00004     copyright            : (C) 2002 by Tue and Ken Haste Andersen
00005     email                :
00006 ***************************************************************************/
00007 
00008 /***************************************************************************
00009  *                                                                         *
00010  *   This program is free software; you can redistribute it and/or modify  *
00011  *   it under the terms of the GNU General Public License as published by  *
00012  *   the Free Software Foundation; either version 2 of the License, or     *
00013  *   (at your option) any later version.                                   *
00014  *                                                                         *
00015  ***************************************************************************/
00016 
00017 #ifdef __WINDOWS__
00018 #pragma intrinsic(fabs)
00019 #endif
00020 
00021 #include "engine/enginevumeter.h"
00022 #include "controlpotmeter.h"
00023 #include "sampleutil.h"
00024 
00025 EngineVuMeter::EngineVuMeter(const char * group) {
00026     // The VUmeter widget is controlled via a controlpotmeter, which means
00027     // that it should react on the setValue(int) signal.
00028     m_ctrlVuMeter = new ControlPotmeter(ConfigKey(group, "VuMeter"), 0., 1.);
00029     m_ctrlVuMeter->set(0);
00030     // left channel VU meter
00031     m_ctrlVuMeterL = new ControlPotmeter(ConfigKey(group, "VuMeterL"), 0., 1.);
00032     m_ctrlVuMeterL->set(0);
00033     // right channel VU meter
00034     m_ctrlVuMeterR = new ControlPotmeter(ConfigKey(group, "VuMeterR"), 0., 1.);
00035     m_ctrlVuMeterR->set(0);
00036 
00037     // Initialize the calculation:
00038     m_iSamplesCalculated = 0;
00039     m_fRMSvolumeL = 0;
00040     m_fRMSvolumeSumL = 0;
00041     m_fRMSvolumeR = 0;
00042     m_fRMSvolumeSumR = 0;
00043 }
00044 
00045 EngineVuMeter::~EngineVuMeter()
00046 {
00047     delete m_ctrlVuMeter;
00048     delete m_ctrlVuMeterL;
00049     delete m_ctrlVuMeterR;
00050 }
00051 
00052 void EngineVuMeter::process(const CSAMPLE * pIn, const CSAMPLE *, const int iBufferSize)
00053 {
00054 
00055     CSAMPLE fVolSumL, fVolSumR;
00056     SampleUtil::sumAbsPerChannel(&fVolSumL, &fVolSumR, pIn, iBufferSize);
00057     m_fRMSvolumeSumL += fVolSumL;
00058     m_fRMSvolumeSumR += fVolSumR;
00059 
00060     m_iSamplesCalculated += iBufferSize/2;
00061 
00062     // Are we ready to update the VU meter?:
00063     if (m_iSamplesCalculated > (44100/2/UPDATE_RATE) )
00064     {
00065         doSmooth(m_fRMSvolumeL, log10(m_fRMSvolumeSumL/(m_iSamplesCalculated*1000)+1));
00066         doSmooth(m_fRMSvolumeR, log10(m_fRMSvolumeSumR/(m_iSamplesCalculated*1000)+1));
00067 
00068         const double epsilon = .0001;
00069 
00070         // Since VU meters are a rolling sum of audio, the no-op checks in
00071         // ControlObject will not prevent us from causing tons of extra
00072         // work. Because of this, we use an epsilon here to be gentle on the GUI
00073         // and MIDI controllers.
00074         if (fabs(m_fRMSvolumeL - m_ctrlVuMeterL->get()) > epsilon)
00075             m_ctrlVuMeterL->set(m_fRMSvolumeL);
00076         if (fabs(m_fRMSvolumeR - m_ctrlVuMeterR->get()) > epsilon)
00077             m_ctrlVuMeterR->set(m_fRMSvolumeR);
00078 
00079         double fRMSvolume = (m_fRMSvolumeL + m_fRMSvolumeR) / 2.0;
00080         if (fabs(fRMSvolume - m_ctrlVuMeter->get()) > epsilon)
00081             m_ctrlVuMeter->set(fRMSvolume);
00082 
00083         // Reset calculation:
00084         m_iSamplesCalculated = 0;
00085         m_fRMSvolumeSumL = 0;
00086         m_fRMSvolumeSumR = 0;
00087     }
00088 }
00089 
00090 
00091 void EngineVuMeter::doSmooth(FLOAT_TYPE &currentVolume, FLOAT_TYPE newVolume)
00092 {
00093     if (currentVolume > newVolume)
00094         currentVolume -= DECAY_SMOOTHING * (currentVolume - newVolume);
00095     else
00096         currentVolume += ATTACK_SMOOTHING * (newVolume - currentVolume);
00097     if (currentVolume < 0)
00098         currentVolume=0;
00099     if (currentVolume > 1.0)
00100         currentVolume=1.0;
00101 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines