예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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());
}
예제 #4
0
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());
        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);
    }
}
예제 #5
0
파일: cuestack.cpp 프로젝트: Jeija/qlcplus
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);
    }
}
예제 #6
0
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);
}
예제 #7
0
파일: cuestack.cpp 프로젝트: Jeija/qlcplus
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();
}
예제 #8
0
void FadeChannel_Test::fadeTime()
{
    FadeChannel ch;
    QVERIFY(ch.fadeTime() == 0);
    ch.setFadeTime(50);
    QVERIFY(ch.fadeTime() == 50);
}
예제 #9
0
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);
    }
}
예제 #10
0
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);
}
예제 #11
0
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);
    }
}
예제 #12
0
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);
}
예제 #13
0
QString Script::handleSetFixture(const QList<QStringList>& tokens, QList<Universe *> universes)
{
    qDebug() << Q_FUNC_INFO;

    if (tokens.size() > 4)
        return QString("Too many arguments");

    bool ok = false;
    quint32 id = 0;
    quint32 ch = 0;
    uchar value = 0;
    double time = 0;

    id = tokens[0][1].toUInt(&ok);
    if (ok == false)
        return QString("Invalid fixture (ID: %1)").arg(tokens[0][1]);

    for (int i = 1; i < tokens.size(); i++)
    {
        QStringList list = tokens[i];
        list[0] = list[0].toLower().trimmed();
        if (list.size() == 2)
        {
            ok = false;
            if (list[0] == "val" || list[0] == "value")
                value = uchar(list[1].toUInt(&ok));
            else if (list[0] == "ch" || list[0] == "channel")
                ch = list[1].toUInt(&ok);
            else if (list[0] == "time")
                time = list[1].toDouble(&ok);
            else
                return QString("Unrecognized keyword: %1").arg(list[0]);

            if (ok == false)
                return QString("Invalid value (%1) for keyword: %2").arg(list[1]).arg(list[0]);
        }
    }

    Doc* doc = qobject_cast<Doc*> (parent());
    Q_ASSERT(doc != NULL);

    Fixture* fxi = doc->fixture(id);
    if (fxi != NULL)
    {
        if (ch < fxi->channels())
        {
            int address = fxi->address() + ch;
            if (address < 512)
            {
                GenericFader* gf = fader();
                Q_ASSERT(gf != NULL);

                FadeChannel fc;
                fc.setFixture(doc, fxi->id());
                fc.setChannel(ch);
                fc.setTarget(value);
                fc.setFadeTime(time);

                // If the script has used the channel previously, it might still be in
                // the bowels of GenericFader so get the starting value from there.
                // Otherwise get it from universes (HTP channels are always 0 then).
                quint32 uni = fc.universe();
                if (gf->channels().contains(fc) == true)
                    fc.setStart(gf->channels()[fc].current());
                else
                    fc.setStart(universes[uni]->preGMValue(address));
                fc.setCurrent(fc.start());

                gf->add(fc);

                return QString();
            }
            else
            {
                return QString("Invalid address: %1").arg(address);
            }
        }
        else
        {
            return QString("Fixture (%1) has no channel number %2").arg(fxi->name()).arg(ch);
        }
    }
    else
    {
        return QString("No such fixture (ID: %1)").arg(id);
    }
}