MetaLinkTest() : m_master(m_factory.getOrCreateHandle("[Master]"), "[Master]"), m_headphone(m_factory.getOrCreateHandle("[Headphone]"), "[Headphone]") { mixxx::Time::setTestMode(true); mixxx::Time::setTestElapsedTime(mixxx::Duration::fromNanos(0)); m_pEffectsManager->registerInputChannel(m_master); m_pEffectsManager->registerInputChannel(m_headphone); registerTestBackend(); EffectChainPointer pChain(new EffectChain(m_pEffectsManager.data(), "org.mixxx.test.chain1")); int iRackNumber = 0; int iChainNumber = 0; int iEffectNumber = 0; StandardEffectRackPointer pRack = m_pEffectsManager->addStandardEffectRack(); m_pChainSlot = pRack->getEffectChainSlot(iChainNumber); m_pChainSlot->loadEffectChainToSlot(pChain); m_pEffectSlot = m_pChainSlot->getEffectSlot(iEffectNumber); QString group = StandardEffectRack::formatEffectSlotGroupString( iRackNumber, iChainNumber, iEffectNumber); EffectManifest manifest; manifest.setId("org.mixxx.test.effect"); manifest.setName("Test Effect"); manifest.setMetaknobDefault(0.0); EffectManifestParameter* low = manifest.addParameter(); low->setId("low"); low->setName(QObject::tr("Low")); low->setDescription(QObject::tr("Gain for Low Filter")); low->setControlHint(EffectManifestParameter::ControlHint::KNOB_LINEAR); low->setSemanticHint(EffectManifestParameter::SemanticHint::UNKNOWN); low->setUnitsHint(EffectManifestParameter::UnitsHint::UNKNOWN); low->setNeutralPointOnScale(0.25); low->setDefault(1.0); low->setMinimum(0); low->setMaximum(1.0); registerTestEffect(manifest, false); // Check the controls reflect the state of their loaded effect. EffectPointer pEffect = m_pEffectsManager->instantiateEffect(manifest.id()); m_pEffectSlot->loadEffect(pEffect, false); QString itemPrefix = EffectParameterSlot::formatItemPrefix(0); m_pControlValue.reset(new ControlProxy(group, itemPrefix)); m_pControlLinkType.reset(new ControlProxy(group, itemPrefix + QString("_link_type"))); m_pControlLinkInverse.reset(new ControlProxy(group, itemPrefix + QString("_link_inverse"))); }
void BaseEffectTest::registerTestEffect(const EffectManifest& manifest) { MockEffectProcessor* pProcessor = new MockEffectProcessor(); MockEffectInstantiator* pInstantiator = new MockEffectInstantiator(); EXPECT_CALL(*pInstantiator, instantiate(_, _)) .Times(1) .WillOnce(Return(pProcessor)); m_pTestBackend->registerEffect(manifest.id(), manifest, EffectInstantiatorPointer(pInstantiator)); }
TEST_F(EffectSlotTest, ControlsReflectSlotState) { EffectChainPointer pChain(new EffectChain(m_pEffectsManager.data(), "org.mixxx.test.chain1")); int iRackNumber = 0; int iChainNumber = 0; int iEffectNumber = 0; StandardEffectRackPointer pRack = m_pEffectsManager->addStandardEffectRack(); EffectChainSlotPointer pChainSlot = pRack->addEffectChainSlot(); // StandardEffectRack::addEffectChainSlot automatically adds 4 effect // slots. In the future we will probably remove this so this will just start // segfaulting. EffectSlotPointer pEffectSlot = pChainSlot->getEffectSlot(0); QString group = StandardEffectRack::formatEffectSlotGroupString( iRackNumber, iChainNumber, iEffectNumber); EffectManifest manifest; manifest.setId("org.mixxx.test.effect"); manifest.setName("Test Effect"); manifest.addParameter(); registerTestEffect(manifest, false); // Check the controls reflect the state of their loaded effect. EffectPointer pEffect = m_pEffectsManager->instantiateEffect(manifest.id()); // Enabled defaults to true in both effects and the slot. pEffect->setEnabled(false); EXPECT_DOUBLE_EQ(1.0, ControlObject::get(ConfigKey(group, "enabled"))); EXPECT_DOUBLE_EQ(0, ControlObject::get(ConfigKey(group, "num_parameters"))); pEffectSlot->loadEffect(pEffect); EXPECT_LE(0, ControlObject::get(ConfigKey(group, "enabled"))); EXPECT_DOUBLE_EQ(1, ControlObject::get(ConfigKey(group, "num_parameters"))); EXPECT_TRUE(pEffect->enabled()); // loaded is read-only. ControlObject::set(ConfigKey(group, "loaded"), 0.0); EXPECT_LE(0, ControlObject::get(ConfigKey(group, "loaded"))); // num_parameters is read-only. ControlObject::set(ConfigKey(group, "num_parameters"), 2.0); EXPECT_DOUBLE_EQ(1, ControlObject::get(ConfigKey(group, "num_parameters"))); }
TEST_F(MetaLinkTest, HalfLinkTakeover) { // An effect that is linked to half of a knob should be more tolerant of // takeover changes. m_pEffectSlot->slotEnabled(1.0); // We have to recreate the effect because we want a neutral point at // 0 or 1. QString group = StandardEffectRack::formatEffectSlotGroupString( 0, 0, 0); EffectManifest manifest; manifest.setId("org.mixxx.test.effect2"); manifest.setName("Test Effect2"); EffectManifestParameter* low = manifest.addParameter(); low->setId("low"); low->setName(QObject::tr("Low")); low->setDescription(QObject::tr("Gain for Low Filter (neutral at 1.0)")); low->setControlHint(EffectManifestParameter::ControlHint::KNOB_LINEAR); low->setSemanticHint(EffectManifestParameter::SemanticHint::UNKNOWN); low->setUnitsHint(EffectManifestParameter::UnitsHint::UNKNOWN); low->setNeutralPointOnScale(1.0); low->setDefault(1.0); low->setMinimum(0); low->setMaximum(1.0); registerTestEffect(manifest, false); // Check the controls reflect the state of their loaded effect. EffectPointer pEffect = m_pEffectsManager->instantiateEffect(manifest.id()); m_pEffectSlot->loadEffect(pEffect, false); QString itemPrefix = EffectParameterSlot::formatItemPrefix(0); m_pControlValue.reset(new ControlProxy(group, itemPrefix)); m_pControlLinkType.reset(new ControlProxy(group, itemPrefix + QString("_link_type"))); m_pControlLinkInverse.reset(new ControlProxy(group, itemPrefix + QString("_link_inverse"))); // OK now the actual test. // 1.5 is a bit of a magic number, but it's enough that a regular // linked control will fail the soft takeover test and not change the // value... double newParam = 0.5 - SoftTakeover::kDefaultTakeoverThreshold * 1.5; m_pEffectSlot->slotEffectMetaParameter(newParam); EXPECT_EQ(1.0, m_pControlValue->get()); // ...but that value is still within the tolerance of a linked-left // and linked-right control. So if we set the exact same newParam, // we should see the control change as expected. m_pEffectSlot->slotEffectMetaParameter(0.5); m_pControlValue->set(1.0); m_pControlLinkType->set( static_cast<double>(EffectManifestParameter::LinkType::LINKED_LEFT)); m_pEffectSlot->syncSofttakeover(); m_pEffectSlot->slotEffectMetaParameter(newParam); EXPECT_EQ(newParam * 2.0, m_pControlValue->get()); // This tolerance change should also work for linked-right controls. m_pEffectSlot->slotEffectMetaParameter(0.5); m_pControlValue->set(1.0); m_pControlLinkType->set( static_cast<double>(EffectManifestParameter::LinkType::LINKED_RIGHT)); m_pEffectSlot->syncSofttakeover(); newParam = 0.5 + SoftTakeover::kDefaultTakeoverThreshold * 1.5; m_pEffectSlot->slotEffectMetaParameter(newParam); EXPECT_FLOAT_EQ(0.0703125, m_pControlValue->get()); }