diff --git a/CMakeLists.txt b/CMakeLists.txt index da6a4d1f02f9..4b50bdc8740a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -497,6 +497,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/control/controlproxy.cpp src/control/controlpushbutton.cpp src/control/controlttrotary.cpp + src/control/grouphandle.cpp src/controllers/controller.cpp src/controllers/controllerenumerator.cpp src/controllers/controllerinputmappingtablemodel.cpp diff --git a/src/control/grouphandle.cpp b/src/control/grouphandle.cpp new file mode 100644 index 000000000000..fd6ae5f64d80 --- /dev/null +++ b/src/control/grouphandle.cpp @@ -0,0 +1,81 @@ +#include "control/grouphandle.h" + +#include +#include +#include +#include + +namespace { + +QMutex allGroupHandlesByNameMutex; + +typedef QHash AllGroupHandlesByName; +AllGroupHandlesByName allGroupHandlesByName; + +QAtomicInt allGroupHandlesFrozen; + +} // namespace + +GroupHandle getOrCreateGroupHandleByName(const QString& name, bool create) { + DEBUG_ASSERT(name == name.trimmed()); + if (allGroupHandlesFrozen.loadRelaxed()) { + // lock-free + DEBUG_ASSERT(!create); + auto iter = allGroupHandlesByName.find(name); + if (iter != allGroupHandlesByName.end()) { + return iter.value(); + } + } else { + // blocking + auto locked = QMutexLocker(&allGroupHandlesByNameMutex); + auto iter = allGroupHandlesByName.find(name); + if (iter != allGroupHandlesByName.end()) { + // Unlock mutex before logging (I/O) + locked.unlock(); + qDebug() << "Found existing group handle" << iter.value(); + return iter.value(); + } + if (create && !allGroupHandlesFrozen.loadAcquire()) { + const auto index = allGroupHandlesByName.size(); + // This will leak memory, i.e. descriptors will never be + // freed during a session until application shutdown. + const auto handle = new mixxx::grouphandle_private::Descriptor{index, name}; + allGroupHandlesByName.insert(name, handle); + // Unlock mutex before logging (I/O) + locked.unlock(); + qInfo() << "Created new group handle" << handle; + return handle; + } + } + qWarning() << "Unknown group name" << name; + return kNullGroupHandle; +} + +void freezeAllGroupHandles() { + const auto locked = QMutexLocker(&allGroupHandlesByNameMutex); + allGroupHandlesByName.squeeze(); + allGroupHandlesFrozen.storeRelease(1); +} + +int resetAllGroupHandles() { + auto locked = QMutexLocker(&allGroupHandlesByNameMutex); + AllGroupHandlesByName tmpGroupHandlesByName; + tmpGroupHandlesByName.swap(allGroupHandlesByName); + allGroupHandlesFrozen.storeRelease(0); + locked.unlock(); + for (const auto groupHandle : qAsConst(tmpGroupHandlesByName)) { + qInfo() << "Deleting" << groupHandle; + delete groupHandle; + } + return tmpGroupHandlesByName.size(); +} + +namespace mixxx { +namespace grouphandle_private { + +QDebug operator<<(QDebug dbg, const mixxx::grouphandle_private::Descriptor& arg) { + return dbg << "GroupHandle{" << arg.m_index << arg.m_name << "}"; +} + +} // namespace grouphandle_private +} // namespace mixxx diff --git a/src/control/grouphandle.h b/src/control/grouphandle.h new file mode 100644 index 000000000000..5f74b35271b8 --- /dev/null +++ b/src/control/grouphandle.h @@ -0,0 +1,137 @@ +#pragma once + +#include +#include + +#include "util/assert.h" +#include "util/compatibility/qhash.h" + +namespace mixxx { +namespace grouphandle_private { +class Descriptor; +} // namespace grouphandle_private +} // namespace mixxx + +typedef const mixxx::grouphandle_private::Descriptor* GroupHandle; + +constexpr GroupHandle kNullGroupHandle = nullptr; + +GroupHandle getOrCreateGroupHandleByName( + const QString& name, + bool create = true); + +inline GroupHandle getGroupHandleByName(const QString& name) { + return getOrCreateGroupHandleByName(name, false); +} + +/// Finalize the registration of groups +/// +/// After invoking this functions no handles for new groups +/// could be created. Accessing the existing handles by their +/// name will be lock-free from now on. +void freezeAllGroupHandles(); + +/// Free all group handles +/// +/// Do not call while handles are in use!!! Mainly needed for testing. +/// +/// Returns the number of groups. +int resetAllGroupHandles(); + +namespace mixxx { +namespace grouphandle_private { + +class Descriptor final { + public: + static constexpr int kInvalidIndex = -1; + + // Trailing return type declaration is required for Clang 14 + friend auto ::getOrCreateGroupHandleByName( + const QString& name, + bool create) -> GroupHandle; + + Descriptor() = default; + Descriptor(Descriptor&&) = delete; + Descriptor(const Descriptor&) = delete; + Descriptor& operator=(Descriptor&&) = delete; + Descriptor& operator=(const Descriptor&) = delete; + + /// Index + /// + /// 0-based integer identifier. The maximum number is limited by the + /// total number of different descriptors, i.e. the total number of + /// distinct group names. + friend int indexOfGroupHandle(GroupHandle handle) { + if (!handle) { + return kInvalidIndex; + } + DEBUG_ASSERT(handle->valid()); + return handle->m_index; + } + + /// Group name + /// + /// String identifier. + friend QString nameOfGroupHandle(GroupHandle handle) { + if (!handle) { + return {}; + } + DEBUG_ASSERT(handle->valid()); + return handle->m_name; + } + + friend bool operator<(const Descriptor& lhs, const Descriptor& rhs) { + return lhs.m_index < rhs.m_index; + } + + friend bool operator==(const Descriptor& lhs, const Descriptor& rhs) { + return lhs.m_index == rhs.m_index; + } + + friend qhash_seed_t qHash(const Descriptor& arg, qhash_seed_t seed = 0) { + return qHash(arg.m_index, seed); + } + + friend QDebug operator<<(QDebug dbg, const Descriptor& arg); + + private: + bool valid() const { + DEBUG_ASSERT(m_index == kInvalidIndex || m_index >= 0); + DEBUG_ASSERT((m_index == kInvalidIndex) == m_name.isEmpty()); + return m_index != kInvalidIndex; + } + + Descriptor(int index, QString name) + : m_index(index), + m_name(std::move(name)) { + } + + int m_index = kInvalidIndex; + QString m_name; +}; + +inline bool operator!=( + const Descriptor& lhs, + const Descriptor& rhs) { + return !(lhs == rhs); +} + +} // namespace grouphandle_private + +} // namespace mixxx + +inline qhash_seed_t qHash(GroupHandle arg, qhash_seed_t seed = 0) { + if (arg) { + return qHash(*arg, seed); + } else { + return qHash(mixxx::grouphandle_private::Descriptor{}, seed); + } +} + +inline QDebug operator<<(QDebug dbg, GroupHandle arg) { + if (arg) { + return dbg << *arg; + } else { + return dbg << mixxx::grouphandle_private::Descriptor{}; + } +} diff --git a/src/coreservices.cpp b/src/coreservices.cpp index 205df0d4b6b7..7e751ecfcb48 100644 --- a/src/coreservices.cpp +++ b/src/coreservices.cpp @@ -49,7 +49,6 @@ #include -#include "engine/channelhandle.h" // Xlibint.h predates C++ and defines macros which conflict // with references to std::max and std::min #undef max @@ -253,16 +252,13 @@ void CoreServices::initialize(QApplication* pApp) { m_pControlIndicatorTimer = std::make_shared(this); - auto pChannelHandleFactory = std::make_shared(); - emit initializationProgressUpdate(20, tr("effects")); - m_pEffectsManager = std::make_shared(pConfig, pChannelHandleFactory); + m_pEffectsManager = std::make_shared(pConfig); m_pEngine = std::make_shared( pConfig, "[Master]", m_pEffectsManager.get(), - pChannelHandleFactory, true); emit initializationProgressUpdate(30, tr("audio interface")); diff --git a/src/effects/backends/effectprocessor.h b/src/effects/backends/effectprocessor.h index 837da2b91043..99cdd6d5eb07 100644 --- a/src/effects/backends/effectprocessor.h +++ b/src/effects/backends/effectprocessor.h @@ -6,7 +6,6 @@ #include #include "effects/defs.h" -#include "engine/channelhandle.h" #include "engine/effects/groupfeaturestate.h" #include "engine/effects/message.h" #include "engine/engine.h" @@ -68,16 +67,16 @@ class EffectProcessor { /// These methods are called from the main thread virtual void initialize( - const QSet& activeInputChannels, - const QSet& registeredOutputChannels, + const QSet& activeInputChannels, + const QSet& registeredOutputChannels, const mixxx::EngineParameters& engineParameters) = 0; virtual void loadEngineEffectParameters( const QMap& parameters) = 0; virtual EffectState* createState(const mixxx::EngineParameters& engineParameters) = 0; - virtual void deleteStatesForInputChannel(ChannelHandle inputChannel) = 0; + virtual void deleteStatesForInputChannel(GroupHandle pInputChannel) = 0; // Called from the audio thread - virtual bool loadStatesForInputChannel(ChannelHandle inputChannel, + virtual bool loadStatesForInputChannel(GroupHandle inputChannel, const EffectStatesMap* pStatesMap) = 0; /// Called from the audio thread @@ -91,8 +90,8 @@ class EffectProcessor { /// EffectProcessorImpl::process to fetch the appropriate EffectState and /// pass it on to EffectProcessorImpl::processChannel, allowing one /// EffectProcessor instance to process multiple signals simultaneously. - virtual void process(const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + virtual void process(GroupHandle inputHandle, + GroupHandle outputHandle, const CSAMPLE* pInput, CSAMPLE* pOutput, const mixxx::EngineParameters& engineParameters, @@ -149,8 +148,8 @@ class EffectProcessorImpl : public EffectProcessor { const EffectEnableState enableState, const GroupFeatureState& groupFeatures) = 0; - void process(const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + void process(GroupHandle inputHandle, + GroupHandle outputHandle, const CSAMPLE* pInput, CSAMPLE* pOutput, const mixxx::EngineParameters& engineParameters, @@ -161,8 +160,8 @@ class EffectProcessorImpl : public EffectProcessor { if (kEffectDebugOutput) { qWarning() << "EffectProcessorImpl::process could not retrieve" "EffectState for input" - << inputHandle - << "and output" << outputHandle + << *inputHandle + << "and output" << *outputHandle << "EffectState should have been preallocated in the" "main thread."; } @@ -172,29 +171,29 @@ class EffectProcessorImpl : public EffectProcessor { processChannel(pState, pInput, pOutput, engineParameters, enableState, groupFeatures); } - void initialize(const QSet& activeInputChannels, - const QSet& registeredOutputChannels, + void initialize(const QSet& activeInputChannels, + const QSet& registeredOutputChannels, const mixxx::EngineParameters& engineParameters) final { m_registeredOutputChannels = registeredOutputChannels; - for (const ChannelHandleAndGroup& inputChannel : activeInputChannels) { + for (GroupHandle inputChannel : activeInputChannels) { if (kEffectDebugOutput) { qDebug() << this << "EffectProcessorImpl::initialize allocating " "EffectStates for input" << inputChannel; } ChannelHandleMap outputChannelMap; - for (const ChannelHandleAndGroup& outputChannel : + for (GroupHandle outputChannel : std::as_const(m_registeredOutputChannels)) { - outputChannelMap.insert(outputChannel.handle(), + outputChannelMap.insert(outputChannel, createSpecificState(engineParameters)); if (kEffectDebugOutput) { qDebug() << this << "EffectProcessorImpl::initialize " "registering output" - << outputChannel << outputChannelMap[outputChannel.handle()]; + << outputChannel << outputChannelMap[outputChannel]; } } - m_channelStateMatrix.insert(inputChannel.handle(), outputChannelMap); + m_channelStateMatrix.insert(inputChannel, outputChannelMap); } }; @@ -202,7 +201,7 @@ class EffectProcessorImpl : public EffectProcessor { return createSpecificState(engineParameters); }; - bool loadStatesForInputChannel(ChannelHandle inputChannel, + bool loadStatesForInputChannel(GroupHandle inputChannel, const EffectStatesMap* pStatesMap) final { if (kEffectDebugOutput) { qDebug() << "EffectProcessorImpl::loadStatesForInputChannel" << this @@ -210,7 +209,7 @@ class EffectProcessorImpl : public EffectProcessor { } // NOTE: ChannelHandleMap is like a map in that it associates an - // object with a ChannelHandle key, but it is actually backed by a + // object with a GroupHandle key, but it is actually backed by a // QVarLengthArray, not a QMap. So it is okay that // m_channelStateMatrix may be accessed concurrently in the main // thread in deleteStatesForInputChannel. @@ -233,8 +232,8 @@ class EffectProcessorImpl : public EffectProcessor { } } - QSet receivedOutputChannels = m_registeredOutputChannels; - for (const ChannelHandleAndGroup& outputChannel : + QSet receivedOutputChannels = m_registeredOutputChannels; + for (GroupHandle outputChannel : std::as_const(m_registeredOutputChannels)) { if (kEffectDebugOutput) { qDebug() << "EffectProcessorImpl::loadStatesForInputChannel" @@ -242,11 +241,11 @@ class EffectProcessorImpl : public EffectProcessor { } auto pState = dynamic_cast( - pStatesMap->at(outputChannel.handle())); + pStatesMap->at(outputChannel)); VERIFY_OR_DEBUG_ASSERT(pState != nullptr) { return false; } - effectSpecificStatesMap.insert(outputChannel.handle(), pState); + effectSpecificStatesMap.insert(outputChannel, pState); receivedOutputChannels.insert(outputChannel); } // Output channels are hardcoded in EngineMaster and should not @@ -256,14 +255,14 @@ class EffectProcessorImpl : public EffectProcessor { }; /// Called from main thread for garbage collection after an input channel is disabled - void deleteStatesForInputChannel(ChannelHandle inputChannel) final { + void deleteStatesForInputChannel(GroupHandle inputChannel) final { if (kEffectDebugOutput) { qDebug() << "EffectProcessorImpl::deleteStatesForInputChannel" << this << inputChannel; } // NOTE: ChannelHandleMap is like a map in that it associates an - // object with a ChannelHandle key, but it is actually backed by a + // object with a GroupHandle key, but it is actually backed by a // QVarLengthArray, not a QMap. So it is okay that // m_channelStateMatrix may be accessed concurrently in the audio // engine thread in loadStatesForInputChannel. @@ -296,6 +295,6 @@ class EffectProcessorImpl : public EffectProcessor { }; private: - QSet m_registeredOutputChannels; + QSet m_registeredOutputChannels; ChannelHandleMap> m_channelStateMatrix; }; diff --git a/src/effects/chains/outputeffectchain.cpp b/src/effects/chains/outputeffectchain.cpp index 6a47f3ad25cc..906e4800feca 100644 --- a/src/effects/chains/outputeffectchain.cpp +++ b/src/effects/chains/outputeffectchain.cpp @@ -12,21 +12,21 @@ OutputEffectChain::OutputEffectChain(EffectsManager* pEffectsManager, m_effectSlots[0]->setEnabled(true); // Register the master channel - const ChannelHandleAndGroup* masterHandleAndGroup = nullptr; + GroupHandle masterHandleAndGroup = nullptr; - // TODO(Be): Remove this hideous hack to get the ChannelHandleAndGroup - const QSet& registeredChannels = + // TODO(Be): Remove this hideous hack to get the GroupHandle + const QSet& registeredChannels = m_pEffectsManager->registeredInputChannels(); - for (const ChannelHandleAndGroup& handle_group : registeredChannels) { - if (handle_group.name() == "[MasterOutput]") { - masterHandleAndGroup = &handle_group; + for (GroupHandle handle_group : registeredChannels) { + if (nameOfGroupHandle(handle_group) == "[MasterOutput]") { + masterHandleAndGroup = handle_group; break; } } DEBUG_ASSERT(masterHandleAndGroup != nullptr); - registerInputChannel(*masterHandleAndGroup); - enableForInputChannel(*masterHandleAndGroup); + registerInputChannel(masterHandleAndGroup); + enableForInputChannel(masterHandleAndGroup); m_pControlChainMix->set(1.0); sendParameterUpdate(); } diff --git a/src/effects/chains/pergroupeffectchain.cpp b/src/effects/chains/pergroupeffectchain.cpp index 2ec903bbb4cc..d6c69146e36f 100644 --- a/src/effects/chains/pergroupeffectchain.cpp +++ b/src/effects/chains/pergroupeffectchain.cpp @@ -16,17 +16,17 @@ PerGroupEffectChain::PerGroupEffectChain(const QString& group, sendParameterUpdate(); // TODO(rryan): remove. - const ChannelHandleAndGroup* handleAndGroup = nullptr; - for (const ChannelHandleAndGroup& handle_group : + GroupHandle handleAndGroup = nullptr; + for (GroupHandle handle_group : m_pEffectsManager->registeredInputChannels()) { - if (handle_group.name() == group) { - handleAndGroup = &handle_group; + if (nameOfGroupHandle(handle_group) == group) { + handleAndGroup = handle_group; break; } } DEBUG_ASSERT(handleAndGroup != nullptr); // Register this channel alone with the chain slot. - registerInputChannel(*handleAndGroup); - enableForInputChannel(*handleAndGroup); + registerInputChannel(handleAndGroup); + enableForInputChannel(handleAndGroup); } diff --git a/src/effects/chains/standardeffectchain.cpp b/src/effects/chains/standardeffectchain.cpp index a2dc01d76647..093472c7c553 100644 --- a/src/effects/chains/standardeffectchain.cpp +++ b/src/effects/chains/standardeffectchain.cpp @@ -14,11 +14,11 @@ StandardEffectChain::StandardEffectChain(unsigned int iChainNumber, addEffectSlot(formatEffectSlotGroup(iChainNumber, i)); } - const QSet& registeredChannels = + const QSet& registeredChannels = m_pEffectsManager->registeredInputChannels(); - for (const ChannelHandleAndGroup& handle_group : registeredChannels) { + for (GroupHandle handle_group : registeredChannels) { int deckNumber; - if (PlayerManager::isDeckGroup(handle_group.name(), &deckNumber) && + if (PlayerManager::isDeckGroup(nameOfGroupHandle(handle_group), &deckNumber) && (iChainNumber + 1) == (unsigned)deckNumber) { registerInputChannel(handle_group, 1.0); } else { diff --git a/src/effects/effectchain.cpp b/src/effects/effectchain.cpp index 7d29850fea25..bec830738b86 100644 --- a/src/effects/effectchain.cpp +++ b/src/effects/effectchain.cpp @@ -281,26 +281,28 @@ int EffectChain::numPresets() const { return m_pChainPresetManager->numPresets(); } -void EffectChain::registerInputChannel(const ChannelHandleAndGroup& handleGroup, +void EffectChain::registerInputChannel(GroupHandle channelHandle, const double initialValue) { - VERIFY_OR_DEBUG_ASSERT(!m_channelEnableButtons.contains(handleGroup)) { + VERIFY_OR_DEBUG_ASSERT(!m_channelEnableButtons.contains(channelHandle)) { return; } auto pEnableControl = std::make_shared( - ConfigKey(m_group, QString("group_%1_enable").arg(handleGroup.name())), + ConfigKey(m_group, QString("group_%1_enable").arg(nameOfGroupHandle(channelHandle))), true, initialValue); - m_channelEnableButtons.insert(handleGroup, pEnableControl); + m_channelEnableButtons.insert(channelHandle, pEnableControl); pEnableControl->setButtonMode(ControlPushButton::POWERWINDOW); if (pEnableControl->toBool()) { - enableForInputChannel(handleGroup); + enableForInputChannel(channelHandle); } connect(pEnableControl.get(), &ControlObject::valueChanged, this, - [this, handleGroup](double value) { slotChannelStatusChanged(value, handleGroup); }); + [this, channelHandle](double value) { + slotChannelStatusChanged(value, channelHandle); + }); } EffectSlotPointer EffectChain::getEffectSlot(unsigned int slotNumber) { @@ -367,11 +369,11 @@ void EffectChain::slotControlPrevChainPreset(double value) { } void EffectChain::slotChannelStatusChanged( - double value, const ChannelHandleAndGroup& handleGroup) { + double value, GroupHandle channelHandle) { if (value > 0) { - enableForInputChannel(handleGroup); + enableForInputChannel(channelHandle); } else { - disableForInputChannel(handleGroup); + disableForInputChannel(channelHandle); } } @@ -386,15 +388,15 @@ void EffectChain::slotPresetListUpdated() { m_pControlNumChainPresets->forceSet(numPresets()); } -void EffectChain::enableForInputChannel(const ChannelHandleAndGroup& handleGroup) { - if (m_enabledInputChannels.contains(handleGroup)) { +void EffectChain::enableForInputChannel(GroupHandle channelHandle) { + if (m_enabledInputChannels.contains(channelHandle)) { return; } EffectsRequest* request = new EffectsRequest(); request->type = EffectsRequest::ENABLE_EFFECT_CHAIN_FOR_INPUT_CHANNEL; request->pTargetChain = m_pEngineEffectChain; - request->EnableInputChannelForChain.channelHandle = handleGroup.handle(); + request->EnableInputChannelForChain.channelHandle = channelHandle; // Allocate EffectStates here in the main thread to avoid allocating // memory in the realtime audio callback thread. Pointers to the @@ -417,18 +419,18 @@ void EffectChain::enableForInputChannel(const ChannelHandleAndGroup& handleGroup m_pMessenger->writeRequest(request); - m_enabledInputChannels.insert(handleGroup); + m_enabledInputChannels.insert(channelHandle); } -void EffectChain::disableForInputChannel(const ChannelHandleAndGroup& handleGroup) { - if (!m_enabledInputChannels.remove(handleGroup)) { +void EffectChain::disableForInputChannel(GroupHandle channelHandle) { + if (!m_enabledInputChannels.remove(channelHandle)) { return; } EffectsRequest* request = new EffectsRequest(); request->type = EffectsRequest::DISABLE_EFFECT_CHAIN_FOR_INPUT_CHANNEL; request->pTargetChain = m_pEngineEffectChain; - request->DisableInputChannelForChain.channelHandle = handleGroup.handle(); + request->DisableInputChannelForChain.channelHandle = channelHandle; m_pMessenger->writeRequest(request); } diff --git a/src/effects/effectchain.h b/src/effects/effectchain.h index 42e5dd33218c..f02dd1d17431 100644 --- a/src/effects/effectchain.h +++ b/src/effects/effectchain.h @@ -10,7 +10,6 @@ #include "effects/defs.h" #include "effects/effectchainmixmode.h" #include "effects/presets/effectchainpreset.h" -#include "engine/channelhandle.h" #include "util/class.h" #include "util/memory.h" @@ -48,11 +47,11 @@ class EffectChain : public QObject { EffectSlotPointer getEffectSlot(unsigned int slotNumber); - void registerInputChannel(const ChannelHandleAndGroup& handleGroup, + void registerInputChannel(GroupHandle channelHandle, const double initialValue = 0.0); /// Do not store this in EffectSlot! The enabled input channels are a property /// of the chain, not the effect. - const QSet& getActiveChannels() const { + const QSet& getActiveChannels() const { return m_enabledInputChannels; } @@ -94,8 +93,8 @@ class EffectChain : public QObject { virtual int numPresets() const; // Activates EffectChain processing for the provided channel. - void enableForInputChannel(const ChannelHandleAndGroup& handleGroup); - void disableForInputChannel(const ChannelHandleAndGroup& handleGroup); + void enableForInputChannel(GroupHandle channelHandle); + void disableForInputChannel(GroupHandle channelHandle); // Protected so QuickEffectChain can use the separate QuickEffect // chain preset list. @@ -120,7 +119,7 @@ class EffectChain : public QObject { void slotControlChainPresetSelector(double value); void slotControlNextChainPreset(double value); void slotControlPrevChainPreset(double value); - void slotChannelStatusChanged(double value, const ChannelHandleAndGroup& handleGroup); + void slotChannelStatusChanged(double value, GroupHandle channelHandle); private: QString debugString() const { @@ -155,8 +154,8 @@ class EffectChain : public QObject { std::unique_ptr m_pControlChainFocusedEffect; SignalProcessingStage m_signalProcessingStage; - QHash> m_channelEnableButtons; - QSet m_enabledInputChannels; + QHash> m_channelEnableButtons; + QSet m_enabledInputChannels; EngineEffectChain* m_pEngineEffectChain; DISALLOW_COPY_AND_ASSIGN(EffectChain); diff --git a/src/effects/effectslot.cpp b/src/effects/effectslot.cpp index 1833da1fbc2a..b9c417b59264 100644 --- a/src/effects/effectslot.cpp +++ b/src/effects/effectslot.cpp @@ -201,7 +201,7 @@ void EffectSlot::fillEffectStatesMap(EffectStatesMap* pStatesMap) const { if (isLoaded()) { for (const auto& outputChannel : m_pEffectsManager->registeredOutputChannels()) { - pStatesMap->insert(outputChannel.handle(), + pStatesMap->insert(outputChannel, m_pEngineEffect->createState(engineParameters)); } } else { diff --git a/src/effects/effectslot.h b/src/effects/effectslot.h index 9fc0a5a6bce5..8ef46bf30b1d 100644 --- a/src/effects/effectslot.h +++ b/src/effects/effectslot.h @@ -14,7 +14,6 @@ #include "effects/effectknobparameterslot.h" #include "effects/effectparameter.h" #include "effects/presets/effectpreset.h" -#include "engine/channelhandle.h" #include "engine/effects/engineeffect.h" #include "engine/engine.h" #include "util/class.h" diff --git a/src/effects/effectsmanager.cpp b/src/effects/effectsmanager.cpp index 36c107e344db..3c9c0e187c38 100644 --- a/src/effects/effectsmanager.cpp +++ b/src/effects/effectsmanager.cpp @@ -22,10 +22,9 @@ const QString kEffectsXmlFile = QStringLiteral("effects.xml"); } // anonymous namespace EffectsManager::EffectsManager( - UserSettingsPointer pConfig, - std::shared_ptr pChannelHandleFactory) + UserSettingsPointer pConfig) : m_pConfig(pConfig), - m_pChannelHandleFactory(pChannelHandleFactory), + m_masterGroupHandle(getOrCreateGroupHandleByName("[Master]")), m_loEqFreq(ConfigKey("[Mixer Profile]", "LoEQFrequency"), 0., 22040), m_hiEqFreq(ConfigKey("[Mixer Profile]", "HiEQFrequency"), 0., 22040) { qRegisterMetaType("EffectChainMixMode"); @@ -74,7 +73,7 @@ void EffectsManager::setup() { readEffectsXml(); } -void EffectsManager::registerInputChannel(const ChannelHandleAndGroup& handle_group) { +void EffectsManager::registerInputChannel(GroupHandle handle_group) { VERIFY_OR_DEBUG_ASSERT(!m_registeredInputChannels.contains(handle_group)) { return; } @@ -88,7 +87,7 @@ void EffectsManager::registerInputChannel(const ChannelHandleAndGroup& handle_gr } } -void EffectsManager::registerOutputChannel(const ChannelHandleAndGroup& handle_group) { +void EffectsManager::registerOutputChannel(GroupHandle handle_group) { VERIFY_OR_DEBUG_ASSERT(!m_registeredOutputChannels.contains(handle_group)) { return; } diff --git a/src/effects/effectsmanager.h b/src/effects/effectsmanager.h index 2e45b2564055..561b02145a94 100644 --- a/src/effects/effectsmanager.h +++ b/src/effects/effectsmanager.h @@ -5,9 +5,9 @@ #include #include "control/controlpotmeter.h" +#include "control/grouphandle.h" #include "effects/backends/effectsbackendmanager.h" #include "effects/presets/effectchainpresetmanager.h" -#include "engine/channelhandle.h" #include "preferences/usersettings.h" #include "util/class.h" @@ -20,8 +20,7 @@ class EngineEffectsManager; /// responsible for specific parts of the effects system. class EffectsManager { public: - EffectsManager(UserSettingsPointer pConfig, - std::shared_ptr pChannelHandleFactory); + EffectsManager(UserSettingsPointer pConfig); virtual ~EffectsManager(); @@ -40,8 +39,8 @@ class EffectsManager { return m_pEngineEffectsManager; } - const ChannelHandle getMasterHandle() const { - return m_pChannelHandleFactory->getOrCreateHandle("[Master]"); + GroupHandle getMasterHandle() const { + return m_masterGroupHandle; } const EffectChainPresetManagerPointer getChainPresetManager() const { @@ -59,13 +58,13 @@ class EffectsManager { return m_pVisibleEffectsList; } - void registerInputChannel(const ChannelHandleAndGroup& handle_group); - const QSet& registeredInputChannels() const { + void registerInputChannel(GroupHandle handle_group); + const QSet& registeredInputChannels() const { return m_registeredInputChannels; } - void registerOutputChannel(const ChannelHandleAndGroup& handle_group); - const QSet& registeredOutputChannels() const { + void registerOutputChannel(GroupHandle handle_group); + const QSet& registeredOutputChannels() const { return m_registeredOutputChannels; } @@ -81,9 +80,12 @@ class EffectsManager { void readEffectsXml(); void saveEffectsXml(); - QSet m_registeredInputChannels; - QSet m_registeredOutputChannels; - UserSettingsPointer m_pConfig; + const UserSettingsPointer m_pConfig; + + const GroupHandle m_masterGroupHandle; + + QSet m_registeredInputChannels; + QSet m_registeredOutputChannels; QHash m_effectChainSlotsByGroup; QList m_standardEffectChains; @@ -92,7 +94,6 @@ class EffectsManager { QHash m_quickEffectChains; EffectsBackendManagerPointer m_pBackendManager; - std::shared_ptr m_pChannelHandleFactory; EngineEffectsManager* m_pEngineEffectsManager; EffectsMessengerPointer m_pMessenger; diff --git a/src/engine/channelhandle.h b/src/engine/channelhandle.h index e20a9e1583e2..937d7f7c0228 100644 --- a/src/engine/channelhandle.h +++ b/src/engine/channelhandle.h @@ -1,206 +1,54 @@ #pragma once -#include -#include #include -#include -#include -#include "util/assert.h" -#include "util/compatibility/qhash.h" +#include "control/grouphandle.h" -// ChannelHandle defines a unique identifier for channels of audio in the engine -// (e.g. headphone output, master output, deck 1, microphone 3). Previously we -// used the group string of the channel in the engine to uniquely identify it -// and key associative containers (e.g. QMap, QHash) but the downside to this is -// that we waste a lot of callback time hashing and re-hashing the strings. -// -// To solve this problem we introduce ChannelHandle, a thin wrapper around an -// integer. As engine channels are registered they are assigned a ChannelHandle -// starting at 0 and incrementing. The benefit to this scheme is that the hash -// and equality of ChannelHandles are simple to calculate and a QVarLengthArray -// can be used to create a fast associative container backed by a simple array -// (since the keys are numbered [0, num_channels]). +constexpr int kMaxExpectedChannelGroups = 256; -/// A wrapper around an integer handle. Used to uniquely identify and refer to -/// channels (headphone output, master output, deck 1, microphone 4, etc.) while -/// avoiding slow QString comparisons incurred when using the group. -/// -/// A helper class, ChannelHandleFactory, keeps a running count of handles that -/// have been assigned. -class ChannelHandle { - public: - ChannelHandle() : m_iHandle(-1) { - } - - inline bool valid() const { - return m_iHandle >= 0; - } - - inline int handle() const { - return m_iHandle; - } - - private: - ChannelHandle(int iHandle) - : m_iHandle(iHandle) { - } - - void setHandle(int iHandle) { - m_iHandle = iHandle; - } - - int m_iHandle; - - friend class ChannelHandleFactory; -}; - -inline bool operator>(const ChannelHandle& h1, const ChannelHandle& h2) { - return h1.handle() > h2.handle(); -} - -inline bool operator<(const ChannelHandle& h1, const ChannelHandle& h2) { - return h1.handle() < h2.handle(); -} - -inline bool operator==(const ChannelHandle& h1, const ChannelHandle& h2) { - return h1.handle() == h2.handle(); -} - -inline bool operator!=(const ChannelHandle& h1, const ChannelHandle& h2) { - return h1.handle() != h2.handle(); -} - -inline QDebug operator<<(QDebug stream, const ChannelHandle& h) { - stream << "ChannelHandle(" << h.handle() << ")"; - return stream; -} - -inline qhash_seed_t qHash( - const ChannelHandle& handle, - qhash_seed_t seed = 0) { - return qHash(handle.handle(), seed); -} - -// Convenience class that mimics QPair except with -// custom equality and hash methods that save the cost of touching the QString. -class ChannelHandleAndGroup { - public: - ChannelHandleAndGroup(const ChannelHandle& handle, const QString& name) - : m_handle(handle), - m_name(name) { - } - - inline const QString& name() const { - return m_name; - } - - inline ChannelHandle handle() const { - return m_handle; - } - - const ChannelHandle m_handle; - const QString m_name; -}; - -inline bool operator==(const ChannelHandleAndGroup& g1, const ChannelHandleAndGroup& g2) { - return g1.handle() == g2.handle(); -} - -inline bool operator!=(const ChannelHandleAndGroup& g1, const ChannelHandleAndGroup& g2) { - return g1.handle() != g2.handle(); -} - -inline QDebug operator<<(QDebug stream, const ChannelHandleAndGroup& g) { - stream << "ChannelHandleAndGroup(" << g.name() << "," << g.handle() << ")"; - return stream; -} - -inline qhash_seed_t qHash( - const ChannelHandleAndGroup& handleGroup, - qhash_seed_t seed = 0) { - return qHash(handleGroup.handle(), seed); -} - -// A helper class used by EngineMaster to assign ChannelHandles to channel group -// strings. Warning: ChannelHandles produced by different ChannelHandleFactory -// objects are not compatible and will produce incorrect results when compared, -// stored in the same container, etc. In practice we only use one instance in -// EngineMaster. -class ChannelHandleFactory { - public: - ChannelHandleFactory() : m_iNextHandle(0) { - } - - ChannelHandle getOrCreateHandle(const QString& group) { - ChannelHandle& handle = m_groupToHandle[group]; - if (!handle.valid()) { - handle.setHandle(m_iNextHandle++); - DEBUG_ASSERT(handle.valid()); - DEBUG_ASSERT(!m_handleToGroup.contains(handle)); - m_handleToGroup.insert(handle, group); - } - return handle; - } - - ChannelHandle handleForGroup(const QString& group) const { - return m_groupToHandle.value(group, ChannelHandle()); - } - - QString groupForHandle(const ChannelHandle& handle) const { - return m_handleToGroup.value(handle, QString()); - } - - private: - int m_iNextHandle; - QHash m_groupToHandle; - QHash m_handleToGroup; -}; - -typedef std::shared_ptr ChannelHandleFactoryPointer; - -// An associative container mapping ChannelHandle to a template type T. Backed -// by a QVarLengthArray with ChannelHandleMap::kMaxExpectedGroups pre-allocated -// entries. Insertions are amortized O(1) time (if less than kMaxExpectedGroups +// An associative container mapping GroupHandle to a template type T. Backed +// by a QVarLengthArray with ChannelHandleMap::kMaxExpectedChannelGroups pre-allocated +// entries. Insertions are amortized O(1) time (if less than kMaxExpectedChannelGroups // exist then no allocation will occur -- insertion is a mere copy). Lookups are // O(1) and quite fast -- a simple index into an array using the handle's // integer value. template class ChannelHandleMap { - static constexpr int kMaxExpectedGroups = 256; - typedef QVarLengthArray container_type; + typedef QVarLengthArray container_type; + public: - typedef typename QVarLengthArray::const_iterator const_iterator; - typedef typename QVarLengthArray::iterator iterator; + typedef typename QVarLengthArray::const_iterator const_iterator; + typedef typename QVarLengthArray::iterator iterator; ChannelHandleMap() : m_dummy{} { } - const T& at(const ChannelHandle& handle) const { - if (!handle.valid()) { + const T& at(GroupHandle handle) const { + const auto index = indexOfGroupHandle(handle); + if (index < 0) { return m_dummy; } - return m_data.at(handle.handle()); + DEBUG_ASSERT(index < m_data.size()); + return m_data.at(index); } - void insert(const ChannelHandle& handle, const T& value) { - if (!handle.valid()) { + void insert(GroupHandle handle, const T& value) { + const auto index = indexOfGroupHandle(handle); + if (index < 0) { return; } - - int iHandle = handle.handle(); - maybeExpand(iHandle + 1); - m_data[iHandle] = value; + maybeExpand(index + 1); + m_data[index] = value; } - T& operator[](const ChannelHandle& handle) { - if (!handle.valid()) { + T& operator[](GroupHandle handle) { + const auto index = indexOfGroupHandle(handle); + if (index < 0) { return m_dummy; } - int iHandle = handle.handle(); - maybeExpand(iHandle + 1); - return m_data[iHandle]; + maybeExpand(index + 1); + return m_data[index]; } void clear() { diff --git a/src/engine/channelmixer.cpp b/src/engine/channelmixer.cpp index 9a76a2c5a487..fe7f902eeee7 100644 --- a/src/engine/channelmixer.cpp +++ b/src/engine/channelmixer.cpp @@ -8,7 +8,7 @@ void ChannelMixer::applyEffectsAndMixChannels(const EngineMaster::GainCalculator const QVarLengthArray& activeChannels, QVarLengthArray* channelGainCache, CSAMPLE* pOutput, - const ChannelHandle& outputHandle, + GroupHandle outputHandle, unsigned int iBufferSize, unsigned int iSampleRate, EngineEffectsManager* pEngineEffectsManager) { @@ -34,7 +34,9 @@ void ChannelMixer::applyEffectsAndMixChannels(const EngineMaster::GainCalculator newGain = gainCalculator.getGain(pChannelInfo); } gainCache.m_gain = newGain; - pEngineEffectsManager->processPostFaderAndMix(pChannelInfo->m_handle, + DEBUG_ASSERT(pChannelInfo->m_pHandle); + pEngineEffectsManager->processPostFaderAndMix( + pChannelInfo->m_pHandle, outputHandle, pChannelInfo->m_pBuffer, pOutput, @@ -53,7 +55,7 @@ void ChannelMixer::applyEffectsInPlaceAndMixChannels( QVarLengthArray* channelGainCache, CSAMPLE* pOutput, - const ChannelHandle& outputHandle, + GroupHandle outputHandle, unsigned int iBufferSize, unsigned int iSampleRate, EngineEffectsManager* pEngineEffectsManager) { @@ -76,7 +78,9 @@ void ChannelMixer::applyEffectsInPlaceAndMixChannels( newGain = gainCalculator.getGain(pChannelInfo); } gainCache.m_gain = newGain; - pEngineEffectsManager->processPostFaderInPlace(pChannelInfo->m_handle, + DEBUG_ASSERT(pChannelInfo->m_pHandle); + pEngineEffectsManager->processPostFaderInPlace( + pChannelInfo->m_pHandle, outputHandle, pChannelInfo->m_pBuffer, iBufferSize, diff --git a/src/engine/channelmixer.h b/src/engine/channelmixer.h index d65cb98ab92e..355cc203d195 100644 --- a/src/engine/channelmixer.h +++ b/src/engine/channelmixer.h @@ -18,7 +18,7 @@ class ChannelMixer { QVarLengthArray* channelGainCache, CSAMPLE* pOutput, - const ChannelHandle& outputHandle, + GroupHandle outputHandle, unsigned int iBufferSize, unsigned int iSampleRate, EngineEffectsManager* pEngineEffectsManager); @@ -30,7 +30,7 @@ class ChannelMixer { QVarLengthArray* channelGainCache, CSAMPLE* pOutput, - const ChannelHandle& outputHandle, + GroupHandle outputHandle, unsigned int iBufferSize, unsigned int iSampleRate, EngineEffectsManager* pEngineEffectsManager); diff --git a/src/engine/channels/engineaux.cpp b/src/engine/channels/engineaux.cpp index 99ff35631e47..0858b03fb2dd 100644 --- a/src/engine/channels/engineaux.cpp +++ b/src/engine/channels/engineaux.cpp @@ -10,8 +10,8 @@ #include "preferences/usersettings.h" #include "util/sample.h" -EngineAux::EngineAux(const ChannelHandleAndGroup& handleGroup, EffectsManager* pEffectsManager) - : EngineChannel(handleGroup, EngineChannel::CENTER, pEffectsManager, +EngineAux::EngineAux(GroupHandle groupHandle, EffectsManager* pEffectsManager) + : EngineChannel(groupHandle, EngineChannel::CENTER, pEffectsManager, /*isTalkoverChannel*/ false, /*isPrimaryDeck*/ false), m_pInputConfigured(new ControlObject(ConfigKey(getGroup(), "input_configured"))), @@ -78,7 +78,7 @@ void EngineAux::process(CSAMPLE* pOut, const int iBufferSize) { EngineEffectsManager* pEngineEffectsManager = m_pEffectsManager->getEngineEffectsManager(); if (pEngineEffectsManager != nullptr) { pEngineEffectsManager->processPreFaderInPlace( - m_group.handle(), m_pEffectsManager->getMasterHandle(), pOut, iBufferSize, + m_groupHandle, m_pEffectsManager->getMasterHandle(), pOut, iBufferSize, // TODO(jholthuis): Use mixxx::audio::SampleRate instead static_cast(m_pSampleRate->get())); } diff --git a/src/engine/channels/engineaux.h b/src/engine/channels/engineaux.h index aa6c8fe72e76..cfc0c4d59b3a 100644 --- a/src/engine/channels/engineaux.h +++ b/src/engine/channels/engineaux.h @@ -15,7 +15,7 @@ class ControlAudioTaperPot; class EngineAux : public EngineChannel, public AudioDestination { Q_OBJECT public: - EngineAux(const ChannelHandleAndGroup& handleGroup, EffectsManager* pEffectsManager); + EngineAux(GroupHandle groupHandle, EffectsManager* pEffectsManager); virtual ~EngineAux(); bool isActive(); diff --git a/src/engine/channels/enginechannel.cpp b/src/engine/channels/enginechannel.cpp index 3ff74f2c54af..eea888f4ced1 100644 --- a/src/engine/channels/enginechannel.cpp +++ b/src/engine/channels/enginechannel.cpp @@ -4,12 +4,12 @@ #include "control/controlpushbutton.h" #include "moc_enginechannel.cpp" -EngineChannel::EngineChannel(const ChannelHandleAndGroup& handleGroup, +EngineChannel::EngineChannel(GroupHandle groupHandle, EngineChannel::ChannelOrientation defaultOrientation, EffectsManager* pEffectsManager, bool isTalkoverChannel, bool isPrimaryDeck) - : m_group(handleGroup), + : m_groupHandle(groupHandle), m_pEffectsManager(pEffectsManager), m_vuMeter(getGroup()), m_pSampleRate(new ControlProxy("[Master]", "samplerate")), @@ -38,7 +38,7 @@ EngineChannel::EngineChannel(const ChannelHandleAndGroup& handleGroup, m_pTalkover->setButtonMode(ControlPushButton::POWERWINDOW); if (m_pEffectsManager != nullptr) { - m_pEffectsManager->registerInputChannel(handleGroup); + m_pEffectsManager->registerInputChannel(groupHandle); } } diff --git a/src/engine/channels/enginechannel.h b/src/engine/channels/enginechannel.h index 6771447c1581..cac5324ce2ed 100644 --- a/src/engine/channels/enginechannel.h +++ b/src/engine/channels/enginechannel.h @@ -1,9 +1,9 @@ #pragma once #include "control/controlproxy.h" +#include "control/grouphandle.h" #include "effects/effectsmanager.h" #include "engine/engineobject.h" -#include "engine/channelhandle.h" #include "engine/enginevumeter.h" #include "preferences/usersettings.h" @@ -21,7 +21,7 @@ class EngineChannel : public EngineObject { RIGHT, }; - EngineChannel(const ChannelHandleAndGroup& handleGroup, + EngineChannel(GroupHandle groupHandle, ChannelOrientation defaultOrientation, EffectsManager* pEffectsManager, bool isTalkoverChannel, @@ -30,12 +30,12 @@ class EngineChannel : public EngineObject { virtual ChannelOrientation getOrientation() const; - inline ChannelHandle getHandle() const { - return m_group.handle(); + GroupHandle getHandle() const { + return m_groupHandle; } - const QString& getGroup() const { - return m_group.name(); + QString getGroup() const { + return nameOfGroupHandle(m_groupHandle); } virtual bool isActive() = 0; @@ -66,7 +66,7 @@ class EngineChannel : public EngineObject { } protected: - const ChannelHandleAndGroup m_group; + const GroupHandle m_groupHandle; EffectsManager* m_pEffectsManager; EngineVuMeter m_vuMeter; diff --git a/src/engine/channels/enginedeck.cpp b/src/engine/channels/enginedeck.cpp index de05794bca51..297c62ec6a70 100644 --- a/src/engine/channels/enginedeck.cpp +++ b/src/engine/channels/enginedeck.cpp @@ -11,13 +11,13 @@ #include "waveform/waveformwidgetfactory.h" EngineDeck::EngineDeck( - const ChannelHandleAndGroup& handleGroup, + GroupHandle groupHandle, UserSettingsPointer pConfig, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, EngineChannel::ChannelOrientation defaultOrientation, bool primaryDeck) - : EngineChannel(handleGroup, defaultOrientation, pEffectsManager, + : EngineChannel(groupHandle, defaultOrientation, pEffectsManager, /*isTalkoverChannel*/ false, primaryDeck), m_pConfig(pConfig), @@ -75,7 +75,7 @@ void EngineDeck::process(CSAMPLE* pOut, const int iBufferSize) { EngineEffectsManager* pEngineEffectsManager = m_pEffectsManager->getEngineEffectsManager(); if (pEngineEffectsManager != nullptr) { - pEngineEffectsManager->processPreFaderInPlace(m_group.handle(), + pEngineEffectsManager->processPreFaderInPlace(m_groupHandle, m_pEffectsManager->getMasterHandle(), pOut, iBufferSize, diff --git a/src/engine/channels/enginedeck.h b/src/engine/channels/enginedeck.h index a6bb982144c5..60be18ce6493 100644 --- a/src/engine/channels/enginedeck.h +++ b/src/engine/channels/enginedeck.h @@ -23,7 +23,7 @@ class EngineDeck : public EngineChannel, public AudioDestination { Q_OBJECT public: EngineDeck( - const ChannelHandleAndGroup& handleGroup, + GroupHandle groupHandle, UserSettingsPointer pConfig, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, diff --git a/src/engine/channels/enginemicrophone.cpp b/src/engine/channels/enginemicrophone.cpp index c7d41ac97507..1743f3ac5178 100644 --- a/src/engine/channels/enginemicrophone.cpp +++ b/src/engine/channels/enginemicrophone.cpp @@ -10,9 +10,9 @@ #include "preferences/usersettings.h" #include "util/sample.h" -EngineMicrophone::EngineMicrophone(const ChannelHandleAndGroup& handleGroup, +EngineMicrophone::EngineMicrophone(GroupHandle groupHandle, EffectsManager* pEffectsManager) - : EngineChannel(handleGroup, EngineChannel::CENTER, pEffectsManager, + : EngineChannel(groupHandle, EngineChannel::CENTER, pEffectsManager, /*isTalkoverChannel*/ true, /*isPrimaryDeck*/ false), m_pInputConfigured(new ControlObject(ConfigKey(getGroup(), "input_configured"))), @@ -78,7 +78,7 @@ void EngineMicrophone::process(CSAMPLE* pOut, const int iBufferSize) { EngineEffectsManager* pEngineEffectsManager = m_pEffectsManager->getEngineEffectsManager(); if (pEngineEffectsManager != nullptr) { pEngineEffectsManager->processPreFaderInPlace( - m_group.handle(), m_pEffectsManager->getMasterHandle(), pOut, iBufferSize, + m_groupHandle, m_pEffectsManager->getMasterHandle(), pOut, iBufferSize, // TODO(jholthuis): Use mixxx::audio::SampleRate instead static_cast(m_pSampleRate->get())); } diff --git a/src/engine/channels/enginemicrophone.h b/src/engine/channels/enginemicrophone.h index 282407d35752..b5e1252cf8ee 100644 --- a/src/engine/channels/enginemicrophone.h +++ b/src/engine/channels/enginemicrophone.h @@ -18,7 +18,7 @@ class ControlAudioTaperPot; class EngineMicrophone : public EngineChannel, public AudioDestination { Q_OBJECT public: - EngineMicrophone(const ChannelHandleAndGroup& handleGroup, + EngineMicrophone(GroupHandle groupHandle, EffectsManager* pEffectsManager); virtual ~EngineMicrophone(); diff --git a/src/engine/effects/engineeffect.cpp b/src/engine/effects/engineeffect.cpp index f84001a3fc02..b33b799328bd 100644 --- a/src/engine/effects/engineeffect.cpp +++ b/src/engine/effects/engineeffect.cpp @@ -6,9 +6,9 @@ EngineEffect::EngineEffect(EffectManifestPointer pManifest, EffectsBackendManagerPointer pBackendManager, - const QSet& activeInputChannels, - const QSet& registeredInputChannels, - const QSet& registeredOutputChannels) + const QSet& activeInputChannels, + const QSet& registeredInputChannels, + const QSet& registeredOutputChannels) : m_pManifest(pManifest), m_pProcessor(pBackendManager->createProcessor(pManifest)), m_parameters(pManifest->parameters().size()) { @@ -20,12 +20,12 @@ EngineEffect::EngineEffect(EffectManifestPointer pManifest, m_parametersById[param->id()] = pParameter; } - for (const ChannelHandleAndGroup& inputChannel : registeredInputChannels) { + for (GroupHandle inputChannel : registeredInputChannels) { ChannelHandleMap outputChannelMap; - for (const ChannelHandleAndGroup& outputChannel : registeredOutputChannels) { - outputChannelMap.insert(outputChannel.handle(), EffectEnableState::Disabled); + for (GroupHandle outputChannel : registeredOutputChannels) { + outputChannelMap.insert(outputChannel, EffectEnableState::Disabled); } - m_effectEnableStateForChannelMatrix.insert(inputChannel.handle(), outputChannelMap); + m_effectEnableStateForChannelMatrix.insert(inputChannel, outputChannelMap); } m_pProcessor->loadEngineEffectParameters(m_parametersById); @@ -53,7 +53,7 @@ EffectState* EngineEffect::createState(const mixxx::EngineParameters& enginePara return m_pProcessor->createState(engineParameters); } -void EngineEffect::loadStatesForInputChannel(ChannelHandle inputChannel, +void EngineEffect::loadStatesForInputChannel(GroupHandle inputChannel, EffectStatesMap* pStatesMap) { if (kEffectDebugOutput) { qDebug() << "EngineEffect::loadStatesForInputChannel" << this @@ -62,7 +62,7 @@ void EngineEffect::loadStatesForInputChannel(ChannelHandle inputChannel, m_pProcessor->loadStatesForInputChannel(inputChannel, pStatesMap); } -void EngineEffect::deleteStatesForInputChannel(ChannelHandle inputChannel) { +void EngineEffect::deleteStatesForInputChannel(GroupHandle inputChannel) { m_pProcessor->deleteStatesForInputChannel(inputChannel); } @@ -123,8 +123,9 @@ bool EngineEffect::processEffectsRequest(EffectsRequest& message, return false; } -bool EngineEffect::process(const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, +bool EngineEffect::process( + GroupHandle inputHandle, + GroupHandle outputHandle, const CSAMPLE* pInput, CSAMPLE* pOutput, const unsigned int numSamples, @@ -214,7 +215,8 @@ bool EngineEffect::process(const ChannelHandle& inputHandle, // Now that the EffectProcessor has been sent the intermediate enabling/disabling // signal, set the channel state to fully enabled/disabled for the next engine callback. - EffectEnableState& effectOnChannelState = m_effectEnableStateForChannelMatrix[inputHandle][outputHandle]; + EffectEnableState& effectOnChannelState = + m_effectEnableStateForChannelMatrix[inputHandle][outputHandle]; if (effectOnChannelState == EffectEnableState::Disabling) { effectOnChannelState = EffectEnableState::Disabled; } else if (effectOnChannelState == EffectEnableState::Enabling) { diff --git a/src/engine/effects/engineeffect.h b/src/engine/effects/engineeffect.h index ea83a6fbc158..7367cbe1ac42 100644 --- a/src/engine/effects/engineeffect.h +++ b/src/engine/effects/engineeffect.h @@ -25,9 +25,9 @@ class EngineEffect final : public EffectsRequestHandler { /// Called in main thread by EffectSlot EngineEffect(EffectManifestPointer pManifest, EffectsBackendManagerPointer pBackendManager, - const QSet& activeInputChannels, - const QSet& registeredInputChannels, - const QSet& registeredOutputChannels); + const QSet& activeInputChannels, + const QSet& registeredInputChannels, + const QSet& registeredOutputChannels); /// Called in main thread by EffectSlot ~EngineEffect(); @@ -35,10 +35,10 @@ class EngineEffect final : public EffectsRequestHandler { EffectState* createState(const mixxx::EngineParameters& engineParameters); /// Called in audio thread to load EffectStates received from the main thread - void loadStatesForInputChannel(ChannelHandle inputChannel, + void loadStatesForInputChannel(GroupHandle inputChannel, EffectStatesMap* pStatesMap); /// Called from the main thread for garbage collection after an input channel is disabled - void deleteStatesForInputChannel(ChannelHandle inputChannel); + void deleteStatesForInputChannel(GroupHandle inputChannel); /// Called in audio thread bool processEffectsRequest( @@ -46,8 +46,8 @@ class EngineEffect final : public EffectsRequestHandler { EffectsResponsePipe* pResponsePipe) override; /// Called in audio thread - bool process(const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + bool process(GroupHandle inputHandle, + GroupHandle outputHandle, const CSAMPLE* pInput, CSAMPLE* pOutput, const unsigned int numSamples, diff --git a/src/engine/effects/engineeffectchain.cpp b/src/engine/effects/engineeffectchain.cpp index 5aea2ad2b02d..d5ec0d8ecc80 100644 --- a/src/engine/effects/engineeffectchain.cpp +++ b/src/engine/effects/engineeffectchain.cpp @@ -5,8 +5,8 @@ #include "util/sample.h" EngineEffectChain::EngineEffectChain(const QString& group, - const QSet& registeredInputChannels, - const QSet& registeredOutputChannels) + const QSet& registeredInputChannels, + const QSet& registeredOutputChannels) : m_group(group), m_enableState(EffectEnableState::Enabled), m_mixMode(EffectChainMixMode::DrySlashWet), @@ -16,12 +16,12 @@ EngineEffectChain::EngineEffectChain(const QString& group, // Try to prevent memory allocation. m_effects.reserve(256); - for (const ChannelHandleAndGroup& inputChannel : registeredInputChannels) { + for (GroupHandle inputChannel : registeredInputChannels) { ChannelHandleMap outputChannelMap; - for (const ChannelHandleAndGroup& outputChannel : registeredOutputChannels) { - outputChannelMap.insert(outputChannel.handle(), ChannelStatus()); + for (GroupHandle outputChannel : registeredOutputChannels) { + outputChannelMap.insert(outputChannel, ChannelStatus()); } - m_chainStatusForChannelMatrix.insert(inputChannel.handle(), outputChannelMap); + m_chainStatusForChannelMatrix.insert(inputChannel, outputChannelMap); } } @@ -146,10 +146,10 @@ bool EngineEffectChain::processEffectsRequest(EffectsRequest& message, return true; } -bool EngineEffectChain::enableForInputChannel(ChannelHandle inputHandle, +bool EngineEffectChain::enableForInputChannel(GroupHandle inputHandle, EffectStatesMapArray* statesForEffectsInChain) { if (kEffectDebugOutput) { - qDebug() << "EngineEffectChain::enableForInputChannel" << this << inputHandle; + qDebug() << "EngineEffectChain::enableForInputChannel" << this << *inputHandle; } auto& outputMap = m_chainStatusForChannelMatrix[inputHandle]; for (auto&& outputChannelStatus : outputMap) { @@ -180,7 +180,7 @@ bool EngineEffectChain::enableForInputChannel(ChannelHandle inputHandle, return true; } -bool EngineEffectChain::disableForInputChannel(ChannelHandle inputHandle) { +bool EngineEffectChain::disableForInputChannel(GroupHandle inputHandle) { auto& outputMap = m_chainStatusForChannelMatrix[inputHandle]; for (auto&& outputChannelStatus : outputMap) { if (outputChannelStatus.enableState != EffectEnableState::Disabled) { @@ -195,7 +195,7 @@ bool EngineEffectChain::disableForInputChannel(ChannelHandle inputHandle) { } // Called from the main thread for garbage collection after an input channel is disabled -void EngineEffectChain::deleteStatesForInputChannel(const ChannelHandle inputChannel) { +void EngineEffectChain::deleteStatesForInputChannel(GroupHandle inputHandle) { // If an output channel is not presently being processed, for example when // PFL is not active, then process() cannot be relied upon to set this // chain's EffectEnableState from Disabling to Disabled. This must be done @@ -205,30 +205,31 @@ void EngineEffectChain::deleteStatesForInputChannel(const ChannelHandle inputCha // with an EffectState that has already been deleted and cause a crash. // Refer to https://bugs.launchpad.net/mixxx/+bug/1741213 // NOTE: ChannelHandleMap is like a map in that it associates an object with - // a ChannelHandle key, but it actually backed by a QVarLengthArray, not a + // a GroupHandle key, but it actually backed by a QVarLengthArray, not a // QMap. So it is okay that m_chainStatusForChannelMatrix may be // accessed concurrently in the audio engine thread in process(), // enableForInputChannel(), or disableForInputChannel(). - auto& outputMap = m_chainStatusForChannelMatrix[inputChannel]; + auto& outputMap = m_chainStatusForChannelMatrix[inputHandle]; for (auto&& outputChannelStatus : outputMap) { outputChannelStatus.enableState = EffectEnableState::Disabled; } for (EngineEffect* pEffect : qAsConst(m_effects)) { if (pEffect != nullptr) { - pEffect->deleteStatesForInputChannel(inputChannel); + pEffect->deleteStatesForInputChannel(inputHandle); } } } EngineEffectChain::ChannelStatus& EngineEffectChain::getChannelStatus( - const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle) { + GroupHandle inputHandle, + GroupHandle outputHandle) { ChannelStatus& status = m_chainStatusForChannelMatrix[inputHandle][outputHandle]; return status; } -bool EngineEffectChain::process(const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, +bool EngineEffectChain::process( + GroupHandle inputHandle, + GroupHandle outputHandle, CSAMPLE* pIn, CSAMPLE* pOut, const unsigned int numSamples, diff --git a/src/engine/effects/engineeffectchain.h b/src/engine/effects/engineeffectchain.h index 9bb5aa6ac355..e932c0ce1081 100644 --- a/src/engine/effects/engineeffectchain.h +++ b/src/engine/effects/engineeffectchain.h @@ -25,8 +25,8 @@ class EngineEffectChain final : public EffectsRequestHandler { public: /// called from main thread EngineEffectChain(const QString& group, - const QSet& registeredInputChannels, - const QSet& registeredOutputChannels); + const QSet& registeredInputChannels, + const QSet& registeredOutputChannels); /// called from main thread ~EngineEffectChain(); @@ -36,8 +36,9 @@ class EngineEffectChain final : public EffectsRequestHandler { EffectsResponsePipe* pResponsePipe) override; /// called from audio thread - bool process(const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + bool process( + GroupHandle inputHandle, + GroupHandle outputHandle, CSAMPLE* pIn, CSAMPLE* pOut, const unsigned int numSamples, @@ -45,7 +46,7 @@ class EngineEffectChain final : public EffectsRequestHandler { const GroupFeatureState& groupFeatures); /// called from main thread - void deleteStatesForInputChannel(const ChannelHandle channel); + void deleteStatesForInputChannel(GroupHandle inputHandle); private: struct ChannelStatus { @@ -64,14 +65,15 @@ class EngineEffectChain final : public EffectsRequestHandler { bool updateParameters(const EffectsRequest& message); bool addEffect(EngineEffect* pEffect, int iIndex); bool removeEffect(EngineEffect* pEffect, int iIndex); - bool enableForInputChannel(ChannelHandle inputHandle, + bool enableForInputChannel(GroupHandle inputHandle, EffectStatesMapArray* statesForEffectsInChain); - bool disableForInputChannel(ChannelHandle inputHandle); + bool disableForInputChannel(GroupHandle inputHandle); // Gets or creates a ChannelStatus entry in m_channelStatus for the provided // handle. - ChannelStatus& getChannelStatus(const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle); + ChannelStatus& getChannelStatus( + GroupHandle inputHandle, + GroupHandle outputHandle); QString m_group; EffectEnableState m_enableState; diff --git a/src/engine/effects/engineeffectsmanager.cpp b/src/engine/effects/engineeffectsmanager.cpp index 5dae585c537e..fb928f76deb2 100644 --- a/src/engine/effects/engineeffectsmanager.cpp +++ b/src/engine/effects/engineeffectsmanager.cpp @@ -94,8 +94,9 @@ void EngineEffectsManager::onCallbackStart() { } } -void EngineEffectsManager::processPreFaderInPlace(const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, +void EngineEffectsManager::processPreFaderInPlace( + GroupHandle inputHandle, + GroupHandle outputHandle, CSAMPLE* pInOut, const unsigned int numSamples, const unsigned int sampleRate) { @@ -113,8 +114,8 @@ void EngineEffectsManager::processPreFaderInPlace(const ChannelHandle& inputHand } void EngineEffectsManager::processPostFaderInPlace( - const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + GroupHandle inputHandle, + GroupHandle outputHandle, CSAMPLE* pInOut, const unsigned int numSamples, const unsigned int sampleRate, @@ -134,8 +135,8 @@ void EngineEffectsManager::processPostFaderInPlace( } void EngineEffectsManager::processPostFaderAndMix( - const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + GroupHandle inputHandle, + GroupHandle outputHandle, CSAMPLE* pIn, CSAMPLE* pOut, const unsigned int numSamples, @@ -157,8 +158,8 @@ void EngineEffectsManager::processPostFaderAndMix( void EngineEffectsManager::processInner( const SignalProcessingStage stage, - const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + GroupHandle inputHandle, + GroupHandle outputHandle, CSAMPLE* pIn, CSAMPLE* pOut, const unsigned int numSamples, @@ -174,7 +175,8 @@ void EngineEffectsManager::processInner( SampleUtil::applyRampingGain(pIn, oldGain, newGain, numSamples); for (EngineEffectChain* pChain : chains) { if (pChain) { - if (pChain->process(inputHandle, + if (pChain->process( + inputHandle, outputHandle, pIn, pOut, diff --git a/src/engine/effects/engineeffectsmanager.h b/src/engine/effects/engineeffectsmanager.h index 9eacda043c6b..b5e7db97961d 100644 --- a/src/engine/effects/engineeffectsmanager.h +++ b/src/engine/effects/engineeffectsmanager.h @@ -2,7 +2,6 @@ #include -#include "engine/channelhandle.h" #include "engine/effects/groupfeaturestate.h" #include "engine/effects/message.h" #include "util/fifo.h" @@ -30,8 +29,8 @@ class EngineEffectsManager final : public EffectsRequestHandler { /// Process the prefader EngineEffectChains on the pInOut buffer, modifying /// the contents of the input buffer. void processPreFaderInPlace( - const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + GroupHandle inputHandle, + GroupHandle outputHandle, CSAMPLE* pInOut, const unsigned int numSamples, const unsigned int sampleRate); @@ -39,8 +38,8 @@ class EngineEffectsManager final : public EffectsRequestHandler { /// Process the postfader EngineEffectChains on the pInOut buffer, modifying /// the contents of the input buffer. void processPostFaderInPlace( - const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + GroupHandle inputHandle, + GroupHandle outputHandle, CSAMPLE* pInOut, const unsigned int numSamples, const unsigned int sampleRate, @@ -54,8 +53,8 @@ class EngineEffectsManager final : public EffectsRequestHandler { /// buffer for every channel, which would potentially require allocation on the /// audio thread because ChannelMixer supports an arbitrary number of channels. void processPostFaderAndMix( - const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + GroupHandle inputHandle, + GroupHandle outputHandle, CSAMPLE* pIn, CSAMPLE* pOut, const unsigned int numSamples, @@ -84,8 +83,8 @@ class EngineEffectsManager final : public EffectsRequestHandler { // samples, so numSamples/2 left channel samples and numSamples/2 right // channel samples. void processInner(const SignalProcessingStage stage, - const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + GroupHandle inputHandle, + GroupHandle outputHandle, CSAMPLE* pIn, CSAMPLE* pOut, const unsigned int numSamples, diff --git a/src/engine/effects/message.h b/src/engine/effects/message.h index 880ea48f623b..145998da2c56 100644 --- a/src/engine/effects/message.h +++ b/src/engine/effects/message.h @@ -6,7 +6,6 @@ #include "effects/defs.h" #include "effects/effectchainmixmode.h" -#include "engine/channelhandle.h" #include "util/memory.h" #include "util/messagepipe.h" @@ -87,10 +86,10 @@ struct EffectsRequest { } RemoveEffectChain; struct { EffectStatesMapArray* pEffectStatesMapArray; - ChannelHandle channelHandle; + GroupHandle channelHandle; } EnableInputChannelForChain; struct { - ChannelHandle channelHandle; + GroupHandle channelHandle; } DisableInputChannelForChain; struct { EngineEffect* pEffect; diff --git a/src/engine/enginemaster.cpp b/src/engine/enginemaster.cpp index 31a9dc4c054d..272473e51b97 100644 --- a/src/engine/enginemaster.cpp +++ b/src/engine/enginemaster.cpp @@ -32,10 +32,8 @@ EngineMaster::EngineMaster( UserSettingsPointer pConfig, const QString& group, EffectsManager* pEffectsManager, - ChannelHandleFactoryPointer pChannelHandleFactory, bool bEnableSidechain) - : m_pChannelHandleFactory(pChannelHandleFactory), - m_pEngineEffectsManager(pEffectsManager->getEngineEffectsManager()), + : m_pEngineEffectsManager(pEffectsManager->getEngineEffectsManager()), m_masterGainOld(0.0), m_boothGainOld(0.0), m_headphoneMasterGainOld(0.0), @@ -433,7 +431,7 @@ void EngineMaster::process(const int iBufferSize) { m_activeHeadphoneChannels, &m_channelHeadphoneGainCache, m_pHead, - m_headphoneHandle.handle(), + m_headphoneHandle, m_iBufferSize, static_cast(m_sampleRate.value()), m_pEngineEffectsManager); @@ -451,8 +449,8 @@ void EngineMaster::process(const int iBufferSize) { headphoneFeatures = m_activeHeadphoneChannels.at(0)->m_features; } m_pEngineEffectsManager->processPostFaderInPlace( - m_headphoneHandle.handle(), - m_headphoneHandle.handle(), + m_headphoneHandle, + m_headphoneHandle, m_pHead, m_iBufferSize, static_cast(m_sampleRate.value()), @@ -467,7 +465,7 @@ void EngineMaster::process(const int iBufferSize) { m_activeTalkoverChannels, &m_channelTalkoverGainCache, m_pTalkover, - m_masterHandle.handle(), + m_masterHandle, m_iBufferSize, static_cast(m_sampleRate.value()), m_pEngineEffectsManager); @@ -477,8 +475,8 @@ void EngineMaster::process(const int iBufferSize) { GroupFeatureState busFeatures; if (m_pEngineEffectsManager) { m_pEngineEffectsManager->processPostFaderInPlace( - m_busTalkoverHandle.handle(), - m_masterHandle.handle(), + m_busTalkoverHandle, + m_masterHandle, m_pTalkover, m_iBufferSize, static_cast(m_sampleRate.value()), @@ -523,7 +521,7 @@ void EngineMaster::process(const int iBufferSize) { m_activeBusChannels[o], &m_channelMasterGainCache, // no [o] because the old gain follows an orientation switch m_pOutputBusBuffers[o], - m_masterHandle.handle(), + m_masterHandle, m_iBufferSize, static_cast(m_sampleRate.value()), m_pEngineEffectsManager); @@ -532,22 +530,22 @@ void EngineMaster::process(const int iBufferSize) { // Process crossfader orientation bus channel effects if (m_pEngineEffectsManager) { m_pEngineEffectsManager->processPostFaderInPlace( - m_busCrossfaderLeftHandle.handle(), - m_masterHandle.handle(), + m_busCrossfaderLeftHandle, + m_masterHandle, m_pOutputBusBuffers[EngineChannel::LEFT], m_iBufferSize, static_cast(m_sampleRate.value()), busFeatures); m_pEngineEffectsManager->processPostFaderInPlace( - m_busCrossfaderCenterHandle.handle(), - m_masterHandle.handle(), + m_busCrossfaderCenterHandle, + m_masterHandle, m_pOutputBusBuffers[EngineChannel::CENTER], m_iBufferSize, static_cast(m_sampleRate.value()), busFeatures); m_pEngineEffectsManager->processPostFaderInPlace( - m_busCrossfaderRightHandle.handle(), - m_masterHandle.handle(), + m_busCrossfaderRightHandle, + m_masterHandle, m_pOutputBusBuffers[EngineChannel::RIGHT], m_iBufferSize, static_cast(m_sampleRate.value()), @@ -718,8 +716,8 @@ void EngineMaster::process(const int iBufferSize) { masterFeatures.has_gain = true; masterFeatures.gain = m_pMasterGain->get(); m_pEngineEffectsManager->processPostFaderInPlace( - m_masterOutputHandle.handle(), - m_masterHandle.handle(), + m_masterOutputHandle, + m_masterHandle, m_pMaster, m_iBufferSize, static_cast(m_sampleRate.value()), @@ -777,8 +775,8 @@ void EngineMaster::applyMasterEffects() { GroupFeatureState masterFeatures; masterFeatures.has_gain = true; masterFeatures.gain = m_pMasterGain->get(); - m_pEngineEffectsManager->processPostFaderInPlace(m_masterHandle.handle(), - m_masterHandle.handle(), + m_pEngineEffectsManager->processPostFaderInPlace(m_masterHandle, + m_masterHandle, m_pMaster, m_iBufferSize, static_cast(m_sampleRate.value()), @@ -816,7 +814,7 @@ void EngineMaster::addChannel(EngineChannel* pChannel) { pChannel->setChannelIndex(pChannelInfo->m_index); pChannelInfo->m_pChannel = pChannel; const QString& group = pChannel->getGroup(); - pChannelInfo->m_handle = m_pChannelHandleFactory->getOrCreateHandle(group); + pChannelInfo->m_pHandle = getOrCreateGroupHandleByName(group); pChannelInfo->m_pVolumeControl = new ControlAudioTaperPot( ConfigKey(group, "volume"), -20, 0, 1); pChannelInfo->m_pVolumeControl->setDefaultValue(1.0); diff --git a/src/engine/enginemaster.h b/src/engine/enginemaster.h index 36164db2fd05..65ffcd2ec93d 100644 --- a/src/engine/enginemaster.h +++ b/src/engine/enginemaster.h @@ -41,7 +41,6 @@ class EngineMaster : public QObject, public AudioSource { EngineMaster(UserSettingsPointer pConfig, const QString& group, EffectsManager* pEffectsManager, - ChannelHandleFactoryPointer pChannelHandleFactory, bool bEnableSidechain); virtual ~EngineMaster(); @@ -49,9 +48,8 @@ class EngineMaster : public QObject, public AudioSource { // be called by SoundManager. const CSAMPLE* buffer(const AudioOutput& output) const; - ChannelHandleAndGroup registerChannelGroup(const QString& group) { - return ChannelHandleAndGroup( - m_pChannelHandleFactory->getOrCreateHandle(group), group); + GroupHandle registerChannelGroup(const QString& group) { + return getOrCreateGroupHandleByName(group); } // Register the sound I/O that does not correspond to any EngineChannel object @@ -109,18 +107,14 @@ class EngineMaster : public QObject, public AudioSource { CSAMPLE_GAIN getMasterGain(int channelIndex) const; struct ChannelInfo { - ChannelInfo(int index) - : m_pChannel(NULL), - m_pBuffer(NULL), - m_pVolumeControl(NULL), - m_pMuteControl(NULL), - m_index(index) { + explicit ChannelInfo(int index) + : m_index(index) { } - ChannelHandle m_handle; - EngineChannel* m_pChannel; - CSAMPLE* m_pBuffer; - ControlObject* m_pVolumeControl; - ControlPushButton* m_pMuteControl; + GroupHandle m_pHandle{}; + EngineChannel* m_pChannel{}; + CSAMPLE* m_pBuffer{}; + ControlObject* m_pVolumeControl{}; + ControlPushButton* m_pMuteControl{}; GroupFeatureState m_features; int m_index; }; @@ -262,7 +256,6 @@ class EngineMaster : public QObject, public AudioSource { // respective output. void processChannels(int iBufferSize); - ChannelHandleFactoryPointer m_pChannelHandleFactory; void applyMasterEffects(); void processHeadphones(const CSAMPLE_GAIN masterMixGainInHeadphones); bool sidechainMixRequired() const; @@ -336,13 +329,13 @@ class EngineMaster : public QObject, public AudioSource { CSAMPLE_GAIN m_headphoneGainOld; CSAMPLE_GAIN m_balleftOld; CSAMPLE_GAIN m_balrightOld; - const ChannelHandleAndGroup m_masterHandle; - const ChannelHandleAndGroup m_headphoneHandle; - const ChannelHandleAndGroup m_masterOutputHandle; - const ChannelHandleAndGroup m_busTalkoverHandle; - const ChannelHandleAndGroup m_busCrossfaderLeftHandle; - const ChannelHandleAndGroup m_busCrossfaderCenterHandle; - const ChannelHandleAndGroup m_busCrossfaderRightHandle; + const GroupHandle m_masterHandle; + const GroupHandle m_headphoneHandle; + const GroupHandle m_masterOutputHandle; + const GroupHandle m_busTalkoverHandle; + const GroupHandle m_busCrossfaderLeftHandle; + const GroupHandle m_busCrossfaderCenterHandle; + const GroupHandle m_busCrossfaderRightHandle; // Mix two Mono channels. This is useful for outdoor gigs ControlObject* m_pMasterMonoMixdown; diff --git a/src/main.cpp b/src/main.cpp index 16849a5bf052..dc05a157d372 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,6 +15,7 @@ #else #include "mixxxmainwindow.h" #endif +#include "control/grouphandle.h" #include "sources/soundsourceproxy.h" #include "util/cmdlineargs.h" #include "util/console.h" @@ -71,6 +72,9 @@ int runMixxx(MixxxApplication* pApp, const CmdlineArgs& args) { } } #endif + + DEBUG_ASSERT(pCoreServices.use_count() == 1); + return exitCode; } @@ -197,6 +201,10 @@ int main(int argc, char * argv[]) { int exitCode = runMixxx(&app, args); + // Avoid warnings about memory leaks by deleting all allocated + // group descriptors/handles before finally exiting the application. + resetAllGroupHandles(); + qDebug() << "Mixxx shutdown complete with code" << exitCode; mixxx::Logging::shutdown(); diff --git a/src/mixer/auxiliary.cpp b/src/mixer/auxiliary.cpp index 583c15a1ace5..697c8d3f60bf 100644 --- a/src/mixer/auxiliary.cpp +++ b/src/mixer/auxiliary.cpp @@ -14,7 +14,7 @@ Auxiliary::Auxiliary(PlayerManager* pParent, EngineMaster* pEngine, EffectsManager* pEffectsManager) : BasePlayer(pParent, group) { - ChannelHandleAndGroup channelGroup = pEngine->registerChannelGroup(group); + GroupHandle channelGroup = pEngine->registerChannelGroup(group); EngineAux* pAuxiliary = new EngineAux(channelGroup, pEffectsManager); pEngine->addChannel(pAuxiliary); AudioInput auxInput = AudioInput(AudioPath::AUXILIARY, 0, 2, index); diff --git a/src/mixer/basetrackplayer.cpp b/src/mixer/basetrackplayer.cpp index 8f9126fc8067..5d28a66ab879 100644 --- a/src/mixer/basetrackplayer.cpp +++ b/src/mixer/basetrackplayer.cpp @@ -43,17 +43,17 @@ BaseTrackPlayerImpl::BaseTrackPlayerImpl( EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, EngineChannel::ChannelOrientation defaultOrientation, - const ChannelHandleAndGroup& handleGroup, + GroupHandle groupHandle, bool defaultMaster, bool defaultHeadphones, bool primaryDeck) - : BaseTrackPlayer(pParent, handleGroup.name()), + : BaseTrackPlayer(pParent, nameOfGroupHandle(groupHandle)), m_pConfig(pConfig), m_pEngineMaster(pMixingEngine), m_pLoadedTrack(), m_replaygainPending(false), m_pChannelToCloneFrom(nullptr) { - m_pChannel = new EngineDeck(handleGroup, + m_pChannel = new EngineDeck(groupHandle, pConfig, pMixingEngine, pEffectsManager, diff --git a/src/mixer/basetrackplayer.h b/src/mixer/basetrackplayer.h index ba7b5ddcdf38..d893614ccc77 100644 --- a/src/mixer/basetrackplayer.h +++ b/src/mixer/basetrackplayer.h @@ -60,7 +60,7 @@ class BaseTrackPlayerImpl : public BaseTrackPlayer { EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, EngineChannel::ChannelOrientation defaultOrientation, - const ChannelHandleAndGroup& handleGroup, + GroupHandle groupHandle, bool defaultMaster, bool defaultHeadphones, bool primaryDeck); diff --git a/src/mixer/deck.cpp b/src/mixer/deck.cpp index bc24cf6878fc..954efc1e31ef 100644 --- a/src/mixer/deck.cpp +++ b/src/mixer/deck.cpp @@ -7,13 +7,13 @@ Deck::Deck(PlayerManager* pParent, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, EngineChannel::ChannelOrientation defaultOrientation, - const ChannelHandleAndGroup& handleGroup) + GroupHandle groupHandle) : BaseTrackPlayerImpl(pParent, pConfig, pMixingEngine, pEffectsManager, defaultOrientation, - handleGroup, + groupHandle, /*defaultMaster*/ true, /*defaultHeadphones*/ false, /*primaryDeck*/ true) { diff --git a/src/mixer/deck.h b/src/mixer/deck.h index 699a16dc1cc6..36766df7cd18 100644 --- a/src/mixer/deck.h +++ b/src/mixer/deck.h @@ -12,6 +12,6 @@ class Deck : public BaseTrackPlayerImpl { EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, EngineChannel::ChannelOrientation defaultOrientation, - const ChannelHandleAndGroup& handleGroup); + GroupHandle groupHandle); ~Deck() override = default; }; diff --git a/src/mixer/microphone.cpp b/src/mixer/microphone.cpp index d5a671428727..d0a43bdca774 100644 --- a/src/mixer/microphone.cpp +++ b/src/mixer/microphone.cpp @@ -14,7 +14,7 @@ Microphone::Microphone(PlayerManager* pParent, EngineMaster* pEngine, EffectsManager* pEffectsManager) : BasePlayer(pParent, group) { - ChannelHandleAndGroup channelGroup = pEngine->registerChannelGroup(group); + GroupHandle channelGroup = pEngine->registerChannelGroup(group); EngineMicrophone* pMicrophone = new EngineMicrophone(channelGroup, pEffectsManager); pEngine->addChannel(pMicrophone); diff --git a/src/mixer/playermanager.cpp b/src/mixer/playermanager.cpp index 40b741ba8601..27d4fe670926 100644 --- a/src/mixer/playermanager.cpp +++ b/src/mixer/playermanager.cpp @@ -389,9 +389,9 @@ void PlayerManager::addConfiguredDecks() { void PlayerManager::addDeckInner() { // Do not lock m_mutex here. - ChannelHandleAndGroup handleGroup = + GroupHandle groupHandle = m_pEngine->registerChannelGroup(groupForDeck(m_decks.count())); - VERIFY_OR_DEBUG_ASSERT(!m_players.contains(handleGroup.handle())) { + VERIFY_OR_DEBUG_ASSERT(!m_players.contains(groupHandle)) { return; } @@ -402,7 +402,7 @@ void PlayerManager::addDeckInner() { m_pEngine, m_pEffectsManager, deckIndex % 2 == 1 ? EngineChannel::RIGHT : EngineChannel::LEFT, - handleGroup); + groupHandle); connect(pDeck->getEngineDeck(), &EngineDeck::noPassthroughInputConfigured, this, @@ -423,7 +423,7 @@ void PlayerManager::addDeckInner() { &PlayerManager::slotAnalyzeTrack); } - m_players[handleGroup.handle()] = pDeck; + m_players[groupHandle] = pDeck; m_decks.append(pDeck); // Register the deck output with SoundManager. @@ -436,7 +436,7 @@ void PlayerManager::addDeckInner() { AudioInput(AudioInput::VINYLCONTROL, 0, 2, deckIndex), pEngineDeck); // Setup equalizer and QuickEffect chain for this deck. - m_pEffectsManager->addDeck(handleGroup.m_name); + m_pEffectsManager->addDeck(nameOfGroupHandle(groupHandle)); // Setup EQ ControlProxies used for resetting EQs on track load pDeck->setupEqControls(); @@ -455,9 +455,9 @@ void PlayerManager::addSampler() { void PlayerManager::addSamplerInner() { // Do not lock m_mutex here. - ChannelHandleAndGroup handleGroup = + GroupHandle groupHandle = m_pEngine->registerChannelGroup(groupForSampler(m_samplers.count())); - VERIFY_OR_DEBUG_ASSERT(!m_players.contains(handleGroup.handle())) { + VERIFY_OR_DEBUG_ASSERT(!m_players.contains(groupHandle)) { return; } @@ -469,7 +469,7 @@ void PlayerManager::addSamplerInner() { m_pEngine, m_pEffectsManager, orientation, - handleGroup); + groupHandle); if (m_pTrackAnalysisScheduler) { connect(pSampler, &BaseTrackPlayer::newTrackLoaded, @@ -481,7 +481,7 @@ void PlayerManager::addSamplerInner() { this, &PlayerManager::slotSaveEjectedTrack); - m_players[handleGroup.handle()] = pSampler; + m_players[groupHandle] = pSampler; m_samplers.append(pSampler); } @@ -492,9 +492,9 @@ void PlayerManager::addPreviewDeck() { void PlayerManager::addPreviewDeckInner() { // Do not lock m_mutex here. - ChannelHandleAndGroup handleGroup = m_pEngine->registerChannelGroup( + GroupHandle groupHandle = m_pEngine->registerChannelGroup( groupForPreviewDeck(m_previewDecks.count())); - VERIFY_OR_DEBUG_ASSERT(!m_players.contains(handleGroup.handle())) { + VERIFY_OR_DEBUG_ASSERT(!m_players.contains(groupHandle)) { return; } @@ -506,7 +506,7 @@ void PlayerManager::addPreviewDeckInner() { m_pEngine, m_pEffectsManager, orientation, - handleGroup); + groupHandle); if (m_pTrackAnalysisScheduler) { connect(pPreviewDeck, &BaseTrackPlayer::newTrackLoaded, @@ -514,7 +514,7 @@ void PlayerManager::addPreviewDeckInner() { &PlayerManager::slotAnalyzeTrack); } - m_players[handleGroup.handle()] = pPreviewDeck; + m_players[groupHandle] = pPreviewDeck; m_previewDecks.append(pPreviewDeck); } @@ -560,14 +560,14 @@ void PlayerManager::addAuxiliaryInner() { } BaseTrackPlayer* PlayerManager::getPlayer(const QString& group) const { - return getPlayer(m_pEngine->registerChannelGroup(group).handle()); + return getPlayer(m_pEngine->registerChannelGroup(group)); } -BaseTrackPlayer* PlayerManager::getPlayer(const ChannelHandle& handle) const { +BaseTrackPlayer* PlayerManager::getPlayer(GroupHandle pHandle) const { const auto locker = lockMutex(&m_mutex); - if (m_players.contains(handle)) { - return m_players[handle]; + if (m_players.contains(pHandle)) { + return m_players[pHandle]; } return nullptr; } diff --git a/src/mixer/playermanager.h b/src/mixer/playermanager.h index bfcc7368a925..bf2961b8e950 100644 --- a/src/mixer/playermanager.h +++ b/src/mixer/playermanager.h @@ -7,6 +7,7 @@ #include #include "analyzer/trackanalysisscheduler.h" +#include "control/grouphandle.h" #include "engine/channelhandle.h" #include "library/library.h" #include "library/trackcollectionmanager.h" @@ -36,7 +37,7 @@ class PlayerManagerInterface { virtual ~PlayerManagerInterface() = default; virtual BaseTrackPlayer* getPlayer(const QString& group) const = 0; - virtual BaseTrackPlayer* getPlayer(const ChannelHandle& channelHandle) const = 0; + virtual BaseTrackPlayer* getPlayer(GroupHandle groupHandle) const = 0; // Get the deck by its deck number. Decks are numbered starting with 1. virtual Deck* getDeck(unsigned int player) const = 0; @@ -102,7 +103,7 @@ class PlayerManager : public QObject, public PlayerManagerInterface { // Auxiliaries and microphones are not players. BaseTrackPlayer* getPlayer(const QString& group) const override; // Get a BaseTrackPlayer (Deck, Sampler or PreviewDeck) by its handle. - BaseTrackPlayer* getPlayer(const ChannelHandle& handle) const override; + BaseTrackPlayer* getPlayer(GroupHandle pHandle) const override; // Get the deck by its deck number. Decks are numbered starting with 1. Deck* getDeck(unsigned int player) const override; @@ -293,5 +294,5 @@ class PlayerManager : public QObject, public PlayerManagerInterface { QList m_previewDecks; QList m_microphones; QList m_auxiliaries; - QMap m_players; + QMap m_players; }; diff --git a/src/mixer/previewdeck.cpp b/src/mixer/previewdeck.cpp index aa2deb76783a..e63e7fd2c61f 100644 --- a/src/mixer/previewdeck.cpp +++ b/src/mixer/previewdeck.cpp @@ -7,13 +7,13 @@ PreviewDeck::PreviewDeck(PlayerManager* pParent, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, EngineChannel::ChannelOrientation defaultOrientation, - const ChannelHandleAndGroup& handleGroup) + GroupHandle groupHandle) : BaseTrackPlayerImpl(pParent, pConfig, pMixingEngine, pEffectsManager, defaultOrientation, - handleGroup, + groupHandle, /*defaultMaster*/ false, /*defaultHeadphones*/ true, /*primaryDeck*/ false) { diff --git a/src/mixer/previewdeck.h b/src/mixer/previewdeck.h index 82241a057edb..9bbdf6e4f77d 100644 --- a/src/mixer/previewdeck.h +++ b/src/mixer/previewdeck.h @@ -10,6 +10,6 @@ class PreviewDeck : public BaseTrackPlayerImpl { EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, EngineChannel::ChannelOrientation defaultOrientation, - const ChannelHandleAndGroup& handleGroup); + GroupHandle groupHandle); ~PreviewDeck() override = default; }; diff --git a/src/mixer/sampler.cpp b/src/mixer/sampler.cpp index 57482a36beea..3730c1c7c73d 100644 --- a/src/mixer/sampler.cpp +++ b/src/mixer/sampler.cpp @@ -8,13 +8,13 @@ Sampler::Sampler(PlayerManager* pParent, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, EngineChannel::ChannelOrientation defaultOrientation, - const ChannelHandleAndGroup& handleGroup) + GroupHandle groupHandle) : BaseTrackPlayerImpl(pParent, pConfig, pMixingEngine, pEffectsManager, defaultOrientation, - handleGroup, + groupHandle, /*defaultMaster*/ true, /*defaultHeadphones*/ false, /*primaryDeck*/ false) { diff --git a/src/mixer/sampler.h b/src/mixer/sampler.h index 28ea557cd383..b4094239b966 100644 --- a/src/mixer/sampler.h +++ b/src/mixer/sampler.h @@ -10,6 +10,6 @@ class Sampler : public BaseTrackPlayerImpl { EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, EngineChannel::ChannelOrientation defaultOrientation, - const ChannelHandleAndGroup& handleGroup); + GroupHandle groupHandle); ~Sampler() override = default; }; diff --git a/src/test/autodjprocessor_test.cpp b/src/test/autodjprocessor_test.cpp index debee56a448d..3e0820e076ec 100644 --- a/src/test/autodjprocessor_test.cpp +++ b/src/test/autodjprocessor_test.cpp @@ -132,7 +132,7 @@ class MockPlayerManager : public PlayerManagerInterface { } MOCK_CONST_METHOD1(getPlayer, BaseTrackPlayer*(const QString&)); - MOCK_CONST_METHOD1(getPlayer, BaseTrackPlayer*(const ChannelHandle&)); + MOCK_CONST_METHOD1(getPlayer, BaseTrackPlayer*(GroupHandle)); MOCK_CONST_METHOD1(getDeck, Deck*(unsigned int)); MOCK_CONST_METHOD1(getPreviewDeck, PreviewDeck*(unsigned int)); MOCK_CONST_METHOD1(getSampler, Sampler*(unsigned int)); diff --git a/src/test/baseeffecttest.h b/src/test/baseeffecttest.h index 25b33b0edc71..f7027d801655 100644 --- a/src/test/baseeffecttest.h +++ b/src/test/baseeffecttest.h @@ -33,17 +33,17 @@ class MockEffectProcessor : public EffectProcessor { } MOCK_METHOD3(initialize, - void(const QSet& activeInputChannels, - const QSet& registeredOutputChannels, + void(const QSet& activeInputChannels, + const QSet& registeredOutputChannels, const mixxx::EngineParameters& engineParameters)); MOCK_METHOD1(createState, EffectState*(const mixxx::EngineParameters& engineParameters)); MOCK_METHOD2(loadStatesForInputChannel, - bool(const ChannelHandle* inputChannel, + bool(GroupHandle inputChannel, const EffectStatesMap* pStatesMap)); - MOCK_METHOD1(deleteStatesForInputChannel, void(const ChannelHandle* inputChannel)); + MOCK_METHOD1(deleteStatesForInputChannel, void(GroupHandle inputChannel)); MOCK_METHOD7(process, - void(const ChannelHandle& inputHandle, - const ChannelHandle& outputHandle, + void(GroupHandle inputHandle, + GroupHandle outputHandle, const CSAMPLE* pInput, CSAMPLE* pOutput, const mixxx::EngineParameters& engineParameters, @@ -63,9 +63,8 @@ class MockEffectInstantiator : public EffectInstantiator { class BaseEffectTest : public MixxxTest { protected: BaseEffectTest() - : m_pChannelHandleFactory(std::make_shared()), - m_pTestBackend(nullptr), - m_pEffectsManager(new EffectsManager(nullptr, config(), m_pChannelHandleFactory)) { + : m_pTestBackend(nullptr), + m_pEffectsManager(new EffectsManager(nullptr, config())) { } void registerTestBackend() { @@ -75,8 +74,6 @@ class BaseEffectTest : public MixxxTest { void registerTestEffect(EffectManifestPointer pManifest, bool willAddToEngine); - ChannelHandleFactoryPointer m_pChannelHandleFactory; - // Deleted by EffectsManager. Do not delete. TestEffectBackend* m_pTestBackend; QScopedPointer m_pEffectsManager; diff --git a/src/test/channelhandle_test.cpp b/src/test/channelhandle_test.cpp index 4d85fbde9ecf..129b0a0981be 100644 --- a/src/test/channelhandle_test.cpp +++ b/src/test/channelhandle_test.cpp @@ -4,52 +4,42 @@ #include "engine/channelhandle.h" #include "test/mixxxtest.h" -namespace { +TEST(ChannelHandleTest, GroupHandle) { + resetAllGroupHandles(); -TEST(ChannelHandleTest, BasicUsage) { - ChannelHandleFactory factory; const QString group = "[Test]"; const QString group2 = "[Test2]"; - ChannelHandle nullHandle; - EXPECT_EQ(nullHandle, nullHandle); - EXPECT_FALSE(nullHandle.valid()); - - EXPECT_FALSE(factory.handleForGroup(group).valid()); - // The ChannelHandleFactory constructor creates handles for [Master] and [Headphone] - EXPECT_EQ(0, factory.getOrCreateHandle(group).handle()); - EXPECT_EQ(0, factory.getOrCreateHandle(group).handle()); - ChannelHandle testHandle = factory.handleForGroup(group); - EXPECT_TRUE(testHandle.valid()); - EXPECT_EQ(0, testHandle.handle()); - EXPECT_QSTRING_EQ(group, factory.groupForHandle(testHandle)); - EXPECT_NE(nullHandle, testHandle); - EXPECT_EQ(testHandle, testHandle); - - EXPECT_FALSE(factory.handleForGroup(group2).valid()); - EXPECT_EQ(1, factory.getOrCreateHandle(group2).handle()); - EXPECT_EQ(1, factory.getOrCreateHandle(group2).handle()); - ChannelHandle testHandle2 = factory.handleForGroup(group2); - EXPECT_TRUE(testHandle2.valid()); - EXPECT_EQ(1, testHandle2.handle()); - EXPECT_QSTRING_EQ(group2, factory.groupForHandle(testHandle2)); - EXPECT_NE(nullHandle, testHandle2); - EXPECT_EQ(testHandle2, testHandle2); - - EXPECT_NE(testHandle, testHandle2); + EXPECT_EQ(nullptr, getGroupHandleByName(group)); + EXPECT_EQ(0, indexOfGroupHandle(getOrCreateGroupHandleByName(group))); + EXPECT_EQ(0, indexOfGroupHandle(getOrCreateGroupHandleByName(group))); + GroupHandle testHandle = getGroupHandleByName(group); + EXPECT_NE(nullptr, testHandle); + EXPECT_EQ(0, indexOfGroupHandle(testHandle)); + EXPECT_QSTRING_EQ(group, nameOfGroupHandle(testHandle)); + EXPECT_EQ(*testHandle, *testHandle); + + EXPECT_EQ(nullptr, getGroupHandleByName(group2)); + EXPECT_EQ(1, indexOfGroupHandle(getOrCreateGroupHandleByName(group2))); + EXPECT_EQ(1, indexOfGroupHandle(getOrCreateGroupHandleByName(group2))); + GroupHandle testHandle2 = getGroupHandleByName(group2); + EXPECT_NE(nullptr, testHandle2); + EXPECT_EQ(1, indexOfGroupHandle(testHandle2)); + EXPECT_QSTRING_EQ(group2, nameOfGroupHandle(testHandle2)); + EXPECT_EQ(*testHandle2, *testHandle2); + + EXPECT_NE(*testHandle, *testHandle2); } TEST(ChannelHandleTest, ChannelHandleMap) { - ChannelHandleFactory factory; + resetAllGroupHandles(); - ChannelHandle test = factory.getOrCreateHandle("[Test]"); - EXPECT_TRUE(test.valid()); - ChannelHandle test2 = factory.getOrCreateHandle("[Test2]"); - EXPECT_TRUE(test2.valid()); + GroupHandle test = getOrCreateGroupHandleByName("[Test]"); + GroupHandle test2 = getOrCreateGroupHandleByName("[Test2]"); ChannelHandleMap map; - EXPECT_QSTRING_EQ(QString(), map.at(ChannelHandle())); + EXPECT_QSTRING_EQ(QString(), map.at(nullptr)); map.insert(test2, "bar"); EXPECT_QSTRING_EQ("bar", map.at(test2)); @@ -65,5 +55,3 @@ TEST(ChannelHandleTest, ChannelHandleMap) { map.insert(test, "foo"); EXPECT_QSTRING_EQ("foo", map.at(test)); } - -} // namespace diff --git a/src/test/enginemicrophonetest.cpp b/src/test/enginemicrophonetest.cpp index ccdedefb31b9..48b6ee2f890b 100644 --- a/src/test/enginemicrophonetest.cpp +++ b/src/test/enginemicrophonetest.cpp @@ -23,8 +23,8 @@ class EngineMicrophoneTest : public SignalPathTest { test = SampleUtil::alloc(outputLength); // No need for a real handle in this test. - m_pMicrophone = new EngineMicrophone( - ChannelHandleAndGroup(ChannelHandle(), "[Microphone]"), m_pEffectsManager); + const auto groupHandle = getOrCreateGroupHandleByName("[Microphone]"); + m_pMicrophone = new EngineMicrophone(groupHandle, m_pEffectsManager); m_pTalkover = ControlObject::getControl(ConfigKey("[Microphone]", "talkover")); } diff --git a/src/test/metaknob_link_test.cpp b/src/test/metaknob_link_test.cpp index d7805e1f1ca0..b4af29344fb5 100644 --- a/src/test/metaknob_link_test.cpp +++ b/src/test/metaknob_link_test.cpp @@ -69,9 +69,8 @@ class MetaLinkTest : public BaseEffectTest { itemPrefix + QString("_link_inverse"))); } - ChannelHandleFactory m_factory; - ChannelHandleAndGroup m_master; - ChannelHandleAndGroup m_headphone; + GroupHandle m_master; + GroupHandle m_headphone; EffectSlotPointer m_pEffectSlot; EffectChainSlotPointer m_pChainSlot; diff --git a/src/test/nativeeffects_test.cpp b/src/test/nativeeffects_test.cpp index 442a326ae949..9af26ebafd8e 100644 --- a/src/test/nativeeffects_test.cpp +++ b/src/test/nativeeffects_test.cpp @@ -4,6 +4,7 @@ #include #include "control/controlpotmeter.h" +#include "control/grouphandle.h" #include "effects/builtin/autopaneffect.h" #include "effects/builtin/bessel4lvmixeqeffect.h" #include "effects/builtin/bessel8lvmixeqeffect.h" @@ -16,7 +17,6 @@ #include "effects/builtin/moogladder4filtereffect.h" #include "effects/builtin/phasereffect.h" #include "effects/builtin/reverbeffect.h" -#include "engine/channelhandle.h" #include "engine/effects/groupfeaturestate.h" #include "test/baseeffecttest.h" #include "util/samplebuffer.h" @@ -35,12 +35,11 @@ void benchmarkBuiltInEffectDefaultParameters(const mixxx::EngineParameters& engi benchmark::State* pState, EffectsManager* pEffectsManager) { EffectManifestPointer pManifest = EffectType::getManifest(); - ChannelHandleFactory factory; - QSet activeInputChannels; + QSet activeInputChannels; QString channel1_group = QString("[Channel1]"); - ChannelHandle channel1 = factory.getOrCreateHandle(channel1_group); - ChannelHandleAndGroup handle_and_group(channel1, channel1_group); + GroupHandle channel1 = factory.getOrCreateHandle(channel1_group); + GroupHandle handle_and_group(channel1, channel1_group); pEffectsManager->registerInputChannel(handle_and_group); pEffectsManager->registerOutputChannel(handle_and_group); activeInputChannels.insert(handle_and_group); diff --git a/src/test/playermanagertest.cpp b/src/test/playermanagertest.cpp index c72c68a2a397..beb12301cc79 100644 --- a/src/test/playermanagertest.cpp +++ b/src/test/playermanagertest.cpp @@ -40,13 +40,11 @@ class PlayerManagerTest : public MixxxDbTest, SoundSourceProviderRegistration { void SetUp() override { // This setup mirrors coreservices -- it would be nice if we could use coreservices instead // but it does a lot of local disk / settings setup. - auto pChannelHandleFactory = std::make_shared(); - m_pEffectsManager = std::make_shared(m_pConfig, pChannelHandleFactory); + m_pEffectsManager = std::make_shared(m_pConfig); m_pEngine = std::make_shared( m_pConfig, "[Master]", m_pEffectsManager.get(), - pChannelHandleFactory, true); m_pSoundManager = std::make_shared(m_pConfig, m_pEngine.get()); m_pControlIndicatorTimer = std::make_shared(nullptr); diff --git a/src/test/signalpathtest.h b/src/test/signalpathtest.h index f74aa09697ef..7d3c121f7cff 100644 --- a/src/test/signalpathtest.h +++ b/src/test/signalpathtest.h @@ -53,12 +53,10 @@ class TestEngineMaster : public EngineMaster { TestEngineMaster(UserSettingsPointer _config, const QString& group, EffectsManager* pEffectsManager, - ChannelHandleFactoryPointer pChannelHandleFactory, bool bEnableSidechain) : EngineMaster(_config, group, pEffectsManager, - pChannelHandleFactory, bEnableSidechain) { m_pMasterEnabled->forceSet(1); m_pHeadphoneEnabled->forceSet(1); @@ -74,13 +72,11 @@ class BaseSignalPathTest : public MixxxTest, SoundSourceProviderRegistration { protected: BaseSignalPathTest() { m_pControlIndicatorTimer = std::make_unique(); - m_pChannelHandleFactory = std::make_shared(); m_pNumDecks = new ControlObject(ConfigKey(m_sMasterGroup, "num_decks")); - m_pEffectsManager = new EffectsManager(config(), m_pChannelHandleFactory); + m_pEffectsManager = new EffectsManager(config()); m_pEngineMaster = new TestEngineMaster(m_pConfig, m_sMasterGroup, m_pEffectsManager, - m_pChannelHandleFactory, false); m_pMixerDeck1 = new Deck(nullptr, @@ -245,7 +241,6 @@ class BaseSignalPathTest : public MixxxTest, SoundSourceProviderRegistration { m_pEngineMaster->process(kProcessBufferSize); } - ChannelHandleFactoryPointer m_pChannelHandleFactory; ControlObject* m_pNumDecks; std::unique_ptr m_pControlIndicatorTimer; EffectsManager* m_pEffectsManager;