![]() |
Mixxx
|
00001 /*************************************************************************** 00002 enginepregain.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 #include "engine/enginepregain.h" 00018 #include "controllogpotmeter.h" 00019 #include "controlpotmeter.h" 00020 #include "controlpushbutton.h" 00021 #include "configobject.h" 00022 #include "controlobject.h" 00023 00024 #include "sampleutil.h" 00025 #include <time.h> // for clock() and CLOCKS_PER_SEC 00026 00027 ControlPotmeter* EnginePregain::s_pReplayGainBoost = NULL; 00028 ControlObject* EnginePregain::s_pEnableReplayGain = NULL; 00029 00030 /*---------------------------------------------------------------- 00031 A pregaincontrol is ... a pregain. 00032 ----------------------------------------------------------------*/ 00033 EnginePregain::EnginePregain(const char * group) 00034 { 00035 potmeterPregain = new ControlLogpotmeter(ConfigKey(group, "pregain"), 4.); 00036 //Replay Gain things 00037 m_pControlReplayGain = new ControlObject(ConfigKey(group, "replaygain")); 00038 m_pTotalGain = new ControlObject(ConfigKey(group, "total_gain")); 00039 00040 if (s_pReplayGainBoost == NULL) { 00041 s_pReplayGainBoost = new ControlPotmeter(ConfigKey("[ReplayGain]", "InitialReplayGainBoost"),0., 15.); 00042 s_pEnableReplayGain = new ControlObject(ConfigKey("[ReplayGain]", "ReplayGainEnabled")); 00043 } 00044 00045 m_bSmoothFade = false; 00046 m_fClock=0; 00047 m_fSumClock=0; 00048 } 00049 00050 EnginePregain::~EnginePregain() 00051 { 00052 delete potmeterPregain; 00053 delete m_pControlReplayGain; 00054 delete m_pTotalGain; 00055 00056 delete s_pEnableReplayGain; 00057 s_pEnableReplayGain = NULL; 00058 delete s_pReplayGainBoost; 00059 s_pReplayGainBoost = NULL; 00060 } 00061 00062 void EnginePregain::process(const CSAMPLE * pIn, const CSAMPLE * pOut, const int iBufferSize) 00063 { 00064 00065 float fEnableReplayGain = s_pEnableReplayGain->get(); 00066 float fReplayGainBoost = s_pReplayGainBoost->get(); 00067 CSAMPLE * pOutput = (CSAMPLE *)pOut; 00068 float fGain = potmeterPregain->get(); 00069 float fReplayGain = m_pControlReplayGain->get(); 00070 m_fReplayGainCorrection=1; 00071 fGain = fGain/2; 00072 if(fReplayGain*fEnableReplayGain != 0) 00073 { 00074 // Here is the point, when ReplayGain Analyser takes its action, suggested gain changes from 0 to a nonzero value 00075 // We want to smoothly fade to this last. 00076 // Anyway we have some the problem that code cannot block the full process for one second. 00077 // So we need to alter gain each time ::process is called. 00078 00079 if(m_bSmoothFade)//This means that a ReplayGain value has been calculated after the track has been loaded 00080 { 00081 if(m_fClock==0) 00082 m_fClock=clock(); 00083 m_fSumClock += (float)((clock()-m_fClock)/CLOCKS_PER_SEC); 00084 m_fClock=clock(); 00085 if(m_fSumClock<1) 00086 { 00087 //Fade smoothly 00088 00089 m_fReplayGainCorrection=(1-m_fSumClock)+(m_fSumClock)*fReplayGain*pow(10, fReplayGainBoost/20); 00090 00091 } 00092 else 00093 { 00094 m_bSmoothFade = false; 00095 } 00096 } 00097 else 00098 { 00099 //Passing a user defined boost 00100 m_fReplayGainCorrection=fReplayGain*pow(10, fReplayGainBoost/20); 00101 } 00102 } 00103 else 00104 { 00105 // If track has not ReplayGain value and ReplayGain is enabled 00106 // we prepare for smoothfading to ReplayGain suggested gain 00107 if(fEnableReplayGain != 0) 00108 { 00109 m_bSmoothFade=true; 00110 m_fClock=0; 00111 m_fSumClock=0; 00112 } 00113 } 00114 fGain = fGain*m_fReplayGainCorrection; 00115 m_pTotalGain->set(fGain); 00116 00117 // Clamp gain to within [0, 2.0] to prevent insane gains. This can happen 00118 // (some corrupt files get really high replaygain values). 00119 fGain = math_max(0.0, math_min(2.0, fGain)); 00120 00121 //qDebug()<<"Clock"<<(float)clock()/CLOCKS_PER_SEC; 00122 // SampleUtil deals with aliased buffers and gains of 1 or 0. 00123 SampleUtil::copyWithGain(pOutput, pIn, fGain, iBufferSize); 00124 }