void FadeChannel_Test::ready() { FadeChannel ch; QVERIFY(ch.isReady() == false); ch.setReady(true); QVERIFY(ch.isReady() == true); }
uint qHash(const FadeChannel& key) { uint hash = key.fixture() << 16; hash = hash | (key.channel() & 0xFFFF); hash = hash & (~0U); return hash; }
void FadeChannel_Test::fadeTime() { FadeChannel ch; QVERIFY(ch.fadeTime() == 0); ch.setFadeTime(50); QVERIFY(ch.fadeTime() == 50); }
/***************************************************************************** * Helper Function *****************************************************************************/ void EFXFixture::setFadeChannel(quint32 nChannel, uchar val) { FadeChannel fc; fc.setFixture(doc(), head().fxi); fc.setChannel(nChannel); fc.setTarget(val); m_parent->m_fader->forceAdd(fc); }
void CueStack_Test::write() { QList<Universe*> ua; ua.append(new Universe(0, new GrandMaster())); CueStack cs(m_doc); Cue cue("One"); cue.setValue(0, 255); cue.setFadeInSpeed(100); cue.setFadeOutSpeed(200); cue.setDuration(300); cs.appendCue(cue); cue = Cue("Two"); cue.setValue(1, 255); cue.setFadeInSpeed(100); cue.setFadeOutSpeed(200); cue.setDuration(300); cs.appendCue(cue); cs.preRun(); QVERIFY(cs.m_fader != NULL); cs.write(ua); QCOMPARE(cs.currentIndex(), -1); cs.start(); cs.write(ua); QCOMPARE(cs.currentIndex(), -1); cs.nextCue(); QCOMPARE(cs.currentIndex(), -1); cs.write(ua); QCOMPARE(cs.currentIndex(), 0); QCOMPARE(cs.m_fader->channels().size(), 1); FadeChannel fc; fc.setChannel(0); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(0)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); cs.previousCue(); QCOMPARE(cs.currentIndex(), 0); cs.write(ua); QCOMPARE(cs.currentIndex(), 1); fc.setChannel(0); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(0)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(0)); fc.setChannel(1); QCOMPARE(cs.m_fader->channels()[fc].channel(), uint(1)); QCOMPARE(cs.m_fader->channels()[fc].target(), uchar(255)); MasterTimer mt(m_doc); cs.postRun(&mt); }
void EFXFixture::start(MasterTimer* timer, QList<Universe *> universes) { Q_UNUSED(universes); Q_UNUSED(timer); if (fadeIntensity() > 0 && m_started == false) { Fixture* fxi = doc()->fixture(head().fxi); Q_ASSERT(fxi != NULL); if (fxi->masterIntensityChannel(head().head) != QLCChannel::invalid()) { FadeChannel fc; fc.setFixture(doc(), head().fxi); fc.setChannel(fxi->masterIntensityChannel(head().head)); if (m_parent->overrideFadeInSpeed() != Function::defaultSpeed()) fc.setFadeTime(m_parent->overrideFadeInSpeed()); else fc.setFadeTime(m_parent->fadeInSpeed()); fc.setStart(0); fc.setCurrent(fc.start()); // Don't use intensity() multiplier because EFX's GenericFader takes care of that fc.setTarget(fadeIntensity()); // Fade channel up with EFX's own GenericFader to allow manual intensity control m_parent->m_fader->add(fc); } } m_started = true; }
void EFXFixture::stop(MasterTimer* timer, QList<Universe *> universes) { Q_UNUSED(universes); if (fadeIntensity() > 0 && m_started == true) { Fixture* fxi = doc()->fixture(head().fxi); Q_ASSERT(fxi != NULL); if (fxi->masterIntensityChannel(head().head) != QLCChannel::invalid()) { FadeChannel fc; fc.setFixture(doc(), head().fxi); fc.setChannel(fxi->masterIntensityChannel(head().head)); if (m_parent->overrideFadeOutSpeed() != Function::defaultSpeed()) fc.setFadeTime(m_parent->overrideFadeOutSpeed()); else fc.setFadeTime(m_parent->fadeOutSpeed()); fc.setStart(uchar(floor((float(fadeIntensity()) * intensity()) + 0.5))); fc.setCurrent(fc.start()); fc.setTarget(0); // Give zero-fading to MasterTimer because EFX will stop after this call timer->faderAdd(fc); // Remove the previously up-faded channel from EFX's internal fader to allow // MasterTimer's fader take HTP precedence. m_parent->m_fader->remove(fc); } } m_started = false; }
void FadeChannel_Test::target() { FadeChannel fch; QCOMPARE(fch.target(), uchar(0)); for (uint i = 0; i <= 255; i++) { fch.setTarget(i); QCOMPARE(fch.target(), uchar(i)); } }
void FadeChannel_Test::current() { FadeChannel fch; QCOMPARE(fch.current(), uchar(0)); for (uint i = 0; i <= 255; i++) { fch.setCurrent(i); QCOMPARE(fch.current(), uchar(i)); QCOMPARE(fch.current(0.4), uchar(floor((qreal(i) * 0.4) + 0.5))); } }
void CueStack::postRun(MasterTimer* timer) { qDebug() << Q_FUNC_INFO; Q_ASSERT(timer != NULL); Q_ASSERT(m_fader != NULL); // Bounce all intensity channels to MasterTimer's fader for zeroing QHashIterator <FadeChannel,FadeChannel> it(m_fader->channels()); while (it.hasNext() == true) { it.next(); FadeChannel fc = it.value(); if (fc.group(doc()) == QLCChannel::Intensity) { fc.setStart(fc.current(intensity())); fc.setTarget(0); fc.setElapsed(0); fc.setReady(false); fc.setFadeTime(fadeOutSpeed()); timer->fader()->add(fc); } } m_currentIndex = -1; delete m_fader; m_fader = NULL; emit currentCueChanged(m_currentIndex); emit stopped(); }
void EFXFixture_Test::stop() { QList<Universe*> ua; ua.append(new Universe(0, new GrandMaster())); MasterTimerStub mts(m_doc, ua); EFX e(m_doc); e.setFadeInSpeed(1000); e.setFadeOutSpeed(2000); EFXFixture* ef = new EFXFixture(&e); ef->setHead(GroupHead(0,0)); e.addFixture(ef); Fixture* fxi = m_doc->fixture(0); QVERIFY(fxi != NULL); e.preRun(&mts); // Not started yet ef->stop(&mts, ua); QCOMPARE(e.m_fader->m_channels.size(), 0); QCOMPARE(mts.fader()->m_channels.size(), 0); // Start ef->start(&mts, ua); QCOMPARE(e.m_fader->m_channels.size(), 1); FadeChannel fc; fc.setFixture(m_doc, fxi->id()); fc.setChannel(fxi->masterIntensityChannel()); QVERIFY(e.m_fader->m_channels.contains(fc) == true); // Then stop ef->stop(&mts, ua); QCOMPARE(e.m_fader->m_channels.size(), 0); // FadeChannels are handed over to MasterTimer's GenericFader QCOMPARE(mts.fader()->m_channels.size(), 1); QVERIFY(e.m_fader->m_channels.contains(fc) == false); QVERIFY(mts.m_fader->m_channels.contains(fc) == true); QCOMPARE(mts.m_fader->m_channels[fc].fadeTime(), uint(2000)); e.postRun(&mts, ua); }
void GenericDMXSource::writeDMX(MasterTimer* timer, QList<Universe *> ua) { Q_UNUSED(timer); m_mutex.lock(); QMutableMapIterator <QPair<quint32,quint32>,uchar> it(m_values); while (it.hasNext() == true && m_outputEnabled == true) { it.next(); FadeChannel fc; fc.setFixture(m_doc, it.key().first); fc.setChannel(it.key().second); QLCChannel::Group grp = fc.group(m_doc); quint32 address = fc.address(); quint32 universe = fc.universe(); if (address != QLCChannel::invalid()) ua[universe]->write(address, it.value()); if (grp != QLCChannel::Intensity) it.remove(); } m_mutex.unlock(); }
void GenericFader_Test::writeLoop() { UniverseArray ua(512); GenericFader fader(m_doc); FadeChannel fc; fc.setFixture(0); fc.setChannel(5); fc.setStart(0); fc.setTarget(250); fc.setFadeTime(1000); fader.add(fc); QCOMPARE(ua.preGMValues()[15], (char) 0); int expected = 0; for (int i = MasterTimer::tick(); i <= 1000; i += MasterTimer::tick()) { ua.zeroIntensityChannels(); fader.write(&ua); int actual = uchar(ua.preGMValues()[15]); expected += 5; QCOMPARE(actual, expected); } }
void GenericFader::add(const FadeChannel& ch) { QHash<FadeChannel,FadeChannel>::iterator channelIterator = m_channels.find(ch); if (channelIterator != m_channels.end()) { // perform a HTP check if (channelIterator.value().current() <= ch.current()) channelIterator.value() = ch; } else { m_channels.insert(ch, ch); } }
void EFXFixture_Test::start() { QList<Universe*> ua; ua.append(new Universe(0, new GrandMaster())); MasterTimerStub mts(m_doc, ua); EFX e(m_doc); e.setFadeInSpeed(1000); e.setFadeOutSpeed(2000); EFXFixture* ef = new EFXFixture(&e); ef->setHead(GroupHead(0,0)); e.addFixture(ef); Fixture* fxi = m_doc->fixture(0); QVERIFY(fxi != NULL); e.preRun(&mts); // Fade intensity == 0, no need to do fade-in ef->setFadeIntensity(0); ef->start(&mts, ua); QCOMPARE(e.m_fader->m_channels.size(), 0); ef->m_started = false; // Fade intensity > 0, need to do fade-in ef->setFadeIntensity(1); ef->start(&mts, ua); QCOMPARE(e.m_fader->m_channels.size(), 1); FadeChannel fc; fc.setFixture(m_doc, fxi->id()); fc.setChannel(fxi->masterIntensityChannel()); QVERIFY(e.m_fader->m_channels.contains(fc) == true); QCOMPARE(e.m_fader->m_channels[fc].fadeTime(), uint(1000)); e.postRun(&mts, ua); }
void EFXFixture_Test::start() { UniverseArray array(512 * 4); MasterTimerStub mts(m_doc, array); EFX e(m_doc); e.setFadeInSpeed(1000); e.setFadeOutSpeed(2000); EFXFixture* ef = new EFXFixture(&e); ef->setFixture(0); e.addFixture(ef); Fixture* fxi = m_doc->fixture(0); QVERIFY(fxi != NULL); e.preRun(&mts); // Fade intensity == 0, no need to do fade-in ef->setFadeIntensity(0); ef->start(&mts, &array); QCOMPARE(e.m_fader->m_channels.size(), 0); ef->m_started = false; // Fade intensity > 0, need to do fade-in ef->setFadeIntensity(1); ef->start(&mts, &array); QCOMPARE(e.m_fader->m_channels.size(), 1); FadeChannel fc; fc.setFixture(fxi->id()); fc.setChannel(fxi->masterIntensityChannel()); QVERIFY(e.m_fader->m_channels.contains(fc) == true); QCOMPARE(e.m_fader->m_channels[fc].fadeTime(), uint(1000)); e.postRun(&mts, &array); }
void FadeChannel_Test::address() { Doc doc(this); Fixture* fxi = new Fixture(&doc); fxi->setAddress(400); fxi->setChannels(5); doc.addFixture(fxi); FadeChannel fc; fc.setChannel(2); QCOMPARE(fc.address(), quint32(2)); fc.setFixture(&doc, fxi->id()); QCOMPARE(fc.address(), quint32(402)); fc.setFixture(&doc, 12345); QCOMPARE(fc.address(), QLCChannel::invalid()); }
void GenericFader_Test::writeZeroFade() { UniverseArray ua(512); GenericFader fader(m_doc); FadeChannel fc; fc.setFixture(0); fc.setChannel(5); fc.setStart(0); fc.setTarget(255); fc.setFadeTime(0); fader.add(fc); QCOMPARE(ua.preGMValues()[15], (char) 0); fader.write(&ua); QCOMPARE(ua.preGMValues()[15], (char) 255); }
void GenericFader_Test::adjustIntensity() { UniverseArray ua(512); GenericFader fader(m_doc); FadeChannel fc; // HTP channel fc.setFixture(0); fc.setChannel(5); fc.setStart(0); fc.setTarget(250); fc.setFadeTime(1000); fader.add(fc); // LTP channel fc.setChannel(0); fader.add(fc); qreal intensity = 0.5; fader.adjustIntensity(intensity); QCOMPARE(fader.intensity(), intensity); int expected = 0; for (int i = MasterTimer::tick(); i <= 1000; i += MasterTimer::tick()) { ua.zeroIntensityChannels(); fader.write(&ua); expected += 5; // GenericFader should apply intensity only to HTP channels int actual = uchar(ua.preGMValues()[15]); int expectedWithIntensity = floor((qreal(expected) * intensity) + 0.5); QVERIFY(actual == expectedWithIntensity); // No intensity adjustment on LTP channels actual = uchar(ua.preGMValues()[10]); QVERIFY(actual == expected); } }
void CueStack::writeDMX(MasterTimer* timer, QList<Universe*> ua) { Q_UNUSED(timer); if (isFlashing() == true && m_cues.size() > 0) { QHashIterator <uint,uchar> it(m_cues.first().values()); while (it.hasNext() == true) { it.next(); FadeChannel fc; fc.setChannel(it.key()); fc.setTarget(it.value()); int uni = floor(fc.channel() / 512); if (uni < ua.size()) ua[uni]->write(fc.channel() - (uni * 512), fc.target()); } } }
void RGBMatrix::insertStartValues(FadeChannel& fc) const { Q_ASSERT(m_fader != NULL); // To create a nice and smooth fade, get the starting value from // m_fader's existing FadeChannel (if any). Otherwise just assume // we're starting from zero. if (m_fader->channels().contains(fc) == true) { FadeChannel old = m_fader->channels()[fc]; fc.setCurrent(old.current()); fc.setStart(old.current()); } else { fc.setCurrent(0); fc.setStart(0); } // The channel is not ready yet fc.setReady(false); // Fade in speed is used for all non-zero targets if (fc.target() == 0) fc.setFadeTime(fadeOutSpeed()); else fc.setFadeTime(fadeInSpeed()); }
QMap <quint32,FadeChannel> ChaserRunner::createFadeChannels(const UniverseArray* universes, QMap <quint32,FadeChannel>& zeroChannels) const { QMap <quint32,FadeChannel> map; if (m_currentStep >= m_steps.size() || m_currentStep < 0) return map; Scene* scene = qobject_cast<Scene*> (m_steps.at(m_currentStep)); Q_ASSERT(scene != NULL); // Put all current channels to a map of channels that will be faded to zero. // If the same channels are added to the new channel map, they are removed // from this zero map. zeroChannels = m_channelMap; QListIterator <SceneValue> it(scene->values()); while (it.hasNext() == true) { SceneValue value(it.next()); Fixture* fxi = m_doc->fixture(value.fxi); if (fxi == NULL || fxi->channel(value.channel) == NULL) continue; FadeChannel channel; channel.setAddress(fxi->universeAddress() + value.channel); channel.setGroup(fxi->channel(value.channel)->group()); channel.setTarget(value.value); // Get starting value from universes. For HTP channels it's always 0. channel.setStart(uchar(universes->preGMValues()[channel.address()])); // Transfer last step's current value to current step's starting value. if (m_channelMap.contains(channel.address()) == true) channel.setStart(m_channelMap[channel.address()].current()); channel.setCurrent(channel.start()); // Append the channel to the channel map map[channel.address()] = channel; // Remove the channel from a map of to-be-zeroed channels since now it // has a new value to fade to. zeroChannels.remove(channel.address()); } // All channels that were present in the previous step but are not present // in the current step will go through this zeroing process. QMutableMapIterator <quint32,FadeChannel> zit(zeroChannels); while (zit.hasNext() == true) { zit.next(); FadeChannel& channel(zit.value()); if (channel.current() == 0 || channel.group() != QLCChannel::Intensity) { // Remove all non-HTP channels and such HTP channels that are // already at zero. There's nothing to do for them. zit.remove(); } else { // This HTP channel was present in the previous step, but is absent // in the current. It's nicer that we fade it back to zero, rather // than just let it drop straight to zero. channel.setStart(channel.current()); channel.setTarget(0); } } return map; }
void FadeChannel_Test::nextStep() { FadeChannel fc; fc.setStart(0); fc.setTarget(250); fc.setFadeTime(1000); for (int i = 5; i < 250; i += 5) { int value = fc.nextStep(MasterTimer::tick()); QCOMPARE(value, i); } fc.setCurrent(0); fc.setReady(false); fc.setFadeTime(0); fc.setElapsed(0); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(250)); fc.setCurrent(0); fc.setReady(false); fc.setFadeTime(MasterTimer::tick() / 5); fc.setElapsed(0); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(250)); fc.setCurrent(0); fc.setReady(false); fc.setFadeTime(1 * MasterTimer::tick()); fc.setElapsed(0); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(250)); fc.setCurrent(0); fc.setReady(false); fc.setFadeTime(2 * MasterTimer::tick()); fc.setElapsed(0); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(125)); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(250)); fc.setCurrent(0); fc.setReady(false); fc.setFadeTime(5 * MasterTimer::tick()); fc.setElapsed(0); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(50)); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(100)); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(150)); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(200)); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(250)); // Maximum elapsed() reached fc.setCurrent(0); fc.setTarget(255); fc.setReady(false); fc.setElapsed(UINT_MAX); fc.setFadeTime(5 * MasterTimer::tick()); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(255)); QCOMPARE(fc.elapsed(), UINT_MAX); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(255)); QCOMPARE(fc.elapsed(), UINT_MAX); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(255)); QCOMPARE(fc.elapsed(), UINT_MAX); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(255)); QCOMPARE(fc.elapsed(), UINT_MAX); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(255)); QCOMPARE(fc.elapsed(), UINT_MAX); // Channel marked as ready fc.setReady(true); fc.setElapsed(0); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(255)); QCOMPARE(fc.elapsed(), MasterTimer::tick() * 1); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(255)); QCOMPARE(fc.elapsed(), MasterTimer::tick() * 2); QCOMPARE(fc.nextStep(MasterTimer::tick()), uchar(255)); QCOMPARE(fc.elapsed(), MasterTimer::tick() * 3); }
void FadeChannel_Test::calculateCurrent() { FadeChannel fch; fch.setStart(0); fch.setTarget(255); // Simple: 255 ticks to fade from 0 to 255 for (uint time = 0; time < 255; time++) QCOMPARE(fch.calculateCurrent(255, time), uchar(time)); // Same thing, but the value should stay at 255 same after 255 ticks for (uint time = 0; time <= 512; time++) QCOMPARE(fch.calculateCurrent(255, time), uchar(MIN(time, 255))); // Simple reverse: 255 ticks to fade from 255 to 0 fch.setStart(255); fch.setTarget(0); for (uint time = 0; time <= 255; time++) QCOMPARE(fch.calculateCurrent(255, time), uchar(255 - time)); // A bit more complex involving decimals that don't produce round integers fch.setStart(13); fch.setTarget(147); QCOMPARE(fch.calculateCurrent(13, 0), uchar(13)); QCOMPARE(fch.calculateCurrent(13, 1), uchar(23)); QCOMPARE(fch.calculateCurrent(13, 2), uchar(33)); QCOMPARE(fch.calculateCurrent(13, 3), uchar(43)); QCOMPARE(fch.calculateCurrent(13, 4), uchar(54)); QCOMPARE(fch.calculateCurrent(13, 5), uchar(64)); QCOMPARE(fch.calculateCurrent(13, 6), uchar(74)); QCOMPARE(fch.calculateCurrent(13, 7), uchar(85)); QCOMPARE(fch.calculateCurrent(13, 8), uchar(95)); QCOMPARE(fch.calculateCurrent(13, 9), uchar(105)); QCOMPARE(fch.calculateCurrent(13, 10), uchar(116)); QCOMPARE(fch.calculateCurrent(13, 11), uchar(126)); QCOMPARE(fch.calculateCurrent(13, 12), uchar(136)); QCOMPARE(fch.calculateCurrent(13, 13), uchar(147)); // One more to check slower operation (200 ticks for 144 steps) fch.setStart(245); fch.setTarget(101); QCOMPARE(fch.calculateCurrent(200, 0), uchar(245)); QCOMPARE(fch.calculateCurrent(200, 1), uchar(245)); QCOMPARE(fch.calculateCurrent(200, 2), uchar(244)); QCOMPARE(fch.calculateCurrent(200, 3), uchar(243)); QCOMPARE(fch.calculateCurrent(200, 4), uchar(243)); QCOMPARE(fch.calculateCurrent(200, 5), uchar(242)); QCOMPARE(fch.calculateCurrent(200, 6), uchar(241)); QCOMPARE(fch.calculateCurrent(200, 7), uchar(240)); QCOMPARE(fch.calculateCurrent(200, 8), uchar(240)); QCOMPARE(fch.calculateCurrent(200, 9), uchar(239)); QCOMPARE(fch.calculateCurrent(200, 10), uchar(238)); QCOMPARE(fch.calculateCurrent(200, 11), uchar(238)); // Skip... QCOMPARE(fch.calculateCurrent(200, 100), uchar(173)); QCOMPARE(fch.calculateCurrent(200, 101), uchar(173)); QCOMPARE(fch.calculateCurrent(200, 102), uchar(172)); // Skip... QCOMPARE(fch.calculateCurrent(200, 198), uchar(103)); QCOMPARE(fch.calculateCurrent(200, 199), uchar(102)); QCOMPARE(fch.calculateCurrent(200, 200), uchar(101)); }
void CueStack::switchCue(int from, int to, const QList<Universe *> ua) { qDebug() << Q_FUNC_INFO; Cue newCue; Cue oldCue; m_mutex.lock(); if (to >= 0 && to < m_cues.size()) newCue = m_cues[to]; if (from >= 0 && from < m_cues.size()) oldCue = m_cues[from]; m_mutex.unlock(); // Fade out the HTP channels of the previous cue QHashIterator <uint,uchar> oldit(oldCue.values()); while (oldit.hasNext() == true) { oldit.next(); FadeChannel fc; fc.setFixture(doc(), Fixture::invalidId()); fc.setChannel(oldit.key()); if (fc.group(doc()) == QLCChannel::Intensity) { fc.setElapsed(0); fc.setReady(false); fc.setTarget(0); fc.setFadeTime(oldCue.fadeOutSpeed()); insertStartValue(fc, ua); m_fader->add(fc); } } // Fade in all channels of the new cue QHashIterator <uint,uchar> newit(newCue.values()); while (newit.hasNext() == true) { newit.next(); FadeChannel fc; fc.setFixture(doc(), Fixture::invalidId()); fc.setChannel(newit.key()); fc.setTarget(newit.value()); fc.setElapsed(0); fc.setReady(false); fc.setFadeTime(newCue.fadeInSpeed()); insertStartValue(fc, ua); m_fader->add(fc); } }
void RGBMatrix::postRun(MasterTimer* timer, QList<Universe *> universes) { if (m_fader != NULL) { QHashIterator <FadeChannel,FadeChannel> it(m_fader->channels()); while (it.hasNext() == true) { it.next(); FadeChannel fc = it.value(); // fade out only intensity channels if (fc.group(doc()) != QLCChannel::Intensity) continue; bool canFade = true; Fixture *fixture = doc()->fixture(fc.fixture()); if (fixture != NULL) canFade = fixture->channelCanFade(fc.channel()); fc.setStart(fc.current(getAttributeValue(Intensity))); fc.setCurrent(fc.current(getAttributeValue(Intensity))); fc.setElapsed(0); fc.setReady(false); if (canFade == false) { fc.setFadeTime(0); fc.setTarget(fc.current(getAttributeValue(Intensity))); } else { if (overrideFadeOutSpeed() == defaultSpeed()) fc.setFadeTime(fadeOutSpeed()); else fc.setFadeTime(overrideFadeOutSpeed()); fc.setTarget(0); } timer->faderAdd(fc); } delete m_fader; m_fader = NULL; } { QMutexLocker algorithmLocker(&m_algorithmMutex); if (m_algorithm != NULL) m_algorithm->postRun(); } Function::postRun(timer, universes); }
void RGBMatrix::updateMapChannels(const RGBMap& map, const FixtureGroup* grp) { quint32 mdAssigned = QLCChannel::invalid(); quint32 mdFxi = Fixture::invalidId(); uint fadeTime = 0; if (overrideFadeInSpeed() == defaultSpeed()) fadeTime = fadeInSpeed(); else fadeTime = overrideFadeInSpeed(); // Create/modify fade channels for ALL pixels in the color map. for (int y = 0; y < map.size(); y++) { for (int x = 0; x < map[y].size(); x++) { QLCPoint pt(x, y); GroupHead grpHead(grp->head(pt)); Fixture* fxi = doc()->fixture(grpHead.fxi); if (fxi == NULL) continue; if (grpHead.fxi != mdFxi) { mdAssigned = QLCChannel::invalid(); mdFxi = grpHead.fxi; } QLCFixtureHead head = fxi->head(grpHead.head); QVector <quint32> rgb = head.rgbChannels(); QVector <quint32> cmy = head.cmyChannels(); if (rgb.size() == 3) { // RGB color mixing FadeChannel fc; fc.setFixture(doc(), grpHead.fxi); fc.setChannel(rgb.at(0)); fc.setTarget(qRed(map[y][x])); insertStartValues(fc, fadeTime); m_fader->add(fc); fc.setChannel(rgb.at(1)); fc.setTarget(qGreen(map[y][x])); insertStartValues(fc, fadeTime); m_fader->add(fc); fc.setChannel(rgb.at(2)); fc.setTarget(qBlue(map[y][x])); insertStartValues(fc, fadeTime); m_fader->add(fc); } else if (cmy.size() == 3) { // CMY color mixing QColor col(map[y][x]); FadeChannel fc; fc.setFixture(doc(), grpHead.fxi); fc.setChannel(cmy.at(0)); fc.setTarget(col.cyan()); insertStartValues(fc, fadeTime); m_fader->add(fc); fc.setChannel(cmy.at(1)); fc.setTarget(col.magenta()); insertStartValues(fc, fadeTime); m_fader->add(fc); fc.setChannel(cmy.at(2)); fc.setTarget(col.yellow()); insertStartValues(fc, fadeTime); m_fader->add(fc); } if (m_dimmerControl && head.masterIntensityChannel() != QLCChannel::invalid()) { //qDebug() << "RGBMatrix: found dimmer at" << head.masterIntensityChannel(); // Simple intensity (dimmer) channel QColor col(map[y][x]); FadeChannel fc; fc.setFixture(doc(), grpHead.fxi); fc.setChannel(head.masterIntensityChannel()); if (col.value() == 0 && mdAssigned != head.masterIntensityChannel()) fc.setTarget(0); else { fc.setTarget(255); if (mdAssigned == QLCChannel::invalid()) mdAssigned = head.masterIntensityChannel(); } insertStartValues(fc, fadeTime); m_fader->add(fc); } } } }
void RGBMatrix::insertStartValues(FadeChannel& fc, uint fadeTime) const { Q_ASSERT(m_fader != NULL); // To create a nice and smooth fade, get the starting value from // m_fader's existing FadeChannel (if any). Otherwise just assume // we're starting from zero. QHash <FadeChannel,FadeChannel>::const_iterator oldChannelIterator = m_fader->channels().find(fc); if (oldChannelIterator != m_fader->channels().end()) { FadeChannel old = oldChannelIterator.value(); fc.setCurrent(old.current()); if (fc.target() == old.target()) { fc.setStart(old.start()); fc.setElapsed(old.elapsed()); } else fc.setStart(old.current()); } else { fc.setCurrent(0); fc.setStart(0); } // The channel is not ready yet fc.setReady(false); // Fade in speed is used for all non-zero targets if (fc.target() == 0) fc.setFadeTime(fadeOutSpeed()); else { fc.setFadeTime(fadeTime); } }
void CueStack::insertStartValue(FadeChannel& fc, const QList<Universe *> ua) { qDebug() << Q_FUNC_INFO; const QHash <FadeChannel,FadeChannel>& channels(m_fader->channels()); if (channels.contains(fc) == true) { // GenericFader contains the channel so grab its current // value as the new starting value to get a smoother fade FadeChannel existing = channels[fc]; fc.setStart(existing.current()); fc.setCurrent(fc.start()); } else { // GenericFader didn't have the channel. Grab the starting value from UniverseArray. quint32 uni = fc.universe(); if (uni != Universe::invalid() && uni < (quint32)ua.count()) { if (fc.group(doc()) != QLCChannel::Intensity) fc.setStart(ua[uni]->preGMValues()[fc.address()]); else fc.setStart(0); // HTP channels must start at zero } fc.setCurrent(fc.start()); } }
void FadeChannel_Test::group() { Doc doc(this); FadeChannel fc; // Only a channel given, no fixture at the address -> intensity fc.setChannel(2); QCOMPARE(fc.group(&doc), QLCChannel::Intensity); Fixture* fxi = new Fixture(&doc); fxi->setAddress(10); fxi->setChannels(5); doc.addFixture(fxi); // Fixture and channel given, fixture is a dimmer -> intensity fc.setFixture(&doc, fxi->id()); QCOMPARE(fc.group(&doc), QLCChannel::Intensity); QDir dir(INTERNAL_FIXTUREDIR); dir.setFilter(QDir::Files); dir.setNameFilters(QStringList() << QString("*%1").arg(KExtFixture)); QVERIFY(doc.fixtureDefCache()->load(dir) == true); QLCFixtureDef* def = doc.fixtureDefCache()->fixtureDef("Futurelight", "DJScan250"); QVERIFY(def != NULL); QLCFixtureMode* mode = def->modes().first(); QVERIFY(mode != NULL); fxi = new Fixture(&doc); fxi->setAddress(0); fxi->setFixtureDefinition(def, mode); doc.addFixture(fxi); // Fixture and channel given, but channel is beyond fixture's channels -> intensity fc.setFixture(&doc, fxi->id()); fc.setChannel(50); QCOMPARE(fc.group(&doc), QLCChannel::Intensity); // Only a channel given, no fixture given but a fixture occupies the address. // Check that reverse address -> fixture lookup works. fc.setFixture(&doc, Fixture::invalidId()); fc.setChannel(2); QCOMPARE(fc.group(&doc), QLCChannel::Colour); // Fixture and channel given, but fixture doesn't exist -> intensity fc.setFixture(&doc, 12345); fc.setChannel(2); QCOMPARE(fc.group(&doc), QLCChannel::Intensity); }