![]() |
Mixxx
|
00001 /*************************************************************************** 00002 dlgprefeq.cpp - description 00003 ------------------- 00004 begin : Thu Jun 7 2007 00005 copyright : (C) 2007 by John Sully 00006 email : jsully@scs.ryerson.ca 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #include "dlgprefeq.h" 00019 #include "engine/enginefilteriir.h" 00020 #include <qlineedit.h> 00021 #include <qwidget.h> 00022 #include <qslider.h> 00023 #include <qlabel.h> 00024 #include <qstring.h> 00025 #include <qcheckbox.h> 00026 #include <qpushbutton.h> 00027 #include <qgraphicsscene.h> 00028 00029 #include <assert.h> 00030 00031 #define CONFIG_KEY "[Mixer Profile]" 00032 00033 const int kFrequencyUpperLimit = 20050; 00034 const int kFrequencyLowerLimit = 16; 00035 00036 DlgPrefEQ::DlgPrefEQ(QWidget *pParent, ConfigObject<ConfigValue> *pConfig) 00037 : QWidget(pParent) 00038 , Ui::DlgPrefEQDlg() 00039 #ifndef __LOFI__ 00040 , m_COTLoFreq(ControlObject::getControl(ConfigKey(CONFIG_KEY, "LoEQFrequency"))) 00041 , m_COTHiFreq(ControlObject::getControl(ConfigKey(CONFIG_KEY, "HiEQFrequency"))) 00042 , m_COTLoFi(ControlObject::getControl(ConfigKey(CONFIG_KEY, "LoFiEQs"))) 00043 #endif 00044 { 00045 m_pConfig = pConfig; 00046 00047 setupUi(this); 00048 00049 // Connection 00050 #ifndef __LOFI__ 00051 connect(SliderHiEQ, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateHiEQ())); 00052 connect(SliderHiEQ, SIGNAL(sliderMoved(int)), this, SLOT(slotUpdateHiEQ())); 00053 connect(SliderHiEQ, SIGNAL(sliderReleased()), this, SLOT(slotUpdateHiEQ())); 00054 00055 connect(SliderLoEQ, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateLoEQ())); 00056 connect(SliderLoEQ, SIGNAL(sliderMoved(int)), this, SLOT(slotUpdateLoEQ())); 00057 connect(SliderLoEQ, SIGNAL(sliderReleased()), this, SLOT(slotUpdateLoEQ())); 00058 00059 connect(CheckBoxLoFi, SIGNAL(stateChanged(int)), this, SLOT(slotLoFiChanged())); 00060 #else 00061 CheckBoxLoFi->setChecked(true); 00062 slotLoFiChanged(); 00063 CheckBoxLoFi->setEnabled(false); 00064 #endif 00065 connect(PushButtonReset, SIGNAL(clicked(bool)), this, SLOT(reset())); 00066 00067 m_lowEqFreq = 0; 00068 m_highEqFreq = 0; 00069 00070 loadSettings(); 00071 } 00072 00073 DlgPrefEQ::~DlgPrefEQ() 00074 { 00075 } 00076 00077 void DlgPrefEQ::loadSettings() 00078 { 00079 QString highEqCourse = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "HiEQFrequency")); 00080 QString highEqPrecise = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "HiEQFrequencyPrecise")); 00081 QString lowEqCourse = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "LoEQFrequency")); 00082 QString lowEqPrecise = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "LoEQFrequencyPrecise")); 00083 00084 double lowEqFreq = 0.0; 00085 double highEqFreq = 0.0; 00086 00087 // Precise takes precedence over course. 00088 lowEqFreq = lowEqCourse.isEmpty() ? lowEqFreq : lowEqCourse.toDouble(); 00089 lowEqFreq = lowEqPrecise.isEmpty() ? lowEqFreq : lowEqPrecise.toDouble(); 00090 highEqFreq = highEqCourse.isEmpty() ? highEqFreq : highEqCourse.toDouble(); 00091 highEqFreq = highEqPrecise.isEmpty() ? highEqFreq : highEqPrecise.toDouble(); 00092 00093 if (lowEqFreq == 0.0 || highEqFreq == 0.0 || lowEqFreq == highEqFreq) { 00094 CheckBoxLoFi->setChecked(true); 00095 setDefaultShelves(); 00096 lowEqFreq = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "LoEQFrequencyPrecise")).toDouble(); 00097 highEqFreq = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "HiEQFrequencyPrecise")).toDouble(); 00098 } 00099 00100 SliderHiEQ->setValue( 00101 getSliderPosition(highEqFreq, 00102 SliderHiEQ->minimum(), 00103 SliderHiEQ->maximum())); 00104 SliderLoEQ->setValue( 00105 getSliderPosition(lowEqFreq, 00106 SliderLoEQ->minimum(), 00107 SliderLoEQ->maximum())); 00108 00109 if (m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "LoFiEQs")) == QString("yes")) { 00110 CheckBoxLoFi->setChecked(true); 00111 } else { 00112 CheckBoxLoFi->setChecked(false); 00113 } 00114 00115 slotUpdate(); 00116 slotApply(); 00117 } 00118 00119 void DlgPrefEQ::setDefaultShelves() 00120 { 00121 m_pConfig->set(ConfigKey(CONFIG_KEY, "HiEQFrequency"), ConfigValue(2500)); 00122 m_pConfig->set(ConfigKey(CONFIG_KEY, "LoEQFrequency"), ConfigValue(250)); 00123 m_pConfig->set(ConfigKey(CONFIG_KEY, "HiEQFrequencyPrecise"), ConfigValue(2500.0)); 00124 m_pConfig->set(ConfigKey(CONFIG_KEY, "LoEQFrequencyPrecise"), ConfigValue(250.0)); 00125 } 00126 00129 void DlgPrefEQ::reset() { 00130 setDefaultShelves(); 00131 loadSettings(); 00132 } 00133 00134 void DlgPrefEQ::slotLoFiChanged() 00135 { 00136 GroupBoxHiEQ->setEnabled(!CheckBoxLoFi->isChecked()); 00137 GroupBoxLoEQ->setEnabled(!CheckBoxLoFi->isChecked()); 00138 if(CheckBoxLoFi->isChecked()) { 00139 m_pConfig->set(ConfigKey(CONFIG_KEY, "LoFiEQs"), ConfigValue(QString("yes"))); 00140 } else { 00141 m_pConfig->set(ConfigKey(CONFIG_KEY, "LoFiEQs"), ConfigValue(QString("no"))); 00142 } 00143 slotApply(); 00144 } 00145 00146 void DlgPrefEQ::slotUpdateHiEQ() 00147 { 00148 if (SliderHiEQ->value() < SliderLoEQ->value()) 00149 { 00150 SliderHiEQ->setValue(SliderLoEQ->value()); 00151 } 00152 m_highEqFreq = getEqFreq(SliderHiEQ->value(), 00153 SliderHiEQ->minimum(), 00154 SliderHiEQ->maximum()); 00155 validate_levels(); 00156 if (m_highEqFreq < 1000) { 00157 TextHiEQ->setText( QString("%1 Hz").arg((int)m_highEqFreq)); 00158 } else { 00159 TextHiEQ->setText( QString("%1 kHz").arg((int)m_highEqFreq / 1000.)); 00160 } 00161 m_pConfig->set(ConfigKey(CONFIG_KEY, "HiEQFrequency"), 00162 ConfigValue(QString::number(static_cast<int>(m_highEqFreq)))); 00163 m_pConfig->set(ConfigKey(CONFIG_KEY, "HiEQFrequencyPrecise"), 00164 ConfigValue(QString::number(m_highEqFreq, 'f'))); 00165 00166 slotApply(); 00167 } 00168 00169 void DlgPrefEQ::slotUpdateLoEQ() 00170 { 00171 if (SliderLoEQ->value() > SliderHiEQ->value()) 00172 { 00173 SliderLoEQ->setValue(SliderHiEQ->value()); 00174 } 00175 m_lowEqFreq = getEqFreq(SliderLoEQ->value(), 00176 SliderLoEQ->minimum(), 00177 SliderLoEQ->maximum()); 00178 validate_levels(); 00179 if (m_lowEqFreq < 1000) { 00180 TextLoEQ->setText(QString("%1 Hz").arg((int)m_lowEqFreq)); 00181 } else { 00182 TextLoEQ->setText(QString("%1 kHz").arg((int)m_lowEqFreq / 1000.)); 00183 } 00184 m_pConfig->set(ConfigKey(CONFIG_KEY, "LoEQFrequency"), 00185 ConfigValue(QString::number(static_cast<int>(m_lowEqFreq)))); 00186 m_pConfig->set(ConfigKey(CONFIG_KEY, "LoEQFrequencyPrecise"), 00187 ConfigValue(QString::number(m_lowEqFreq, 'f'))); 00188 00189 slotApply(); 00190 } 00191 00192 int DlgPrefEQ::getSliderPosition(double eqFreq, int minValue, int maxValue) 00193 { 00194 if (eqFreq >= kFrequencyUpperLimit) { 00195 return maxValue; 00196 } else if (eqFreq <= kFrequencyLowerLimit) { 00197 return minValue; 00198 } 00199 double dsliderPos = (eqFreq - kFrequencyLowerLimit) / (kFrequencyUpperLimit-kFrequencyLowerLimit); 00200 dsliderPos = pow(dsliderPos, 1./4.) * (maxValue - minValue) + minValue; 00201 return dsliderPos; 00202 } 00203 00204 00205 void DlgPrefEQ::slotApply() 00206 { 00207 #ifndef __LOFI__ 00208 m_COTLoFreq.slotSet(m_lowEqFreq); 00209 m_COTHiFreq.slotSet(m_highEqFreq); 00210 m_COTLoFi.slotSet(CheckBoxLoFi->isChecked()); 00211 #endif 00212 } 00213 00214 void DlgPrefEQ::slotUpdate() 00215 { 00216 slotUpdateLoEQ(); 00217 slotUpdateHiEQ(); 00218 slotLoFiChanged(); 00219 } 00220 00221 double DlgPrefEQ::getEqFreq(int sliderVal, int minValue, int maxValue) { 00222 // We're mapping f(x) = x^4 onto the range kFrequencyLowerLimit, 00223 // kFrequencyUpperLimit with x [minValue, maxValue]. First translate x into 00224 // [0.0, 1.0], raise it to the 4th power, and then scale the result from 00225 // [0.0, 1.0] to [kFrequencyLowerLimit, kFrequencyUpperLimit]. 00226 double normValue = static_cast<double>(sliderVal - minValue) / 00227 (maxValue - minValue); 00228 // Use a non-linear mapping between slider and frequency. 00229 normValue = normValue * normValue * normValue * normValue; 00230 double result = normValue * (kFrequencyUpperLimit-kFrequencyLowerLimit) + 00231 kFrequencyLowerLimit; 00232 return result; 00233 } 00234 00235 void DlgPrefEQ::validate_levels() { 00236 m_highEqFreq = math_max(math_min(m_highEqFreq, kFrequencyUpperLimit), 00237 kFrequencyLowerLimit); 00238 m_lowEqFreq = math_max(math_min(m_lowEqFreq, kFrequencyUpperLimit), 00239 kFrequencyLowerLimit); 00240 if (m_lowEqFreq == m_highEqFreq) { 00241 if (m_lowEqFreq == kFrequencyLowerLimit) { 00242 ++m_highEqFreq; 00243 } else if (m_highEqFreq == kFrequencyUpperLimit) { 00244 --m_lowEqFreq; 00245 } else { 00246 ++m_highEqFreq; 00247 } 00248 } 00249 }