diff --git a/build/depends.py b/build/depends.py index c5129e6ea20..14a17f73460 100644 --- a/build/depends.py +++ b/build/depends.py @@ -581,7 +581,6 @@ def sources(self, build): "engine/enginebufferscale.cpp", "engine/enginebufferscaledummy.cpp", "engine/enginebufferscalelinear.cpp", - "engine/enginefilterblock.cpp", "engine/enginefilterbiquad1.cpp", "engine/enginefiltermoogladder4.cpp", "engine/enginefilterbessel4.cpp", diff --git a/res/skins/Shade/effect_parameter_knob.xml b/res/skins/Shade/effect_parameter_knob.xml index b6f2c109612..70b3aa8f618 100644 --- a/res/skins/Shade/effect_parameter_knob.xml +++ b/res/skins/Shade/effect_parameter_knob.xml @@ -38,7 +38,6 @@ 38,26 - master_volume 64 knobs/knob_rotary_s%1.png diff --git a/res/skins/Shade/mixer_panel.xml b/res/skins/Shade/mixer_panel.xml index 65998404921..85107952269 100644 --- a/res/skins/Shade/mixer_panel.xml +++ b/res/skins/Shade/mixer_panel.xml @@ -426,6 +426,10 @@ true LeftButton + + [Channel1],filterHighKill_loaded + visible + filterMidKill @@ -447,6 +451,10 @@ true LeftButton + + [Channel1],filterMidKill_loaded + visible + filterLowKill @@ -468,6 +476,10 @@ true LeftButton + + [Channel1],filterLowKill_loaded + visible + @@ -490,6 +502,10 @@ true LeftButton + + [Channel2],filterHighKill_loaded + visible + filterMidKill @@ -511,6 +527,10 @@ true LeftButton + + [Channel2],filterMidKill_loaded + visible + filterLowKill @@ -532,6 +552,10 @@ true LeftButton + + [Channel2],filterLowKill_loaded + visible + + 16,16 me,me - 100,100 [Library],show_coverart visible diff --git a/src/basetrackplayer.cpp b/src/basetrackplayer.cpp index ccbc27e56d6..2267d3bb61d 100644 --- a/src/basetrackplayer.cpp +++ b/src/basetrackplayer.cpp @@ -27,6 +27,12 @@ BaseTrackPlayer::BaseTrackPlayer(QObject* pParent, : BasePlayer(pParent, group), m_pConfig(pConfig), m_pLoadedTrack(), + m_pLowFilter(NULL), + m_pMidFilter(NULL), + m_pHighFilter(NULL), + m_pLowFilterKill(NULL), + m_pMidFilterKill(NULL), + m_pHighFilterKill(NULL), m_replaygainPending(false) { m_pChannel = new EngineDeck(getGroup(), pConfig, pMixingEngine, pEffectsManager, defaultOrientation); @@ -73,9 +79,7 @@ BaseTrackPlayer::BaseTrackPlayer(QObject* pParent, m_pEndOfTrack = new ControlObject(ConfigKey(group, "end_of_track")); m_pEndOfTrack->set(0.); - m_pLowFilter = new ControlObjectSlave(group,"filterLow"); - m_pMidFilter = new ControlObjectSlave(group,"filterMid"); - m_pHighFilter = new ControlObjectSlave(group,"filterHigh"); + m_pPreGain = new ControlObjectSlave(ConfigKey(group, "pregain")); //BPM of the current song m_pBPM = new ControlObjectThread(group, "file_bpm"); @@ -108,6 +112,9 @@ BaseTrackPlayer::~BaseTrackPlayer() delete m_pLowFilter; delete m_pMidFilter; delete m_pHighFilter; + delete m_pLowFilterKill; + delete m_pMidFilterKill; + delete m_pHighFilterKill; delete m_pPreGain; } @@ -256,6 +263,9 @@ void BaseTrackPlayer::slotFinishLoading(TrackPointer pTrackInfoObject) m_pLowFilter->set(1.0); m_pMidFilter->set(1.0); m_pHighFilter->set(1.0); + m_pLowFilterKill->set(0.0); + m_pMidFilterKill->set(0.0); + m_pHighFilterKill->set(0.0); m_pPreGain->set(1.0); } @@ -286,3 +296,13 @@ void BaseTrackPlayer::slotPlayToggled(double v) { EngineDeck* BaseTrackPlayer::getEngineDeck() const { return m_pChannel; } + +void BaseTrackPlayer::setupEqControlls() { + const QString group = getGroup(); + m_pLowFilter = new ControlObjectSlave(group,"filterLow"); + m_pMidFilter = new ControlObjectSlave(group,"filterMid"); + m_pHighFilter = new ControlObjectSlave(group,"filterHigh"); + m_pLowFilterKill = new ControlObjectSlave(group,"filterLowKill"); + m_pMidFilterKill = new ControlObjectSlave(group,"filterMidKill"); + m_pHighFilterKill = new ControlObjectSlave(group,"filterHighKill"); +} diff --git a/src/basetrackplayer.h b/src/basetrackplayer.h index 95bf5b7a445..5c2d08a9d0e 100644 --- a/src/basetrackplayer.h +++ b/src/basetrackplayer.h @@ -34,6 +34,8 @@ class BaseTrackPlayer : public BasePlayer { // connected. Delete me when EngineMaster supports AudioInput assigning. EngineDeck* getEngineDeck() const; + void setupEqControlls(); + public slots: void slotLoadTrack(TrackPointer track, bool bPlay=false); void slotFinishLoading(TrackPointer pTrackInfoObject); @@ -66,6 +68,9 @@ class BaseTrackPlayer : public BasePlayer { ControlObjectSlave* m_pLowFilter; ControlObjectSlave* m_pMidFilter; ControlObjectSlave* m_pHighFilter; + ControlObjectSlave* m_pLowFilterKill; + ControlObjectSlave* m_pMidFilterKill; + ControlObjectSlave* m_pHighFilterKill; ControlObjectSlave* m_pPreGain; EngineDeck* m_pChannel; diff --git a/src/configobject.cpp b/src/configobject.cpp index 7ccc26c9a36..45fb5e8459b 100644 --- a/src/configobject.cpp +++ b/src/configobject.cpp @@ -274,7 +274,6 @@ template bool ConfigObject::Parse() return true; } - template void ConfigObject::clear() { //Delete the pointers, because that's what we did before we @@ -398,7 +397,6 @@ QString ConfigObject::getResourcePath() { return qResourcePath; } - template ConfigObject::ConfigObject(QDomNode node) { if (!node.isNull() && node.isElement()) { diff --git a/src/configobject.h b/src/configobject.h index 0bbb55a06f8..55e3b90f41e 100644 --- a/src/configobject.h +++ b/src/configobject.h @@ -84,7 +84,6 @@ class ConfigValue { friend bool operator==(const ConfigValue& s1, const ConfigValue& s2); }; - class ConfigValueKbd : public ConfigValue { public: ConfigValueKbd(); diff --git a/src/controleffectknob.cpp b/src/controleffectknob.cpp index 194bb3aca2a..c45c989a7ce 100644 --- a/src/controleffectknob.cpp +++ b/src/controleffectknob.cpp @@ -9,7 +9,7 @@ ControlEffectKnob::ControlEffectKnob(ConfigKey key, double dMinValue, double dMa void ControlEffectKnob::setBehaviour(EffectManifestParameter::ControlHint type, double dMinValue, double dMaxValue) { - if ( m_pControl == NULL) { + if (m_pControl == NULL) { return; } diff --git a/src/dlgautodj.cpp b/src/dlgautodj.cpp index bdd46fdeb69..4a276d152c6 100644 --- a/src/dlgautodj.cpp +++ b/src/dlgautodj.cpp @@ -12,7 +12,7 @@ #include "widget/wwidget.h" #include "util/math.h" -#define CONFIG_KEY "[Auto DJ]" +#define kConfigKey "[Auto DJ]" const char* kTransitionPreferenceName = "Transition"; const int kTransitionPreferenceDefault = 10; @@ -123,7 +123,7 @@ DlgAutoDJ::DlgAutoDJ(QWidget* parent, ConfigObject* pConfig, m_pCOCrossfaderReverse = new ControlObjectSlave("[Mixer Profile]", "xFaderReverse"); QString str_autoDjTransition = m_pConfig->getValueString( - ConfigKey(CONFIG_KEY, kTransitionPreferenceName)); + ConfigKey(kConfigKey, kTransitionPreferenceName)); if (str_autoDjTransition.isEmpty()) { spinBoxTransition->setValue(kTransitionPreferenceDefault); } else { @@ -611,7 +611,7 @@ bool DlgAutoDJ::removePlayingTrackFromQueue(QString group) { m_pAutoDJTableModel->removeTrack(m_pAutoDJTableModel->index(0, 0)); // Re-queue if configured - if (m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "Requeue")).toInt()) { + if (m_pConfig->getValueString(ConfigKey(kConfigKey, "Requeue")).toInt()) { m_pAutoDJTableModel->appendTrack(loadedId); } return true; @@ -690,7 +690,7 @@ void DlgAutoDJ::transitionValueChanged(int value) { player2PlayChanged(1.0); } } - m_pConfig->set(ConfigKey(CONFIG_KEY, kTransitionPreferenceName), + m_pConfig->set(ConfigKey(kConfigKey, kTransitionPreferenceName), ConfigValue(value)); m_backUpTransition = value; } diff --git a/src/dlgprefcrossfader.cpp b/src/dlgprefcrossfader.cpp index 5feb78ccc86..224bcb5664d 100644 --- a/src/dlgprefcrossfader.cpp +++ b/src/dlgprefcrossfader.cpp @@ -22,7 +22,7 @@ #include "controlobject.h" #include "engine/enginexfader.h" -#define CONFIG_KEY "[Mixer Profile]" +#define kConfigKey "[Mixer Profile]" DlgPrefCrossfader::DlgPrefCrossfader(QWidget * parent, ConfigObject * _config) : DlgPreferencePage(parent), @@ -31,10 +31,10 @@ DlgPrefCrossfader::DlgPrefCrossfader(QWidget * parent, ConfigObject m_xFaderMode(MIXXX_XFADER_ADDITIVE), m_transform(0.0), m_cal(0.0), - m_COTMode(CONFIG_KEY, "xFaderMode"), - m_COTCurve(CONFIG_KEY, "xFaderCurve"), - m_COTCalibration(CONFIG_KEY, "xFaderCalibration"), - m_COTReverse(CONFIG_KEY, "xFaderReverse"), + m_COTMode(kConfigKey, "xFaderMode"), + m_COTCurve(kConfigKey, "xFaderCurve"), + m_COTCalibration(kConfigKey, "xFaderCalibration"), + m_COTReverse(kConfigKey, "xFaderReverse"), m_COTCrossfader("[Master]", "crossfader"), m_xFaderReverse(false) { setupUi(this); @@ -62,11 +62,11 @@ DlgPrefCrossfader::~DlgPrefCrossfader() { /** Loads the config keys and sets the widgets in the dialog to match */ void DlgPrefCrossfader::loadSettings() { m_transform = 1. + ((double) SliderXFader->value() / SliderXFader->maximum()); - double sliderTransform = config->getValueString(ConfigKey(CONFIG_KEY, "xFaderCurve")).toDouble(); + double sliderTransform = config->getValueString(ConfigKey(kConfigKey, "xFaderCurve")).toDouble(); double sliderVal = SliderXFader->maximum() / MIXXX_XFADER_STEEPNESS_COEFF * (sliderTransform - 1.); SliderXFader->setValue((int)sliderVal); - m_xFaderMode = config->getValueString(ConfigKey(CONFIG_KEY, "xFaderMode")).toInt(); + m_xFaderMode = config->getValueString(ConfigKey(kConfigKey, "xFaderMode")).toInt(); if (m_xFaderMode == MIXXX_XFADER_CONSTPWR) { radioButtonConstantPower->setChecked(true); @@ -76,7 +76,7 @@ void DlgPrefCrossfader::loadSettings() { //SliderXFader->setEnabled(false); } - m_xFaderReverse = config->getValueString(ConfigKey(CONFIG_KEY, "xFaderReverse")).toInt() == 1; + m_xFaderReverse = config->getValueString(ConfigKey(kConfigKey, "xFaderReverse")).toInt() == 1; checkBoxReverse->setChecked(m_xFaderReverse); slotUpdateXFader(); @@ -116,7 +116,7 @@ void DlgPrefCrossfader::slotUpdate() { } if (radioButtonConstantPower->isChecked()) { m_xFaderMode = MIXXX_XFADER_CONSTPWR; - double sliderTransform = config->getValueString(ConfigKey(CONFIG_KEY, "xFaderCurve")).toDouble(); + double sliderTransform = config->getValueString(ConfigKey(kConfigKey, "xFaderCurve")).toDouble(); double sliderVal = SliderXFader->maximum() / MIXXX_XFADER_STEEPNESS_COEFF * (sliderTransform - 1.); SliderXFader->setValue((int)sliderVal); } @@ -203,10 +203,10 @@ void DlgPrefCrossfader::slotUpdateXFader() { m_cal = EngineXfader::getCalibration(m_transform); QString QS_transform = QString::number(m_transform); - config->set(ConfigKey(CONFIG_KEY, "xFaderMode"), ConfigValue(m_xFaderMode)); - config->set(ConfigKey(CONFIG_KEY, "xFaderCurve"), ConfigValue(QS_transform)); + config->set(ConfigKey(kConfigKey, "xFaderMode"), ConfigValue(m_xFaderMode)); + config->set(ConfigKey(kConfigKey, "xFaderCurve"), ConfigValue(QS_transform)); //config->set(ConfigKey(CONFIG_KEY, "xFaderCalibration"), ConfigValue(m_cal)); //FIXME: m_cal is a double - be forewarned - config->set(ConfigKey(CONFIG_KEY, "xFaderReverse"), + config->set(ConfigKey(kConfigKey, "xFaderReverse"), ConfigValue(checkBoxReverse->isChecked() ? 1 : 0)); drawXfaderDisplay(); diff --git a/src/dlgprefeq.cpp b/src/dlgprefeq.cpp index 05ee3b5c309..ba3026ac6c5 100644 --- a/src/dlgprefeq.cpp +++ b/src/dlgprefeq.cpp @@ -17,28 +17,39 @@ #include #include +#include #include "dlgprefeq.h" #include "engine/enginefilterbessel4.h" #include "controlobject.h" +#include "controlobjectslave.h" #include "util/math.h" +#include "playermanager.h" -#define CONFIG_KEY "[Mixer Profile]" -#define ENABLE_INTERNAL_EQ "EnableEQs" +const char* kConfigKey = "[Mixer Profile]"; +const char* kEnableEqs = "EnableEQs"; +const char* kDefaultEqId = "org.mixxx.effects.bessel8lvmixeq"; const int kFrequencyUpperLimit = 20050; const int kFrequencyLowerLimit = 16; -DlgPrefEQ::DlgPrefEQ(QWidget* pParent, ConfigObject* pConfig) +DlgPrefEQ::DlgPrefEQ(QWidget* pParent, EffectsManager* pEffectsManager, + ConfigObject* pConfig) : DlgPreferencePage(pParent), - m_COTLoFreq(CONFIG_KEY, "LoEQFrequency"), - m_COTHiFreq(CONFIG_KEY, "HiEQFrequency"), - m_COTLoFi(CONFIG_KEY, "LoFiEQs"), - m_COTEnableEq(CONFIG_KEY, ENABLE_INTERNAL_EQ), + m_COLoFreq(kConfigKey, "LoEQFrequency"), + m_COHiFreq(kConfigKey, "HiEQFrequency"), m_pConfig(pConfig), m_lowEqFreq(0.0), m_highEqFreq(0.0), + m_pEffectsManager(pEffectsManager), + m_deckEffectSelectorsSetup(false), m_bEqAutoReset(false) { + + // Get the EQ Effect Rack + m_pEQEffectRack = m_pEffectsManager->getEQEffectRack().data(); + m_eqRackGroup = QString("[EffectRack%1_EffectUnit%2_Effect1]"). + arg(m_pEffectsManager->getEQEffectRackNumber() + 1); + setupUi(this); // Connection connect(SliderHiEQ, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateHiEQ())); @@ -49,10 +60,26 @@ DlgPrefEQ::DlgPrefEQ(QWidget* pParent, ConfigObject* pConfig) connect(SliderLoEQ, SIGNAL(sliderMoved(int)), this, SLOT(slotUpdateLoEQ())); connect(SliderLoEQ, SIGNAL(sliderReleased()), this, SLOT(slotUpdateLoEQ())); - connect(radioButton_bypass, SIGNAL(clicked()), this, SLOT(slotEqChanged())); - connect(radioButton_bessel4, SIGNAL(clicked()), this, SLOT(slotEqChanged())); - connect(radioButton_butterworth8, SIGNAL(clicked()), this, SLOT(slotEqChanged())); - connect(bEqAutoReset, SIGNAL(stateChanged(int)), this, SLOT(slotEqAutoReset(int))); + connect(bEqAutoReset, SIGNAL(stateChanged(int)), this, SLOT(slotUpdateEqAutoReset(int))); + connect(CheckBoxBypass, SIGNAL(stateChanged(int)), this, SLOT(slotBypass(int))); + + connect(CheckBoxHideEffects, SIGNAL(stateChanged(int)), + this, SLOT(slotPopulateDeckEffectSelectors())); + + connect(this, + SIGNAL(effectOnChainSlot(const unsigned int, const unsigned int, QString)), + m_pEQEffectRack, + SLOT(slotLoadEffectOnChainSlot(const unsigned int, const unsigned int, QString))); + + // Set to basic view if a previous configuration is missing + CheckBoxHideEffects->setChecked(m_pConfig->getValueString( + ConfigKey(kConfigKey, "AdvancedView"), QString("no")) == QString("no")); + + // Add drop down lists for current decks and connect num_decks control + // to slotAddComboBox + m_pNumDecks = new ControlObjectSlave("[Master]", "num_decks", this); + m_pNumDecks->connectValueChanged(SLOT(slotAddComboBox(double))); + slotAddComboBox(m_pNumDecks->get()); loadSettings(); slotUpdate(); @@ -60,14 +87,113 @@ DlgPrefEQ::DlgPrefEQ(QWidget* pParent, ConfigObject* pConfig) } DlgPrefEQ::~DlgPrefEQ() { + qDeleteAll(m_deckEffectSelectors); + m_deckEffectSelectors.clear(); + + qDeleteAll(m_fliterWaveformEnableCOs); + m_fliterWaveformEnableCOs.clear(); +} + +void DlgPrefEQ::slotAddComboBox(double numDecks) { + int oldDecks = m_deckEffectSelectors.size(); + while (m_deckEffectSelectors.size() < static_cast(numDecks)) { + QHBoxLayout* innerHLayout = new QHBoxLayout(); + QLabel* label = new QLabel(QObject::tr("Deck %1"). + arg(m_deckEffectSelectors.size() + 1), this); + + QString group = PlayerManager::groupForDeck( + m_deckEffectSelectors.size()); + + m_fliterWaveformEnableCOs.append( + new ControlObject(ConfigKey(group, "fliterWaveformEnable"))); + + // Create the drop down list and populate it with the available effects + QComboBox* box = new QComboBox(this); + m_deckEffectSelectors.append(box); + connect(box, SIGNAL(currentIndexChanged(int)), + this, SLOT(slotEffectChangedOnDeck(int))); + + // Setup the GUI + innerHLayout->addWidget(label); + innerHLayout->addWidget(box); + innerHLayout->addStretch(); + verticalLayout_2->addLayout(innerHLayout); + } + slotPopulateDeckEffectSelectors(); + for (int i = oldDecks; i < static_cast(numDecks); ++i) { + // Set the configured effect for box and simpleBox or Bessel8 LV-Mix EQ + // if none is configured + QString configuredEffect; + int selectedEffectIndex; + QString group = PlayerManager::groupForDeck(i); + configuredEffect = m_pConfig->getValueString(ConfigKey(kConfigKey, + "EffectForGroup_" + group), kDefaultEqId); + selectedEffectIndex = m_deckEffectSelectors[i]->findData(configuredEffect); + if (selectedEffectIndex < 0) { + selectedEffectIndex = m_deckEffectSelectors[i]->findData(kDefaultEqId); + configuredEffect = kDefaultEqId; + } + m_deckEffectSelectors[i]->setCurrentIndex(selectedEffectIndex); + m_fliterWaveformEnableCOs[i]->set(m_pEffectsManager->isEQ(configuredEffect)); + } +} + +static bool isEQ(EffectManifest* pManifest) { + return pManifest->isEQ(); +} + +void DlgPrefEQ::slotPopulateDeckEffectSelectors() { + m_deckEffectSelectorsSetup = true; // prevents a recursive call + QList > availableEQEffectNames; + EffectsManager::EffectManifestFilterFnc filter; + if (CheckBoxHideEffects->isChecked()) { + m_pConfig->set(ConfigKey(kConfigKey, "AdvancedView"), QString("no")); + filter = isEQ; + } else { + m_pConfig->set(ConfigKey(kConfigKey, "AdvancedView"), QString("yes")); + filter = NULL; // take all; + } + availableEQEffectNames = + m_pEffectsManager->getEffectNamesFiltered(filter); + + foreach (QComboBox* box, m_deckEffectSelectors) { + // Populate comboboxes with all available effects + // Save current selection + QString selectedEffectId = box->itemData(box->currentIndex()).toString(); + QString selectedEffectName = box->itemText(box->currentIndex()); + box->clear(); + int currentIndex = -1;// Nothing selected + + int i; + for (i = 0; i < availableEQEffectNames.size(); ++i) { + box->addItem(availableEQEffectNames[i].second); + box->setItemData(i, QVariant(availableEQEffectNames[i].first)); + if (selectedEffectId == availableEQEffectNames[i].first) { + currentIndex = i; + } + } + if (currentIndex < 0 && !selectedEffectName.isEmpty()) { + // current selection is not part of the new list + // So we need to add it + box->addItem(selectedEffectName); + box->setItemData(i, QVariant(selectedEffectId)); + currentIndex = i; + } + box->setCurrentIndex(currentIndex); + } + m_deckEffectSelectorsSetup = false; } void DlgPrefEQ::loadSettings() { - QString highEqCourse = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "HiEQFrequency")); - QString highEqPrecise = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "HiEQFrequencyPrecise")); - QString lowEqCourse = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "LoEQFrequency")); - QString lowEqPrecise = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "LoEQFrequencyPrecise")); - m_bEqAutoReset = static_cast(m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "EqAutoReset")).toInt()); + QString highEqCourse = m_pConfig->getValueString(ConfigKey(kConfigKey, "HiEQFrequency")); + QString highEqPrecise = m_pConfig->getValueString(ConfigKey(kConfigKey, "HiEQFrequencyPrecise")); + QString lowEqCourse = m_pConfig->getValueString(ConfigKey(kConfigKey, "LoEQFrequency")); + QString lowEqPrecise = m_pConfig->getValueString(ConfigKey(kConfigKey, "LoEQFrequencyPrecise")); + m_bEqAutoReset = static_cast(m_pConfig->getValueString( + ConfigKey(kConfigKey, "EqAutoReset")).toInt()); + bEqAutoReset->setChecked(m_bEqAutoReset); + CheckBoxBypass->setChecked(m_pConfig->getValueString( + ConfigKey(kConfigKey, kEnableEqs), QString("yes")) == QString("no")); double lowEqFreq = 0.0; double highEqFreq = 0.0; @@ -80,8 +206,8 @@ void DlgPrefEQ::loadSettings() { if (lowEqFreq == 0.0 || highEqFreq == 0.0 || lowEqFreq == highEqFreq) { setDefaultShelves(); - lowEqFreq = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "LoEQFrequencyPrecise")).toDouble(); - highEqFreq = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "HiEQFrequencyPrecise")).toDouble(); + lowEqFreq = m_pConfig->getValueString(ConfigKey(kConfigKey, "LoEQFrequencyPrecise")).toDouble(); + highEqFreq = m_pConfig->getValueString(ConfigKey(kConfigKey, "HiEQFrequencyPrecise")).toDouble(); } SliderHiEQ->setValue( @@ -94,59 +220,54 @@ void DlgPrefEQ::loadSettings() { SliderLoEQ->maximum())); if (m_pConfig->getValueString( - ConfigKey(CONFIG_KEY, ENABLE_INTERNAL_EQ), "yes") == QString("yes")) { - radioButton_bypass->setChecked(false); - if (m_pConfig->getValueString( - ConfigKey(CONFIG_KEY, "LoFiEQs")) == QString("yes")) { - radioButton_bessel4->setChecked(true); - radioButton_butterworth8->setChecked(false); - } else { - radioButton_bessel4->setChecked(false); - radioButton_butterworth8->setChecked(true); - } - } else { - radioButton_bypass->setChecked(true); - radioButton_bessel4->setChecked(false); - radioButton_butterworth8->setChecked(false); + ConfigKey(kConfigKey, kEnableEqs), "yes") == QString("yes")) { + CheckBoxBypass->setChecked(false); } } void DlgPrefEQ::setDefaultShelves() { - m_pConfig->set(ConfigKey(CONFIG_KEY, "HiEQFrequency"), ConfigValue(2500)); - m_pConfig->set(ConfigKey(CONFIG_KEY, "LoEQFrequency"), ConfigValue(250)); - m_pConfig->set(ConfigKey(CONFIG_KEY, "HiEQFrequencyPrecise"), ConfigValue(2500.0)); - m_pConfig->set(ConfigKey(CONFIG_KEY, "LoEQFrequencyPrecise"), ConfigValue(250.0)); + m_pConfig->set(ConfigKey(kConfigKey, "HiEQFrequency"), ConfigValue(2500)); + m_pConfig->set(ConfigKey(kConfigKey, "LoEQFrequency"), ConfigValue(250)); + m_pConfig->set(ConfigKey(kConfigKey, "HiEQFrequencyPrecise"), ConfigValue(2500.0)); + m_pConfig->set(ConfigKey(kConfigKey, "LoEQFrequencyPrecise"), ConfigValue(250.0)); } void DlgPrefEQ::slotResetToDefaults() { - radioButton_bypass->setChecked(false); - radioButton_butterworth8->setChecked(false); - radioButton_bessel4->setChecked(true); - m_bEqAutoReset = false; - slotEqChanged(); setDefaultShelves(); + foreach(QComboBox* pCombo, m_deckEffectSelectors) { + pCombo->setCurrentIndex( + pCombo->findData(kDefaultEqId)); + } loadSettings(); + CheckBoxBypass->setChecked(Qt::Unchecked); + CheckBoxHideEffects->setChecked(Qt::Checked); + m_bEqAutoReset = false; + bEqAutoReset->setChecked(Qt::Unchecked); slotUpdate(); slotApply(); } -void DlgPrefEQ::slotEqChanged() { - if (radioButton_bypass->isChecked()) { - m_pConfig->set(ConfigKey(CONFIG_KEY, ENABLE_INTERNAL_EQ), QString("no")); - } else { - m_pConfig->set(ConfigKey(CONFIG_KEY, ENABLE_INTERNAL_EQ), QString("yes")); - } +void DlgPrefEQ::slotEffectChangedOnDeck(int effectIndex) { + QComboBox* c = qobject_cast(sender()); + // Check if qobject_cast was successful + if (c && !m_deckEffectSelectorsSetup) { + int deckNumber = m_deckEffectSelectors.indexOf(c); + QString effectId = c->itemData(effectIndex).toString(); + emit(effectOnChainSlot(deckNumber, 0, effectId)); - if (radioButton_bessel4->isChecked()) { - m_pConfig->set(ConfigKey(CONFIG_KEY, "LoFiEQs"), ConfigValue(QString("yes"))); - } + QString group = PlayerManager::groupForDeck(deckNumber); - if (radioButton_butterworth8->isChecked()) { - m_pConfig->set(ConfigKey(CONFIG_KEY, "LoFiEQs"), ConfigValue(QString("no"))); - } + // Update the configured effect for the current QComboBox + m_pConfig->set(ConfigKey(kConfigKey, "EffectForGroup_" + group), + ConfigValue(effectId)); - slotApply(); + m_fliterWaveformEnableCOs[deckNumber]->set(m_pEffectsManager->isEQ(effectId)); + + // This is required to remove a previous selected effect that does not + // fit to the current ShowAllEffects checkbox + slotPopulateDeckEffectSelectors(); + } } void DlgPrefEQ::slotUpdateHiEQ() @@ -164,9 +285,9 @@ void DlgPrefEQ::slotUpdateHiEQ() } else { TextHiEQ->setText( QString("%1 kHz").arg((int)m_highEqFreq / 1000.)); } - m_pConfig->set(ConfigKey(CONFIG_KEY, "HiEQFrequency"), + m_pConfig->set(ConfigKey(kConfigKey, "HiEQFrequency"), ConfigValue(QString::number(static_cast(m_highEqFreq)))); - m_pConfig->set(ConfigKey(CONFIG_KEY, "HiEQFrequencyPrecise"), + m_pConfig->set(ConfigKey(kConfigKey, "HiEQFrequencyPrecise"), ConfigValue(QString::number(m_highEqFreq, 'f'))); slotApply(); @@ -187,9 +308,9 @@ void DlgPrefEQ::slotUpdateLoEQ() } else { TextLoEQ->setText(QString("%1 kHz").arg((int)m_lowEqFreq / 1000.)); } - m_pConfig->set(ConfigKey(CONFIG_KEY, "LoEQFrequency"), + m_pConfig->set(ConfigKey(kConfigKey, "LoEQFrequency"), ConfigValue(QString::number(static_cast(m_lowEqFreq)))); - m_pConfig->set(ConfigKey(CONFIG_KEY, "LoEQFrequencyPrecise"), + m_pConfig->set(ConfigKey(kConfigKey, "LoEQFrequencyPrecise"), ConfigValue(QString::number(m_lowEqFreq, 'f'))); slotApply(); @@ -208,27 +329,51 @@ int DlgPrefEQ::getSliderPosition(double eqFreq, int minValue, int maxValue) } void DlgPrefEQ::slotApply() { - m_COTLoFreq.slotSet(m_lowEqFreq); - m_COTHiFreq.slotSet(m_highEqFreq); - - m_pConfig->set(ConfigKey(CONFIG_KEY,"EqAutoReset"), + m_COLoFreq.set(m_lowEqFreq); + m_COHiFreq.set(m_highEqFreq); + m_pConfig->set(ConfigKey(kConfigKey,"EqAutoReset"), ConfigValue(m_bEqAutoReset ? 1 : 0)); - m_COTLoFi.slotSet((m_pConfig->getValueString( - ConfigKey(CONFIG_KEY, "LoFiEQs")) == QString("yes"))); - m_COTEnableEq.slotSet((m_pConfig->getValueString( - ConfigKey(CONFIG_KEY, ENABLE_INTERNAL_EQ), "yes") == QString("yes"))); } +// supposed to set the widgets to match internal state void DlgPrefEQ::slotUpdate() { slotUpdateLoEQ(); slotUpdateHiEQ(); - slotEqChanged(); + slotPopulateDeckEffectSelectors(); bEqAutoReset->setChecked(m_bEqAutoReset); } -void DlgPrefEQ::slotEqAutoReset(int i) { +void DlgPrefEQ::slotUpdateEqAutoReset(int i) { m_bEqAutoReset = static_cast(i); - slotUpdate(); +} + +void DlgPrefEQ::slotBypass(int state) { + if (state) { + m_pConfig->set(ConfigKey(kConfigKey, kEnableEqs), QString("no")); + // Disable effect processing for all decks by setting the appropriate + // controls to 0 ("[EffectRackX_EffectUnitDeck_Effect1],enable") + int deck = 1; + foreach(QComboBox* box, m_deckEffectSelectors) { + ControlObject::set(ConfigKey(m_eqRackGroup.arg(deck), "enabled"), 0); + m_fliterWaveformEnableCOs[deck - 1]->set(0); + deck++; + box->setEnabled(false); + } + } else { + m_pConfig->set(ConfigKey(kConfigKey, kEnableEqs), QString("yes")); + // Enable effect processing for all decks by setting the appropriate + // controls to 1 ("[EffectRackX_EffectUnitDeck_Effect1],enable") + int deck = 1; + ControlObjectSlave enableControl; + foreach(QComboBox* box, m_deckEffectSelectors) { + ControlObject::set(ConfigKey(m_eqRackGroup.arg(deck), "enabled"), 1); + m_fliterWaveformEnableCOs[deck - 1]->set(1); + deck++; + box->setEnabled(true); + } + } + + slotApply(); } double DlgPrefEQ::getEqFreq(int sliderVal, int minValue, int maxValue) { @@ -240,7 +385,7 @@ double DlgPrefEQ::getEqFreq(int sliderVal, int minValue, int maxValue) { (maxValue - minValue); // Use a non-linear mapping between slider and frequency. normValue = normValue * normValue * normValue * normValue; - double result = normValue * (kFrequencyUpperLimit-kFrequencyLowerLimit) + + double result = normValue * (kFrequencyUpperLimit - kFrequencyLowerLimit) + kFrequencyLowerLimit; return result; } diff --git a/src/dlgprefeq.h b/src/dlgprefeq.h index c977245c001..ba4a064292c 100644 --- a/src/dlgprefeq.h +++ b/src/dlgprefeq.h @@ -19,12 +19,13 @@ #define DLGPREFEQ_H #include +#include #include "ui_dlgprefeqdlg.h" #include "configobject.h" -#include "engine/enginefilterblock.h" -#include "controlobjectthread.h" +#include "controlobjectslave.h" #include "preferences/dlgpreferencepage.h" +#include "effects/effectsmanager.h" /** *@author John Sully @@ -32,23 +33,29 @@ class DlgPrefEQ : public DlgPreferencePage, public Ui::DlgPrefEQDlg { Q_OBJECT public: - DlgPrefEQ(QWidget *parent, ConfigObject* _config); + DlgPrefEQ(QWidget *parent, EffectsManager* pEffectsManager, + ConfigObject* _config); virtual ~DlgPrefEQ(); public slots: - void slotEqChanged(); - /** Update Hi EQ **/ + void slotEffectChangedOnDeck(int effectIndex); + void slotAddComboBox(double numDecks); + // Slot for toggling between advanced and basic views + void slotPopulateDeckEffectSelectors(); + // Update Hi EQ void slotUpdateHiEQ(); - /** Update Lo EQ **/ + // Update Lo EQ void slotUpdateLoEQ(); - /** Apply changes to widget */ + // Apply changes to widget void slotApply(); void slotUpdate(); void slotResetToDefaults(); - void slotEqAutoReset(int); + void slotUpdateEqAutoReset(int); + void slotBypass(int state); signals: void apply(const QString &); + void effectOnChainSlot(const unsigned int, const unsigned int, QString); private: void loadSettings(); @@ -57,12 +64,21 @@ class DlgPrefEQ : public DlgPreferencePage, public Ui::DlgPrefEQDlg { int getSliderPosition(double eqFreq, int minimum, int maximum); void validate_levels(); - ControlObjectThread m_COTLoFreq; - ControlObjectThread m_COTHiFreq; - ControlObjectThread m_COTLoFi; - ControlObjectThread m_COTEnableEq; + ControlObjectSlave m_COLoFreq; + ControlObjectSlave m_COHiFreq; ConfigObject* m_pConfig; double m_lowEqFreq, m_highEqFreq; + + // Members needed for changing the effects loaded on the EQ Effect Rack + EffectsManager* m_pEffectsManager; + EffectRack* m_pEQEffectRack; + QList m_deckEffectSelectors; + QList m_fliterWaveformEnableCOs; + ControlObjectSlave* m_pNumDecks; + QString m_eqRackGroup; + + bool m_deckEffectSelectorsSetup; + bool m_bEqAutoReset; }; diff --git a/src/dlgprefeqdlg.ui b/src/dlgprefeqdlg.ui index 08f18c64883..245395080da 100644 --- a/src/dlgprefeqdlg.ui +++ b/src/dlgprefeqdlg.ui @@ -7,7 +7,7 @@ 0 0 529 - 434 + 436 @@ -17,54 +17,45 @@ - - - Bypass - + - Disable Mixxx`s internal equalizers if you prefer to use equalizers on connected hardware mixers, and to lower CPU utilization. + Resets the equalizers to their default values when loading a track. + + + Reset equalizers on track load - - buttonGroup - - + - Bessel 4th order - - - Use this option if you prefer lower CPU utilization. + Bypass - - buttonGroup - - + - Butterworth 8th order + Fill menus with the best suited effects only - - Use this option if you prefer steep roll-off. + + true - - buttonGroup - - - - Reset equalizers on track load + + + + 75 + true + - - Resets the equalizers to their default values when loading a track. + + Effect Rack Configuration - + @@ -339,7 +330,4 @@ - - - diff --git a/src/dlgpreferences.cpp b/src/dlgpreferences.cpp index 8d28d9baf16..e01fa3d9c94 100644 --- a/src/dlgpreferences.cpp +++ b/src/dlgpreferences.cpp @@ -58,6 +58,7 @@ DlgPreferences::DlgPreferences(MixxxMainWindow * mixxx, SkinLoader* pSkinLoader, SoundManager * soundman, PlayerManager* pPlayerManager, ControllerManager * controllers, VinylControlManager *pVCManager, + EffectsManager* pEffectsManager, ConfigObject* pConfig, Library *pLibrary) : m_pConfig(pConfig), m_pageSizeHint(QSize(0, 0)), @@ -100,7 +101,7 @@ DlgPreferences::DlgPreferences(MixxxMainWindow * mixxx, SkinLoader* pSkinLoader, addPageWidget(m_wwaveform); m_wautodj = new DlgPrefAutoDJ(this, m_pConfig); addPageWidget(m_wautodj); - m_weq = new DlgPrefEQ(this, m_pConfig); + m_weq = new DlgPrefEQ(this, pEffectsManager, m_pConfig); addPageWidget(m_weq); m_wcrossfader = new DlgPrefCrossfader(this, m_pConfig); addPageWidget(m_wcrossfader); diff --git a/src/dlgpreferences.h b/src/dlgpreferences.h index 9c06c333fdc..b164ad8f5f5 100644 --- a/src/dlgpreferences.h +++ b/src/dlgpreferences.h @@ -47,6 +47,7 @@ class DlgPrefNoVinyl; class DlgPrefShoutcast; class DlgPrefReplayGain; class ControllerManager; +class EffectsManager; class SkinLoader; class PlayerManager; class Library; @@ -60,8 +61,8 @@ class DlgPreferences : public QDialog, public Ui::DlgPreferencesDlg { public: DlgPreferences(MixxxMainWindow* mixxx, SkinLoader* pSkinLoader, SoundManager* soundman, PlayerManager* pPlayerManager, ControllerManager* controllers, - VinylControlManager* pVCManager, ConfigObject* pConfig, - Library *pLibrary); + VinylControlManager* pVCManager, EffectsManager* pEffectsManager, + ConfigObject* pConfig, Library *pLibrary); virtual ~DlgPreferences(); void addPageWidget(DlgPreferencePage* pWidget); diff --git a/src/dlgprefmodplug.cpp b/src/dlgprefmodplug.cpp index 20b24d5a23a..d4c5ddc114e 100644 --- a/src/dlgprefmodplug.cpp +++ b/src/dlgprefmodplug.cpp @@ -7,7 +7,7 @@ #include "configobject.h" #include "soundsourcemodplug.h" -#define CONFIG_KEY "[Modplug]" +#define kConfigKey "[Modplug]" DlgPrefModplug::DlgPrefModplug(QWidget *parent, ConfigObject *_config) @@ -51,67 +51,67 @@ void DlgPrefModplug::slotResetToDefaults() { void DlgPrefModplug::loadSettings() { m_pUi->memoryLimit->setValue(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"PerTrackMemoryLimitMB"),"256").toInt()); + ConfigKey(kConfigKey,"PerTrackMemoryLimitMB"),"256").toInt()); m_pUi->oversampling->setChecked(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"OversamplingEnabled"),"1") == QString("1")); + ConfigKey(kConfigKey,"OversamplingEnabled"),"1") == QString("1")); m_pUi->noiseReduction->setChecked(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"NoiseReductionEnabled"),"0") == QString("1")); + ConfigKey(kConfigKey,"NoiseReductionEnabled"),"0") == QString("1")); m_pUi->stereoSeparation->setValue(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"StereoSeparation"),"1").toInt()); + ConfigKey(kConfigKey,"StereoSeparation"),"1").toInt()); m_pUi->maxMixChannels->setValue(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"MaxMixChannels"),"128").toInt()); + ConfigKey(kConfigKey,"MaxMixChannels"),"128").toInt()); m_pUi->resampleMode->setCurrentIndex(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"ResamplingMode"),"1").toInt()); + ConfigKey(kConfigKey,"ResamplingMode"),"1").toInt()); m_pUi->reverb->setChecked(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"ReverbEnabled"),"0") == QString("1")); + ConfigKey(kConfigKey,"ReverbEnabled"),"0") == QString("1")); m_pUi->reverbDepth->setValue(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"ReverbLevel"),"50").toInt()); + ConfigKey(kConfigKey,"ReverbLevel"),"50").toInt()); m_pUi->reverbDelay->setValue(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"ReverbDelay"),"50").toInt()); + ConfigKey(kConfigKey,"ReverbDelay"),"50").toInt()); m_pUi->megabass->setChecked(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"MegabassEnabled"),"0") == QString("1")); + ConfigKey(kConfigKey,"MegabassEnabled"),"0") == QString("1")); m_pUi->bassDepth->setValue(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"MegabassLevel"),"50").toInt()); + ConfigKey(kConfigKey,"MegabassLevel"),"50").toInt()); m_pUi->bassCutoff->setValue(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"MegabassCutoff"),"50").toInt()); + ConfigKey(kConfigKey,"MegabassCutoff"),"50").toInt()); m_pUi->surround->setChecked(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"SurroundEnabled"),"0") == QString("1")); + ConfigKey(kConfigKey,"SurroundEnabled"),"0") == QString("1")); m_pUi->surroundDepth->setValue(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"SurroundLevel"),"50").toInt()); + ConfigKey(kConfigKey,"SurroundLevel"),"50").toInt()); m_pUi->surroundDelay->setValue(m_pConfig->getValueString( - ConfigKey(CONFIG_KEY,"SurroundDelay"),"50").toInt()); + ConfigKey(kConfigKey,"SurroundDelay"),"50").toInt()); } void DlgPrefModplug::saveSettings() { - m_pConfig->set(ConfigKey(CONFIG_KEY,"PerTrackMemoryLimitMB"), + m_pConfig->set(ConfigKey(kConfigKey,"PerTrackMemoryLimitMB"), ConfigValue(m_pUi->memoryLimit->value())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"OversamplingEnabled"), + m_pConfig->set(ConfigKey(kConfigKey,"OversamplingEnabled"), ConfigValue(m_pUi->oversampling->isChecked())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"NoiseReductionEnabled"), + m_pConfig->set(ConfigKey(kConfigKey,"NoiseReductionEnabled"), ConfigValue(m_pUi->noiseReduction->isChecked())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"StereoSeparation"), + m_pConfig->set(ConfigKey(kConfigKey,"StereoSeparation"), ConfigValue(m_pUi->stereoSeparation->value())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"MaxMixChannels"), + m_pConfig->set(ConfigKey(kConfigKey,"MaxMixChannels"), ConfigValue(m_pUi->maxMixChannels->value())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"ResamplingMode"), + m_pConfig->set(ConfigKey(kConfigKey,"ResamplingMode"), ConfigValue(m_pUi->resampleMode->currentIndex())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"ReverbEnabled"), + m_pConfig->set(ConfigKey(kConfigKey,"ReverbEnabled"), ConfigValue(m_pUi->reverb->isChecked())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"ReverbLevel"), + m_pConfig->set(ConfigKey(kConfigKey,"ReverbLevel"), ConfigValue(m_pUi->reverbDepth->value())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"ReverbDelay"), + m_pConfig->set(ConfigKey(kConfigKey,"ReverbDelay"), ConfigValue(m_pUi->reverbDelay->value())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"MegabassEnabled"), + m_pConfig->set(ConfigKey(kConfigKey,"MegabassEnabled"), ConfigValue(m_pUi->megabass->isChecked())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"MegabassLevel"), + m_pConfig->set(ConfigKey(kConfigKey,"MegabassLevel"), ConfigValue(m_pUi->bassDepth->value())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"MegabassCutoff"), + m_pConfig->set(ConfigKey(kConfigKey,"MegabassCutoff"), ConfigValue(m_pUi->bassCutoff->value())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"SurroundEnabled"), + m_pConfig->set(ConfigKey(kConfigKey,"SurroundEnabled"), ConfigValue(m_pUi->surround->isChecked())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"SurroundLevel"), + m_pConfig->set(ConfigKey(kConfigKey,"SurroundLevel"), ConfigValue(m_pUi->surroundDepth->value())); - m_pConfig->set(ConfigKey(CONFIG_KEY,"SurroundDelay"), + m_pConfig->set(ConfigKey(kConfigKey,"SurroundDelay"), ConfigValue(m_pUi->surroundDelay->value())); } diff --git a/src/dlgprefreplaygain.cpp b/src/dlgprefreplaygain.cpp index 11daa5dd9d3..2cf81cef252 100644 --- a/src/dlgprefreplaygain.cpp +++ b/src/dlgprefreplaygain.cpp @@ -3,14 +3,14 @@ #include "controlobject.h" #include "util/math.h" -#define CONFIG_KEY "[ReplayGain]" +#define kConfigKey "[ReplayGain]" DlgPrefReplayGain::DlgPrefReplayGain(QWidget * parent, ConfigObject * _config) : DlgPreferencePage(parent), config(_config), - m_COTReplayGainBoost(CONFIG_KEY, "ReplayGainBoost"), - m_COTEnabled(CONFIG_KEY, "ReplayGainEnabled") { + m_COTReplayGainBoost(kConfigKey, "ReplayGainBoost"), + m_COTEnabled(kConfigKey, "ReplayGainEnabled") { setupUi(this); //Connections @@ -26,20 +26,20 @@ DlgPrefReplayGain::~DlgPrefReplayGain() { } void DlgPrefReplayGain::loadSettings() { - if(config->getValueString(ConfigKey(CONFIG_KEY,"ReplayGainEnabled"))==QString("")) { + if(config->getValueString(ConfigKey(kConfigKey,"ReplayGainEnabled"))==QString("")) { slotResetToDefaults(); } else { int iReplayGainBoost = - config->getValueString(ConfigKey(CONFIG_KEY, "InitialReplayGainBoost")).toInt(); + config->getValueString(ConfigKey(kConfigKey, "InitialReplayGainBoost")).toInt(); SliderBoost->setValue(iReplayGainBoost); lcddB->display(iReplayGainBoost); bool gainEnabled = - config->getValueString(ConfigKey(CONFIG_KEY, "ReplayGainEnabled")).toInt() == 1; + config->getValueString(ConfigKey(kConfigKey, "ReplayGainEnabled")).toInt() == 1; EnableGain->setChecked(gainEnabled); bool analyserEnabled = - config->getValueString(ConfigKey(CONFIG_KEY, "ReplayGainAnalyserEnabled")).toInt(); + config->getValueString(ConfigKey(kConfigKey, "ReplayGainAnalyserEnabled")).toInt(); EnableAnalyser->setChecked(analyserEnabled); } slotUpdate(); @@ -59,10 +59,10 @@ void DlgPrefReplayGain::slotResetToDefaults() { void DlgPrefReplayGain::slotSetRGEnabled() { if (EnableGain->isChecked()) { - config->set(ConfigKey(CONFIG_KEY,"ReplayGainEnabled"), ConfigValue(1)); + config->set(ConfigKey(kConfigKey,"ReplayGainEnabled"), ConfigValue(1)); } else { - config->set(ConfigKey(CONFIG_KEY,"ReplayGainEnabled"), ConfigValue(0)); - config->set(ConfigKey(CONFIG_KEY,"ReplayGainAnalyserEnabled"), + config->set(ConfigKey(kConfigKey,"ReplayGainEnabled"), ConfigValue(0)); + config->set(ConfigKey(kConfigKey,"ReplayGainAnalyserEnabled"), ConfigValue(0)); } @@ -72,20 +72,20 @@ void DlgPrefReplayGain::slotSetRGEnabled() { void DlgPrefReplayGain::slotSetRGAnalyserEnabled() { int enabled = EnableAnalyser->isChecked() ? 1 : 0; - config->set(ConfigKey(CONFIG_KEY,"ReplayGainAnalyserEnabled"), + config->set(ConfigKey(kConfigKey,"ReplayGainAnalyserEnabled"), ConfigValue(enabled)); slotApply(); } void DlgPrefReplayGain::slotUpdateBoost() { - config->set(ConfigKey(CONFIG_KEY, "InitialReplayGainBoost"), + config->set(ConfigKey(kConfigKey, "InitialReplayGainBoost"), ConfigValue(SliderBoost->value())); slotApply(); } void DlgPrefReplayGain::slotUpdate() { if (config->getValueString( - ConfigKey(CONFIG_KEY,"ReplayGainEnabled")).toInt()==1) { + ConfigKey(kConfigKey,"ReplayGainEnabled")).toInt()==1) { EnableAnalyser->setEnabled(true); SliderBoost->setEnabled(true); } else { diff --git a/src/effects/effectbuttonparameterslot.h b/src/effects/effectbuttonparameterslot.h index 255df560ca7..560d4e90421 100644 --- a/src/effects/effectbuttonparameterslot.h +++ b/src/effects/effectbuttonparameterslot.h @@ -9,7 +9,6 @@ #include "controlobject.h" #include "effects/effect.h" #include "effects/effectparameterslotbase.h" - class ControlObject; class ControlPushButton; diff --git a/src/effects/effectchainmanager.cpp b/src/effects/effectchainmanager.cpp index 5180c6f76dc..ddf7d80f771 100644 --- a/src/effects/effectchainmanager.cpp +++ b/src/effects/effectchainmanager.cpp @@ -46,6 +46,10 @@ EffectRackPointer EffectChainManager::getEffectRack(int i) { return m_effectRacks[i]; } +int EffectChainManager::getEffectRacksSize() { + return m_effectRacks.size(); +} + void EffectChainManager::addEffectChain(EffectChainPointer pEffectChain) { if (pEffectChain) { m_effectChains.append(pEffectChain); diff --git a/src/effects/effectchainmanager.h b/src/effects/effectchainmanager.h index bfbe1b73f30..2e984868b63 100644 --- a/src/effects/effectchainmanager.h +++ b/src/effects/effectchainmanager.h @@ -28,6 +28,7 @@ class EffectChainManager : public QObject { EffectRackPointer addEffectRack(); EffectRackPointer getEffectRack(int i); + int getEffectRacksSize(); void addEffectChain(EffectChainPointer pEffectChain); void removeEffectChain(EffectChainPointer pEffectChain); diff --git a/src/effects/effectchainslot.cpp b/src/effects/effectchainslot.cpp index b5d94b68589..065a27e6202 100644 --- a/src/effects/effectchainslot.cpp +++ b/src/effects/effectchainslot.cpp @@ -9,7 +9,7 @@ EffectChainSlot::EffectChainSlot(EffectRack* pRack, unsigned int iRackNumber, unsigned int iChainNumber) : m_iRackNumber(iRackNumber), - m_iChainNumber(iChainNumber), + m_iChainSlotNumber(iChainNumber), // The control group names are 1-indexed while internally everything // is 0-indexed. m_group(formatGroupString(iRackNumber, iChainNumber)), @@ -166,7 +166,7 @@ void EffectChainSlot::loadEffectChain(EffectChainPointer pEffectChain) { if (pEffectChain) { m_pEffectChain = pEffectChain; m_pEffectChain->addToEngine(m_pEffectRack->getEngineEffectRack(), - m_iChainNumber); + m_iChainSlotNumber); m_pEffectChain->updateEngineState(); connect(m_pEffectChain.data(), SIGNAL(effectsChanged()), @@ -215,7 +215,7 @@ void EffectChainSlot::clear() { // Stop listening to signals from any loaded effect if (m_pEffectChain) { m_pEffectChain->removeFromEngine(m_pEffectRack->getEngineEffectRack(), - m_iChainNumber); + m_iChainSlotNumber); foreach (EffectSlotPointer pSlot, m_slots) { pSlot->clear(); } @@ -236,7 +236,7 @@ unsigned int EffectChainSlot::numSlots() const { EffectSlotPointer EffectChainSlot::addEffectSlot() { //qDebug() << debugString() << "addEffectSlot"; - EffectSlot* pEffectSlot = new EffectSlot(m_iRackNumber, m_iChainNumber, + EffectSlot* pEffectSlot = new EffectSlot(m_iRackNumber, m_iChainSlotNumber, m_slots.size()); // Rebroadcast effectLoaded signals connect(pEffectSlot, SIGNAL(effectLoaded(EffectPointer, unsigned int)), @@ -272,7 +272,7 @@ void EffectChainSlot::registerGroup(const QString& group) { void EffectChainSlot::slotEffectLoaded(EffectPointer pEffect, unsigned int slotNumber) { // const int is a safe read... don't bother locking - emit(effectLoaded(pEffect, m_iChainNumber, slotNumber)); + emit(effectLoaded(pEffect, m_iChainSlotNumber, slotNumber)); } void EffectChainSlot::slotClearEffect(unsigned int iEffectSlotNumber) { @@ -365,9 +365,9 @@ void EffectChainSlot::slotControlChainInsertionType(double v) { void EffectChainSlot::slotControlChainSelector(double v) { //qDebug() << debugString() << "slotControlChainSelector" << v; if (v > 0) { - emit(nextChain(m_iChainNumber, m_pEffectChain)); + emit(nextChain(m_iChainSlotNumber, m_pEffectChain)); } else if (v < 0) { - emit(prevChain(m_iChainNumber, m_pEffectChain)); + emit(prevChain(m_iChainSlotNumber, m_pEffectChain)); } } @@ -398,3 +398,7 @@ void EffectChainSlot::slotGroupStatusChanged(const QString& group) { } } } + +unsigned int EffectChainSlot::getChainSlotNumber() const { + return m_iChainSlotNumber; +} diff --git a/src/effects/effectchainslot.h b/src/effects/effectchainslot.h index dd178891128..2c252ec19b5 100644 --- a/src/effects/effectchainslot.h +++ b/src/effects/effectchainslot.h @@ -46,6 +46,8 @@ class EffectChainSlot : public QObject { // Unload the loaded EffectChain. void clear(); + unsigned int getChainSlotNumber() const; + signals: // Indicates that the effect pEffect has been loaded into slotNumber of // EffectChainSlot chainNumber. pEffect may be an invalid pointer, which @@ -86,6 +88,7 @@ class EffectChainSlot : public QObject { // Signal that indicates that the EffectChainSlot has been updated. void updated(); + private slots: void slotChainEffectsChanged(bool shouldEmit=true); void slotChainNameChanged(const QString& name); @@ -114,11 +117,11 @@ class EffectChainSlot : public QObject { private: QString debugString() const { - return QString("EffectChainSlot(%1)").arg(m_iChainNumber); + return QString("EffectChainSlot(%1)").arg(m_iChainSlotNumber); } const unsigned int m_iRackNumber; - const unsigned int m_iChainNumber; + const unsigned int m_iChainSlotNumber; const QString m_group; EffectRack* m_pEffectRack; diff --git a/src/effects/effectmanifest.h b/src/effects/effectmanifest.h index 3733344d30e..974235ab8c5 100644 --- a/src/effects/effectmanifest.h +++ b/src/effects/effectmanifest.h @@ -22,7 +22,8 @@ class EffectManifest { public: EffectManifest() - : m_effectRampsFromDry(false) { + : m_isMixingEQ(false), + m_effectRampsFromDry(false) { } virtual ~EffectManifest() { @@ -60,6 +61,15 @@ class EffectManifest { virtual const QString& description() const { return m_description; } + + virtual const bool& isEQ() const { + return m_isMixingEQ; + } + + virtual void setIsMixingEQ(const bool value) { + m_isMixingEQ = value; + } + virtual void setDescription(const QString& description) { m_description = description; } @@ -90,6 +100,8 @@ class EffectManifest { QString m_author; QString m_version; QString m_description; + // This helps us at DlgPrefEQ's basic selection of Equalizers + bool m_isMixingEQ; QList m_parameters; bool m_effectRampsFromDry; }; diff --git a/src/effects/effectparameterslot.h b/src/effects/effectparameterslot.h index f1b7f714c72..3e7fb449f91 100644 --- a/src/effects/effectparameterslot.h +++ b/src/effects/effectparameterslot.h @@ -68,4 +68,4 @@ class EffectParameterSlot : public EffectParameterSlotBase { DISALLOW_COPY_AND_ASSIGN(EffectParameterSlot); }; -#endif /* EFFECTPARAMETERSLOT_H */ +#endif // EFFECTPARAMETERSLOT_H diff --git a/src/effects/effectprocessor.h b/src/effects/effectprocessor.h index 8c6a2413d17..74bcd0e0602 100644 --- a/src/effects/effectprocessor.h +++ b/src/effects/effectprocessor.h @@ -49,7 +49,7 @@ class GroupEffectProcessor : public EffectProcessor { } virtual ~GroupEffectProcessor() { for (typename QMap::iterator it = m_groupState.begin(); - it != m_groupState.end();) { + it != m_groupState.end();) { T* pState = it.value(); it = m_groupState.erase(it); delete pState; diff --git a/src/effects/effectrack.cpp b/src/effects/effectrack.cpp index cd306099c39..304aa47b1ff 100644 --- a/src/effects/effectrack.cpp +++ b/src/effects/effectrack.cpp @@ -77,6 +77,25 @@ void EffectRack::slotNumEffectChainSlots(double v) { qWarning() << "WARNING: num_effectchain_slots is a read-only control."; } +void EffectRack::slotLoadEffectOnChainSlot(const unsigned int iChainSlotNumber, + const unsigned int iEffectSlotNumber, + QString effectId) { + if (iChainSlotNumber >= static_cast(m_effectChainSlots.size())) { + return; + } + EffectPointer pNextEffect = m_pEffectsManager->instantiateEffect(effectId); + + EffectChainSlotPointer pChainSlot = m_effectChainSlots[iChainSlotNumber]; + EffectChainPointer pChain = pChainSlot->getEffectChain(); + if (!pChain) { + pChain = EffectChainPointer(new EffectChain(m_pEffectsManager, QString(), + EffectChainPointer())); + pChain->setName(QObject::tr("Empty Chain")); + pChainSlot->loadEffectChain(pChain); + } + pChain->replaceEffect(iEffectSlotNumber, pNextEffect); +} + void EffectRack::slotClearRack(double v) { if (v > 0) { foreach (EffectChainSlotPointer pChainSlot, m_effectChainSlots) { @@ -89,6 +108,36 @@ int EffectRack::numEffectChainSlots() const { return m_effectChainSlots.size(); } + +EffectChainSlotPointer EffectRack::addEffectChainSlotForEQ() { + int iChainSlotNumber = m_effectChainSlots.size(); + EffectChainSlot* pChainSlot = + new EffectChainSlot(this, m_iRackNumber, iChainSlotNumber); + + // Add a single EffectSlot for EQDefault + pChainSlot->addEffectSlot(); + + const QSet& registeredGroups = + m_pEffectChainManager->registeredGroups(); + foreach (const QString& group, registeredGroups) { + pChainSlot->registerGroup(group); + } + + EffectChainSlotPointer pChainSlotPointer = EffectChainSlotPointer(pChainSlot); + m_effectChainSlots.append(pChainSlotPointer); + m_controlNumEffectChainSlots.setAndConfirm( + m_controlNumEffectChainSlots.get() + 1); + + // Now load an empty effect chain into the slot so that users can edit + // effect slots on the fly without having to load a chain. + EffectChainPointer pChain(new EffectChain(m_pEffectsManager, QString(), + EffectChainPointer())); + pChain->setName(QObject::tr("Empty Chain")); + pChainSlotPointer->loadEffectChain(pChain); + + return pChainSlotPointer; +} + EffectChainSlotPointer EffectRack::addEffectChainSlot() { int iChainSlotNumber = m_effectChainSlots.size(); EffectChainSlot* pChainSlot = @@ -143,6 +192,10 @@ EffectChainSlotPointer EffectRack::getEffectChainSlot(int i) { return m_effectChainSlots[i]; } +int EffectRack::getRackNumber() { + return m_iRackNumber; +} + void EffectRack::loadNextChain(const unsigned int iChainSlotNumber, EffectChainPointer pLoadedChain) { if (pLoadedChain) { diff --git a/src/effects/effectrack.h b/src/effects/effectrack.h index e75cb27ef64..cd2b5a99d3b 100644 --- a/src/effects/effectrack.h +++ b/src/effects/effectrack.h @@ -34,11 +34,18 @@ class EffectRack : public QObject { void registerGroup(const QString& group); int numEffectChainSlots() const; EffectChainSlotPointer addEffectChainSlot(); + EffectChainSlotPointer addEffectChainSlotForEQ(); EffectChainSlotPointer getEffectChainSlot(int i); + // Getter for rack number + int getRackNumber(); + public slots: void slotClearRack(double v); void slotNumEffectChainSlots(double v); + void slotLoadEffectOnChainSlot(const unsigned int iChainSlotNumber, + const unsigned int iEffectSlotNumber, + QString effectId); private slots: void loadNextChain(const unsigned int iChainSlotNumber, diff --git a/src/effects/effectsmanager.cpp b/src/effects/effectsmanager.cpp index c40be700aa7..d253d0a78f7 100644 --- a/src/effects/effectsmanager.cpp +++ b/src/effects/effectsmanager.cpp @@ -3,14 +3,15 @@ #include #include -#include "effects/effectchainmanager.h" #include "engine/effects/engineeffectsmanager.h" #include "engine/effects/engineeffect.h" EffectsManager::EffectsManager(QObject* pParent, ConfigObject* pConfig) : QObject(pParent), m_pEffectChainManager(new EffectChainManager(pConfig, this)), - m_nextRequestId(0) { + m_nextRequestId(0), + m_pLoEqFreq(NULL), + m_pHiEqFreq(NULL) { qRegisterMetaType("EffectChain::InsertionType"); QPair requestPipes = TwoWayMessagePipe::makeTwoWayMessagePipe( @@ -33,6 +34,9 @@ EffectsManager::~EffectsManager() { delete it.value(); it = m_activeRequests.erase(it); } + + delete m_pHiEqFreq; + delete m_pLoEqFreq; // Safe because the Engine is deleted before EffectsManager. delete m_pEngineEffectsManager; } @@ -69,6 +73,28 @@ const QList EffectsManager::getAvailableEffects() const { return availableEffects; } +const QList > EffectsManager::getEffectNamesFiltered(EffectManifestFilterFnc filter) const { + QList > filteredEQEffectNames; + QString currentEffectName; + foreach (EffectsBackend* pBackend, m_effectsBackends) { + QList backendEffects = pBackend->getEffectIds(); + foreach (QString effectId, backendEffects) { + EffectManifest manifest = pBackend->getManifest(effectId); + if (filter && !filter(&manifest)) { + continue; + } + currentEffectName = manifest.name(); + filteredEQEffectNames.append(qMakePair(effectId, currentEffectName)); + } + } + + return filteredEQEffectNames; +} + +bool EffectsManager::isEQ(const QString& effectId) const { + return getEffectManifest(effectId).isEQ(); +} + QString EffectsManager::getNextEffectId(const QString& effectId) { const QList effects = getAvailableEffects(); @@ -134,6 +160,122 @@ EffectRackPointer EffectsManager::getEffectRack(int i) { return m_pEffectChainManager->getEffectRack(i); } +EffectRackPointer EffectsManager::getEQEffectRack() { + // The EQ Rack is the last one + int eqRackNumber = getEQEffectRackNumber(); + return m_pEffectChainManager->getEffectRack(eqRackNumber); +} + +int EffectsManager::getEQEffectRackNumber() { + // The EQ Rack is the last one + int eqRackNumber = m_pEffectChainManager->getEffectRacksSize() - 1; + return eqRackNumber; +} + +void EffectsManager::addEqualizer(const QString& group) { + int rackNumExt = getEQEffectRackNumber() + 1; + EffectRackPointer pRack = getEQEffectRack(); + EffectChainSlotPointer pChainSlot = pRack->addEffectChainSlotForEQ(); + const unsigned int chainSlotNumberExt = pChainSlot->getChainSlotNumber() + 1; + + // Set the EQ to be active on group + ControlObject::set(ConfigKey(QString("[EffectRack%1_EffectUnit%2]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), + "group_" + group + "_enable"), + 1.0); + + // Set the EQ to be fully wet + ControlObject::set(ConfigKey(QString("[EffectRack%1_EffectUnit%2]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), + "mix"), + 1.0); + + // Create aliases + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterLow"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), "parameter1")); + + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterMid"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), "parameter2")); + + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterHigh"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), "parameter3")); + + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterLowKill"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), + "button_parameter1")); + + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterMidKill"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), + "button_parameter2")); + + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterHighKill"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), + "button_parameter3")); + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterLow_loaded"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), + "parameter1_loaded")); + + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterMid_loaded"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), + "parameter2_loaded")); + + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterHigh_loaded"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), + "parameter3_loaded")); + + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterLowKill_loaded"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), + "button_parameter1_loaded")); + + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterMidKill_loaded"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), + "button_parameter2_loaded")); + + ControlDoublePrivate::insertAlias(ConfigKey(group, "filterHighKill_loaded"), + ConfigKey( + QString("[EffectRack%1_EffectUnit%2_Effect1]").arg( + QString::number(rackNumExt), + QString::number(chainSlotNumberExt)), + "button_parameter3_loaded")); + + +} + void EffectsManager::setupDefaults() { //m_pEffectChainManager->loadEffectChains(); @@ -180,6 +322,13 @@ void EffectsManager::setupDefaults() { pEffect = instantiateEffect("org.mixxx.effects.echo"); pChain->addEffect(pEffect); m_pEffectChainManager->addEffectChain(pChain); + + // Add a new EffectRack for Equalizers + addEffectRack(); + + // These controls are used inside EQ Effects + m_pLoEqFreq = new ControlPotmeter(ConfigKey("[Mixer Profile]", "LoEQFrequency"), 0., 22040); + m_pHiEqFreq = new ControlPotmeter(ConfigKey("[Mixer Profile]", "HiEQFrequency"), 0., 22040); } bool EffectsManager::writeRequest(EffectsRequest* request) { diff --git a/src/effects/effectsmanager.h b/src/effects/effectsmanager.h index db08cb5d80b..8d32dea17a8 100644 --- a/src/effects/effectsmanager.h +++ b/src/effects/effectsmanager.h @@ -8,21 +8,25 @@ #include #include "configobject.h" +#include "controlpotmeter.h" +#include "controlpushbutton.h" #include "util.h" #include "util/fifo.h" #include "effects/effect.h" #include "effects/effectsbackend.h" #include "effects/effectchainslot.h" #include "effects/effectchain.h" +#include "effects/effectchainmanager.h" #include "effects/effectrack.h" #include "engine/effects/message.h" class EngineEffectsManager; -class EffectChainManager; class EffectsManager : public QObject { Q_OBJECT public: + typedef bool (*EffectManifestFilterFnc)(EffectManifest* pManifest); + EffectsManager(QObject* pParent, ConfigObject* pConfig); virtual ~EffectsManager(); @@ -43,17 +47,25 @@ class EffectsManager : public QObject { EffectRackPointer addEffectRack(); EffectRackPointer getEffectRack(int rack); + EffectRackPointer getEQEffectRack(); + int getEQEffectRackNumber(); QString getNextEffectId(const QString& effectId); QString getPrevEffectId(const QString& effectId); const QList getAvailableEffects() const; + // Each entry of the set is a pair containing the effect id and its name + const QList > getEffectNamesFiltered(EffectManifestFilterFnc filter) const; + bool isEQ(const QString& effectId) const; EffectManifest getEffectManifest(const QString& effectId) const; EffectPointer instantiateEffect(const QString& effectId); - // Temporary, but for setting up all the default EffectChains and EffectRack + // Temporary, but for setting up all the default EffectChains and EffectRacks void setupDefaults(); + // Add an Equalizer for the specified channel + void addEqualizer(const QString& group); + // Write an EffectsRequest to the EngineEffectsManager. EffectsManager takes // ownership of request and deletes it once a response is received. bool writeRequest(EffectsRequest* request); @@ -77,6 +89,10 @@ class EffectsManager : public QObject { qint64 m_nextRequestId; QHash m_activeRequests; + // We need to create Control Objects for Equalizers' frequencies + ControlPotmeter* m_pLoEqFreq; + ControlPotmeter* m_pHiEqFreq; + DISALLOW_COPY_AND_ASSIGN(EffectsManager); }; diff --git a/src/effects/native/bessel4lvmixeqeffect.cpp b/src/effects/native/bessel4lvmixeqeffect.cpp index bd1f182c5e3..86c74ea8894 100644 --- a/src/effects/native/bessel4lvmixeqeffect.cpp +++ b/src/effects/native/bessel4lvmixeqeffect.cpp @@ -16,6 +16,7 @@ EffectManifest Bessel4LVMixEQEffect::getManifest() { manifest.setDescription(QObject::tr( "A Bessel 4th order filter equalizer with Lipshitz and Vanderkooy mix (bit perfect unity, roll-off -24 db/Oct). " "To adjust frequency shelves see the Equalizer preferences.")); + manifest.setIsMixingEQ(true); manifest.setEffectRampsFromDry(true); EffectManifestParameter* low = manifest.addParameter(); diff --git a/src/effects/native/bessel8lvmixeqeffect.cpp b/src/effects/native/bessel8lvmixeqeffect.cpp index 380ecaf8cdc..1571b1609ee 100644 --- a/src/effects/native/bessel8lvmixeqeffect.cpp +++ b/src/effects/native/bessel8lvmixeqeffect.cpp @@ -23,6 +23,7 @@ EffectManifest Bessel8LVMixEQEffect::getManifest() { manifest.setDescription(QObject::tr( "A Bessel 8th order filter equalizer with Lipshitz and Vanderkooy mix (bit perfect unity, roll-off -48 db/Oct). " "To adjust frequency shelves see the Equalizer preferences.")); + manifest.setIsMixingEQ(true); manifest.setEffectRampsFromDry(true); EffectManifestParameter* low = manifest.addParameter(); diff --git a/src/effects/native/linkwitzriley8eqeffect.cpp b/src/effects/native/linkwitzriley8eqeffect.cpp index ebaf4ba654b..bfe262917df 100644 --- a/src/effects/native/linkwitzriley8eqeffect.cpp +++ b/src/effects/native/linkwitzriley8eqeffect.cpp @@ -20,6 +20,7 @@ EffectManifest LinkwitzRiley8EQEffect::getManifest() { manifest.setDescription(QObject::tr( "A Linkwitz-Riley 8th order filter equalizer (optimized crossover, constant phase shift, roll-off -48 db/Oct). " "To adjust frequency shelves see the Equalizer preferences.")); + manifest.setIsMixingEQ(true); EffectManifestParameter* low = manifest.addParameter(); low->setId("low"); diff --git a/src/engine/effects/engineeffectchain.cpp b/src/engine/effects/engineeffectchain.cpp index 06d7684a210..e69ef757fda 100644 --- a/src/engine/effects/engineeffectchain.cpp +++ b/src/engine/effects/engineeffectchain.cpp @@ -63,6 +63,7 @@ bool EngineEffectChain::removeEffect(EngineEffect* pEffect, int iIndex) { return true; } +// this is called from the engine thread onCallbackStart() bool EngineEffectChain::updateParameters(const EffectsRequest& message) { // TODO(rryan): Parameter interpolation. m_insertionType = message.SetEffectChainParameters.insertion_type; diff --git a/src/engine/enginedeck.cpp b/src/engine/enginedeck.cpp index 2850f113c70..ddc1f9dcc76 100644 --- a/src/engine/enginedeck.cpp +++ b/src/engine/enginedeck.cpp @@ -22,7 +22,6 @@ #include "engine/enginevinylsoundemu.h" #include "engine/enginedeck.h" #include "engine/enginepregain.h" -#include "engine/enginefilterblock.h" #include "engine/enginevumeter.h" #include "engine/enginefilterbessel4.h" @@ -58,7 +57,6 @@ EngineDeck::EngineDeck(QString group, // Set up additional engines m_pPregain = new EnginePregain(group); - m_pFilter = new EngineFilterBlock(group); m_pVUMeter = new EngineVuMeter(group); m_pBuffer = new EngineBuffer(group, pConfig, this, pMixingEngine); m_pVinylSoundEmu = new EngineVinylSoundEmu(group); @@ -68,7 +66,6 @@ EngineDeck::~EngineDeck() { delete m_pPassing; delete m_pBuffer; - delete m_pFilter; delete m_pPregain; delete m_pVinylSoundEmu; delete m_pVUMeter; @@ -101,8 +98,6 @@ void EngineDeck::process(CSAMPLE* pOut, const int iBufferSize) { // Apply pregain m_pPregain->process(pOut, iBufferSize); - // Filter the channel with EQs - m_pFilter->process(pOut, iBufferSize); // Process effects enabled for this channel if (m_pEngineEffectsManager != NULL) { // This is out of date by a callback but some effects will want the RMS diff --git a/src/engine/enginedeck.h b/src/engine/enginedeck.h index 112a6a6479e..7400189a0b5 100644 --- a/src/engine/enginedeck.h +++ b/src/engine/enginedeck.h @@ -30,7 +30,6 @@ class EngineBuffer; class EnginePregain; class EngineBuffer; -class EngineFilterBlock; class EngineClipping; class EngineMaster; class EngineVuMeter; @@ -80,7 +79,6 @@ class EngineDeck : public EngineChannel, public AudioDestination { private: ConfigObject* m_pConfig; EngineBuffer* m_pBuffer; - EngineFilterBlock* m_pFilter; EnginePregain* m_pPregain; EngineVinylSoundEmu* m_pVinylSoundEmu; EngineVuMeter* m_pVUMeter; diff --git a/src/engine/enginefilterblock.cpp b/src/engine/enginefilterblock.cpp deleted file mode 100644 index 511b24bccac..00000000000 --- a/src/engine/enginefilterblock.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/*************************************************************************** - enginefilterblock.cpp - description - ------------------- - begin : Thu Apr 4 2002 - copyright : (C) 2002 by Tue and Ken Haste Andersen - email : -***************************************************************************/ - -/*************************************************************************** -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -***************************************************************************/ - -#include - -#include "controlpushbutton.h" -#include "controlaudiotaperpot.h" -#include "controlobjectslave.h" -#include "engine/enginefilterblock.h" -#include "engine/enginefilterbessel4.h" -#include "engine/enginefilter.h" -#include "engine/enginefilterbutterworth8.h" -#include "sampleutil.h" -#include "util/timer.h" -#include "util/defs.h" - -ControlPotmeter* EngineFilterBlock::s_loEqFreq = NULL; -ControlPotmeter* EngineFilterBlock::s_hiEqFreq = NULL; -ControlPushButton* EngineFilterBlock::s_lofiEq = NULL; -ControlPushButton* EngineFilterBlock::s_EnableEq = NULL; - -EngineFilterBlock::EngineFilterBlock(QString group) -{ - ilowFreq = 0; - ihighFreq = 0; - blofi = false; - m_eqNeverTouched = true; - - m_pSampleRate = new ControlObjectSlave("[Master]", "samplerate"); - m_iOldSampleRate = static_cast(m_pSampleRate->get()); - - // Setup Filter Controls - - if (s_loEqFreq == NULL) { - s_loEqFreq = new ControlPotmeter(ConfigKey("[Mixer Profile]", "LoEQFrequency"), 0., 22040); - s_hiEqFreq = new ControlPotmeter(ConfigKey("[Mixer Profile]", "HiEQFrequency"), 0., 22040); - s_lofiEq = new ControlPushButton(ConfigKey("[Mixer Profile]", "LoFiEQs")); - s_EnableEq = new ControlPushButton(ConfigKey("[Mixer Profile]", "EnableEQs")); - } - - // Load Defaults - lowLight = new EngineFilterBessel4Low(m_iOldSampleRate, 246); - bandLight = new EngineFilterBessel4Band(m_iOldSampleRate, 246, 2484); - highLight = new EngineFilterBessel4High(m_iOldSampleRate, 2484); - lowDef = new EngineFilterButterworth8Low(m_iOldSampleRate, 246); - bandDef = new EngineFilterButterworth8Band(m_iOldSampleRate, 246, 2484); - highDef = new EngineFilterButterworth8High(m_iOldSampleRate, 2484); - - low = lowDef; - band = bandDef; - high = highDef; - - /* - lowrbj = new EngineFilterRBJ(); - lowrbj->calc_filter_coeffs(6, 100., 44100., 0.3, 0., true); - midrbj = new EngineFilterRBJ(); - midrbj->calc_filter_coeffs(6, 1000., 44100., 0.3, 0., true); - highrbj = new EngineFilterRBJ(); - highrbj->calc_filter_coeffs(8, 10000., 48000., 0.3, 0., true); - - lowrbj = new EngineFilterRBJ(); - lowrbj->calc_filter_coeffs(0, 100., 48000., 0.3., 0., false); - highrbj = new EngineFilterRBJ(); - highrbj->calc_filter_coeffs(1, 10000., 48000., 0.3., 0., false); - */ - - filterpotLow = new ControlAudioTaperPot(ConfigKey(group, "filterLow"), -12, 12, 0.5); - filterKillLow = new ControlPushButton(ConfigKey(group, "filterLowKill")); - filterKillLow->setButtonMode(ControlPushButton::POWERWINDOW); - - filterpotMid = new ControlAudioTaperPot(ConfigKey(group, "filterMid"), -12, 12, 0.5); - filterKillMid = new ControlPushButton(ConfigKey(group, "filterMidKill")); - filterKillMid->setButtonMode(ControlPushButton::POWERWINDOW); - - filterpotHigh = new ControlAudioTaperPot(ConfigKey(group, "filterHigh"), -12, 12, 0.5); - filterKillHigh = new ControlPushButton(ConfigKey(group, "filterHighKill")); - filterKillHigh->setButtonMode(ControlPushButton::POWERWINDOW); - - m_pLowBuf = new CSAMPLE[MAX_BUFFER_LEN]; - m_pBandBuf = new CSAMPLE[MAX_BUFFER_LEN]; - m_pHighBuf = new CSAMPLE[MAX_BUFFER_LEN]; - - old_low = old_mid = old_high = 1.0; -} - -EngineFilterBlock::~EngineFilterBlock() -{ - delete lowLight; - delete bandLight; - delete highLight; - delete lowDef; - delete bandDef; - delete highDef; - delete [] m_pHighBuf; - delete [] m_pBandBuf; - delete [] m_pLowBuf; - delete filterpotLow; - delete filterKillLow; - delete filterpotMid; - delete filterKillMid; - delete filterpotHigh; - delete filterKillHigh; - delete m_pSampleRate; - - // Delete and clear these static controls. We need to clear them so that - // other instances of EngineFilterBlock won't delete them as well. - delete s_loEqFreq; - s_loEqFreq = NULL; - delete s_hiEqFreq; - s_hiEqFreq = NULL; - delete s_lofiEq; - s_lofiEq = NULL; - delete s_EnableEq; - s_EnableEq = NULL; -} - -void EngineFilterBlock::setFilters() { - int iSampleRate = static_cast(m_pSampleRate->get()); - if (m_iOldSampleRate != iSampleRate || - (ilowFreq != (int)s_loEqFreq->get()) || - (ihighFreq != (int)s_hiEqFreq->get()) || - (blofi != (int)s_lofiEq->get())) { - ilowFreq = (int)s_loEqFreq->get(); - ihighFreq = (int)s_hiEqFreq->get(); - blofi = (int)s_lofiEq->get(); - m_iOldSampleRate = iSampleRate; - if (blofi) { - lowLight->setFrequencyCorners(iSampleRate, ilowFreq); - bandLight->setFrequencyCorners(iSampleRate, ilowFreq, ihighFreq); - highLight->setFrequencyCorners(iSampleRate, ihighFreq); - low = lowLight; - band = bandLight; - high = highLight; - } else { - lowDef->setFrequencyCorners(iSampleRate, ilowFreq); - bandDef->setFrequencyCorners(iSampleRate, ilowFreq, ihighFreq); - highDef->setFrequencyCorners(iSampleRate, ihighFreq); - low = lowDef; - band = bandDef; - high = highDef; - } - } -} - -void EngineFilterBlock::process(CSAMPLE* pInOut, const int iBufferSize) { - ScopedTimer t("EngineFilterBlock::process"); - - // Check if EQ processing is disabled. - if (!s_EnableEq->get()) { - return; - } - - float fLow = 0.f, fMid = 0.f, fHigh = 0.f; - if (filterKillLow->get() == 0.) { - fLow = filterpotLow->get(); - } - if (filterKillMid->get() == 0.) { - fMid = filterpotMid->get(); - } - if (filterKillHigh->get() == 0.) { - fHigh = filterpotHigh->get(); - } - - // If the user has never touched the Eq controls (they are still at zero) - // Then pass through. As soon as the user twiddles one, actually activate - // the EQ code and crossfade to it. This will save CPU if the user never - // uses EQ but also doesn't know to disable it. - if (m_eqNeverTouched) { - if (fLow == 1. && fMid == 1. && fHigh == 1.) { - return; - } - m_eqNeverTouched = false; - } - - float fDry = 0; - // This is the RGBW Mix. It is currently not working, - // because of the group delay, introduced by the filters. - // Since the dry signal has no delay, we get a frequency distorsion - // once it is mixed together with the filtered signal - // This might be fixed later by an allpass filter for the dry signal - // or zero-phase no-lag filters - // "Linear Phase EQ" "filtfilt()" - //fDry = qMin(qMin(fLow, fMid), fHigh); - //fLow -= fDry; - //fMid -= fDry; - //fHigh -= fDry; - - setFilters(); - - // Process the new EQ'd signals. - // They use up to 16 frames history so in case we are just starting, - // 16 frames are junk, this is handled by ramp_delay - int ramp_delay = 0; - if (fLow || old_low) { - low->process(pInOut, m_pLowBuf, iBufferSize); - if(old_low == 0) { - ramp_delay = 30; - } - } - if (fMid || old_mid) { - band->process(pInOut, m_pBandBuf, iBufferSize); - if(old_mid== 0) { - ramp_delay = 30; - } - } - if (fHigh || old_high) { - high->process(pInOut, m_pHighBuf, iBufferSize); - if(old_high == 0) { - ramp_delay = 30; - } - } - - if (ramp_delay) { - // first use old gains - SampleUtil::copy4WithGain(pInOut, - pInOut, old_dry, - m_pLowBuf, old_low, - m_pBandBuf, old_mid, - m_pHighBuf, old_high, - ramp_delay); - // Now ramp the remaining frames - SampleUtil::copy4WithRampingGain(&pInOut[ramp_delay], - &pInOut[ramp_delay], old_dry, fDry, - &m_pLowBuf[ramp_delay], old_low, fLow, - &m_pBandBuf[ramp_delay], old_mid, fMid, - &m_pHighBuf[ramp_delay], old_high, fHigh, - iBufferSize - ramp_delay); - } else if (fLow != old_low || - fMid != old_mid || - fHigh != old_high || - fDry != old_dry) { - SampleUtil::copy4WithRampingGain(pInOut, - pInOut, old_dry, fDry, - m_pLowBuf, old_low, fLow, - m_pBandBuf, old_mid, fMid, - m_pHighBuf, old_high, fHigh, - iBufferSize); - } else { - SampleUtil::copy4WithGain(pInOut, - pInOut, fDry, - m_pLowBuf, fLow, - m_pBandBuf, fMid, - m_pHighBuf, fHigh, - iBufferSize); - } - - old_low = fLow; - old_mid = fMid; - old_high = fHigh; - old_dry = fDry; -} diff --git a/src/engine/enginefilterblock.h b/src/engine/enginefilterblock.h deleted file mode 100644 index d2da16b0983..00000000000 --- a/src/engine/enginefilterblock.h +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************** - enginefilterblock.h - description - ------------------- - begin : Thu Apr 4 2002 - copyright : (C) 2002 by Tue and Ken Haste Andersen - email : - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef ENGINEFILTERBLOCK_H -#define ENGINEFILTERBLOCK_H - -#include "engine/engineobject.h" -#include "engine/enginefilterbessel4.h" -#include "engine/enginefilterbutterworth8.h" - -class ControlObjectSlave; -class ControlAudioTaperPot; -class ControlPotmeter; -class ControlPushButton; - -#define SIZE_NOISE_BUF 40 -//#define NOISE_FACTOR 116.415321827e-12 // 1/4 bit of noise (99db SNR) -#define NOISE_FACTOR 0.25 // this is necessary to prevent denormals -// from consuming too much CPU resources -// and is well below being audible. -/** - * Parallel processing of LP, BP and HP filters, and final mixing - * - *@author Tue and Ken Haste Andersen - */ - -class EngineFilterBlock : public EngineObject { - Q_OBJECT - public: - EngineFilterBlock(QString group); - virtual ~EngineFilterBlock(); - - void process(CSAMPLE* pInOut, const int iBufferSize); - - private: - void setFilters(); - - CSAMPLE *m_pLowBuf, *m_pBandBuf, *m_pHighBuf; - EngineFilterBessel4Low* lowLight; - EngineFilterBessel4Band* bandLight; - EngineFilterBessel4High* highLight; - EngineFilterButterworth8Low* lowDef; - EngineFilterButterworth8Band* bandDef; - EngineFilterButterworth8High* highDef; - EngineObjectConstIn *low, *band, *high; - ControlAudioTaperPot *filterpotLow, *filterpotMid, *filterpotHigh; - ControlPushButton *filterKillLow, *filterKillMid, *filterKillHigh; - ControlObjectSlave* m_pSampleRate; - - static ControlPotmeter *s_loEqFreq, *s_hiEqFreq; - static ControlPushButton *s_lofiEq; - static ControlPushButton *s_EnableEq; - - int m_iOldSampleRate; - double old_low, old_mid, old_high, old_dry; - - int ilowFreq, ihighFreq; - bool blofi; - bool m_eqNeverTouched; -}; - -#endif diff --git a/src/engine/enginefilterbutterworth8.cpp b/src/engine/enginefilterbutterworth8.cpp index 51281df5621..7cc42b59bb1 100644 --- a/src/engine/enginefilterbutterworth8.cpp +++ b/src/engine/enginefilterbutterworth8.cpp @@ -1,6 +1,5 @@ #include "engine/enginefilterbutterworth8.h" - EngineFilterButterworth8Low::EngineFilterButterworth8Low(int sampleRate, double freqCorner1) { setFrequencyCorners(sampleRate, freqCorner1); } @@ -23,7 +22,6 @@ void EngineFilterButterworth8Band::setFrequencyCorners(int sampleRate, setCoefs("BpBu8", sampleRate, freqCorner1, freqCorner2); } - EngineFilterButterworth8High::EngineFilterButterworth8High(int sampleRate, double freqCorner1) { setFrequencyCorners(sampleRate, freqCorner1); } diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 94b6e7b03b1..2fec93fb943 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -33,6 +33,7 @@ #include "defs_urls.h" #include "dlgabout.h" #include "dlgpreferences.h" +#include "dlgprefeq.h" #include "dlgdevelopertools.h" #include "engine/enginemaster.h" #include "engine/enginemicrophone.h" @@ -149,7 +150,7 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) NativeBackend* pNativeBackend = new NativeBackend(m_pEffectsManager); m_pEffectsManager->addEffectsBackend(pNativeBackend); - // Sets up the default EffectChains and EffectRack. + // Sets up the default EffectChains and EffectRacks m_pEffectsManager->setupDefaults(); m_pRecordingManager = new RecordingManager(m_pConfig, m_pEngine); @@ -217,7 +218,7 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) // Do not write meta data back to ID3 when meta data has changed // Because multiple TrackDao objects can exists for a particular track - // writing meta data may ruine your MP3 file if done simultaneously. + // writing meta data may ruin your MP3 file if done simultaneously. // see Bug #728197 // For safety reasons, we deactivate this feature. m_pConfig->set(ConfigKey("[Library]","WriteAudioTags"), ConfigValue(0)); @@ -245,7 +246,6 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) // Create the player manager. m_pPlayerManager = new PlayerManager(m_pConfig, m_pSoundManager, m_pEffectsManager, m_pEngine); - m_pPlayerManager->addConfiguredDecks(); m_pPlayerManager->addSampler(); m_pPlayerManager->addSampler(); @@ -333,7 +333,8 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) // Initialize preference dialog m_pPrefDlg = new DlgPreferences(this, m_pSkinLoader, m_pSoundManager, m_pPlayerManager, - m_pControllerManager, m_pVCManager, m_pConfig, m_pLibrary); + m_pControllerManager, m_pVCManager, m_pEffectsManager, + m_pConfig, m_pLibrary); m_pPrefDlg->setWindowIcon(QIcon(":/images/ic_mixxx_window.png")); m_pPrefDlg->setHidden(true); diff --git a/src/playermanager.cpp b/src/playermanager.cpp index 86232f1dae4..a33fa64a810 100644 --- a/src/playermanager.cpp +++ b/src/playermanager.cpp @@ -256,12 +256,17 @@ void PlayerManager::addDeckInner() { // Register the deck output with SoundManager (deck is 0-indexed to SoundManager) m_pSoundManager->registerOutput( - AudioOutput(AudioOutput::DECK, 0, 0, number-1), m_pEngine); + AudioOutput(AudioOutput::DECK, 0, 0, number - 1), m_pEngine); // Register vinyl input signal with deck for passthrough support. EngineDeck* pEngineDeck = pDeck->getEngineDeck(); m_pSoundManager->registerInput( - AudioInput(AudioInput::VINYLCONTROL, 0, 0, number-1), pEngineDeck); + AudioInput(AudioInput::VINYLCONTROL, 0, 0, number - 1), pEngineDeck); + + // Setup EQ for this deck + m_pEffectsManager->addEqualizer(group); + + pDeck->setupEqControlls(); } void PlayerManager::addSampler() { diff --git a/src/waveform/renderers/qtwaveformrendererfilteredsignal.cpp b/src/waveform/renderers/qtwaveformrendererfilteredsignal.cpp index da066ccf106..d12355fea6a 100644 --- a/src/waveform/renderers/qtwaveformrendererfilteredsignal.cpp +++ b/src/waveform/renderers/qtwaveformrendererfilteredsignal.cpp @@ -3,7 +3,7 @@ #include "waveformwidgetrenderer.h" #include "waveform/waveform.h" #include "waveform/waveformwidgetfactory.h" -#include "controlobjectthread.h" +#include "controlobjectslave.h" #include "trackinfoobject.h" #include "util/math.h" diff --git a/src/waveform/renderers/waveformrendererfilteredsignal.cpp b/src/waveform/renderers/waveformrendererfilteredsignal.cpp index 17b5b4d39be..2cd009a540d 100644 --- a/src/waveform/renderers/waveformrendererfilteredsignal.cpp +++ b/src/waveform/renderers/waveformrendererfilteredsignal.cpp @@ -3,7 +3,7 @@ #include "waveformwidgetrenderer.h" #include "waveform/waveform.h" #include "waveform/waveformwidgetfactory.h" -#include "controlobjectthread.h" +#include "controlobjectslave.h" #include "widget/wskincolor.h" #include "trackinfoobject.h" #include "widget/wwidget.h" diff --git a/src/waveform/renderers/waveformrenderersignalbase.cpp b/src/waveform/renderers/waveformrenderersignalbase.cpp index edb2bbe29fa..0bf64e2506a 100644 --- a/src/waveform/renderers/waveformrenderersignalbase.cpp +++ b/src/waveform/renderers/waveformrenderersignalbase.cpp @@ -5,7 +5,7 @@ #include "waveform/waveformwidgetfactory.h" #include "waveformwidgetrenderer.h" #include "controlobject.h" -#include "controlobjectthread.h" +#include "controlobjectslave.h" #include "widget/wskincolor.h" #include "widget/wwidget.h" @@ -64,22 +64,22 @@ bool WaveformRendererSignalBase::init() { deleteControls(); //create controls - m_pEQEnabled = new ControlObjectThread( - ConfigKey("[Mixer Profile]", "EnableEQs")); - m_pLowFilterControlObject = new ControlObjectThread( - m_waveformRenderer->getGroup(),"filterLow"); - m_pLowFilterControlObject = new ControlObjectThread( - m_waveformRenderer->getGroup(),"filterLow"); - m_pMidFilterControlObject = new ControlObjectThread( - m_waveformRenderer->getGroup(),"filterMid"); - m_pHighFilterControlObject = new ControlObjectThread( - m_waveformRenderer->getGroup(),"filterHigh"); - m_pLowKillControlObject = new ControlObjectThread( - m_waveformRenderer->getGroup(),"filterLowKill"); - m_pMidKillControlObject = new ControlObjectThread( - m_waveformRenderer->getGroup(),"filterMidKill"); - m_pHighKillControlObject = new ControlObjectThread( - m_waveformRenderer->getGroup(),"filterHighKill"); + m_pEQEnabled = new ControlObjectSlave( + m_waveformRenderer->getGroup(), "fliterWaveformEnable"); + m_pLowFilterControlObject = new ControlObjectSlave( + m_waveformRenderer->getGroup(), "filterLow"); + m_pLowFilterControlObject = new ControlObjectSlave( + m_waveformRenderer->getGroup(), "filterLow"); + m_pMidFilterControlObject = new ControlObjectSlave( + m_waveformRenderer->getGroup(), "filterMid"); + m_pHighFilterControlObject = new ControlObjectSlave( + m_waveformRenderer->getGroup(), "filterHigh"); + m_pLowKillControlObject = new ControlObjectSlave( + m_waveformRenderer->getGroup(), "filterLowKill"); + m_pMidKillControlObject = new ControlObjectSlave( + m_waveformRenderer->getGroup(), "filterMidKill"); + m_pHighKillControlObject = new ControlObjectSlave( + m_waveformRenderer->getGroup(), "filterHighKill"); return onInit(); } diff --git a/src/waveform/renderers/waveformrenderersignalbase.h b/src/waveform/renderers/waveformrenderersignalbase.h index ce39ee29e5d..1571b77bf6b 100644 --- a/src/waveform/renderers/waveformrenderersignalbase.h +++ b/src/waveform/renderers/waveformrenderersignalbase.h @@ -6,7 +6,7 @@ #include "skin/skincontext.h" class ControlObject; -class ControlObjectThread; +class ControlObjectSlave; class WaveformRendererSignalBase : public WaveformRendererAbstract { public: @@ -26,13 +26,13 @@ class WaveformRendererSignalBase : public WaveformRendererAbstract { float* highGain); protected: - ControlObjectThread* m_pEQEnabled; - ControlObjectThread* m_pLowFilterControlObject; - ControlObjectThread* m_pMidFilterControlObject; - ControlObjectThread* m_pHighFilterControlObject; - ControlObjectThread* m_pLowKillControlObject; - ControlObjectThread* m_pMidKillControlObject; - ControlObjectThread* m_pHighKillControlObject; + ControlObjectSlave* m_pEQEnabled; + ControlObjectSlave* m_pLowFilterControlObject; + ControlObjectSlave* m_pMidFilterControlObject; + ControlObjectSlave* m_pHighFilterControlObject; + ControlObjectSlave* m_pLowKillControlObject; + ControlObjectSlave* m_pMidKillControlObject; + ControlObjectSlave* m_pHighKillControlObject; Qt::Alignment m_alignment; diff --git a/src/waveform/renderers/waveformwidgetrenderer.h b/src/waveform/renderers/waveformwidgetrenderer.h index 7a4c036ad7c..6d058a8f80c 100644 --- a/src/waveform/renderers/waveformwidgetrenderer.h +++ b/src/waveform/renderers/waveformwidgetrenderer.h @@ -34,7 +34,7 @@ class WaveformWidgetRenderer { void onPreRender(VSyncThread* vsyncThread); void draw(QPainter* painter, QPaintEvent* event); - const char* getGroup() const { return m_group;} + inline const char* getGroup() const { return m_group;} const TrackPointer getTrackInfo() const { return m_trackInfoObject;} double getFirstDisplayedPosition() const { return m_firstDisplayedPosition;}