summaryrefslogtreecommitdiffstats
path: root/src/control/controlindicator.cpp
blob: c3935f6403feb640d4220ee557bb423042ac335f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "control/controlindicator.h"
#include "control/controlproxy.h"
#include "util/math.h"

ControlIndicator::ControlIndicator(ConfigKey key)
        : ControlObject(key, false),
          m_blinkValue(OFF),
          m_nextSwitchTime(0.0) {
    // Tick time in audio buffer resolution
    m_pCOTGuiTickTime = new ControlProxy("[Master]", "guiTickTime", this);
    m_pCOTGuiTick50ms = new ControlProxy("[Master]", "guiTick50ms", this);
    m_pCOTGuiTick50ms->connectValueChanged(SLOT(slotGuiTick50ms(double)));
    connect(this, SIGNAL(blinkValueChanged()),
            this, SLOT(slotBlinkValueChanged()));
}

ControlIndicator::~ControlIndicator() {
}

void ControlIndicator::setBlinkValue(enum BlinkValue bv) {
    if (m_blinkValue != bv) {
        m_blinkValue = bv; // must be set at first, to avoid timer toggle
        emit(blinkValueChanged());
    }
}

void ControlIndicator::slotGuiTick50ms(double cpuTime) {
    if (m_nextSwitchTime <= cpuTime) {
        switch (m_blinkValue) {
        case RATIO1TO1_500MS:
            toggle(0.5);
            break;
        case RATIO1TO1_250MS:
            toggle(0.25);
            break;
        case OFF: // fall through
        case ON: // fall through
        default:
            // nothing to do
            break;
        }
    }
}

void ControlIndicator::slotBlinkValueChanged() {
    bool oldValue = toBool();

    switch (m_blinkValue) {
    case OFF:
        if (oldValue) {
            set(0.0);
        }
        break;
    case ON:
        if (!oldValue) {
            set(1.0);
        }
        break;
    case RATIO1TO1_500MS:
        toggle(0.5);
        break;
    case RATIO1TO1_250MS:
        toggle(0.25);
        break;
    default:
        // nothing to do
        break;
    }
}

void ControlIndicator::toggle(double duration) {
    double tickTime = m_pCOTGuiTickTime->get();
    double toggles = floor(tickTime / duration);
    bool phase = fmod(toggles, 2) >= 1;
    bool val = toBool();
    if(val != phase) {
        // Out of phase, wait until we are in phase
        m_nextSwitchTime = (toggles + 2) * duration;
    } else {
        m_nextSwitchTime = (toggles + 1) * duration;
    }
    set(val ? 0.0 : 1.0);
}