• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mcallegari / qlcplus / 27867971263

20 Jun 2026 10:09AM UTC coverage: 35.268% (-0.1%) from 35.377%
27867971263

push

github

mcallegari
Back to 5.3.0 debug

18433 of 52265 relevant lines covered (35.27%)

41250.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.3
/engine/src/fadechannel.cpp
1
/*
2
  Q Light Controller
3
  fadechannel.cpp
4

5
  Copyright (c) Heikki Junnila
6

7
  Licensed under the Apache License, Version 2.0 (the "License");
8
  you may not use this file except in compliance with the License.
9
  You may obtain a copy of the License at
10

11
      http://www.apache.org/licenses/LICENSE-2.0.txt
12

13
  Unless required by applicable law or agreed to in writing, software
14
  distributed under the License is distributed on an "AS IS" BASIS,
15
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
  See the License for the specific language governing permissions and
17
  limitations under the License.
18
*/
19

20
#include <QDebug>
21
#include <cmath>
22

23
#include "qlcfixturemode.h"
24
#include "fadechannel.h"
25
#include "qlcchannel.h"
26
#include "universe.h"
27
#include "fixture.h"
28

29
FadeChannel::FadeChannel()
60,607✔
30
    : m_flags(0)
60,607✔
31
    , m_fixture(Fixture::invalidId())
121,214✔
32
    , m_universe(Universe::invalid())
60,607✔
33
    , m_primaryChannel(QLCChannel::invalid())
60,607✔
34
    , m_address(QLCChannel::invalid())
60,607✔
35
    , m_channelRef(NULL)
60,607✔
36
    , m_start(0)
60,607✔
37
    , m_target(0)
60,607✔
38
    , m_current(0)
60,607✔
39
    , m_ready(false)
60,607✔
40
    , m_fadeTime(0)
60,607✔
41
    , m_elapsed(0)
121,214✔
42
{
43
}
60,607✔
44

45
FadeChannel::FadeChannel(const FadeChannel& ch)
60,960✔
46
    : m_flags(ch.m_flags)
60,960✔
47
    , m_fixture(ch.m_fixture)
60,960✔
48
    , m_universe(ch.m_universe)
60,960✔
49
    , m_primaryChannel(ch.m_primaryChannel)
60,960✔
50
    , m_channels(ch.m_channels)
60,960✔
51
    , m_address(ch.m_address)
60,960✔
52
    , m_channelRef(ch.m_channelRef)
60,960✔
53
    , m_start(ch.m_start)
60,960✔
54
    , m_target(ch.m_target)
60,960✔
55
    , m_current(ch.m_current)
60,960✔
56
    , m_ready(ch.m_ready)
60,960✔
57
    , m_fadeTime(ch.m_fadeTime)
60,960✔
58
    , m_elapsed(ch.m_elapsed)
60,960✔
59
{
60
    //qDebug() << Q_FUNC_INFO;
61
}
60,960✔
62

63
FadeChannel::FadeChannel(const Doc *doc, quint32 fxi, quint32 channel)
60,633✔
64
    : m_flags(0)
60,633✔
65
    , m_fixture(fxi)
60,633✔
66
    , m_universe(Universe::invalid())
121,266✔
67
    , m_primaryChannel(QLCChannel::invalid())
60,633✔
68
    , m_address(QLCChannel::invalid())
60,633✔
69
    , m_channelRef(NULL)
60,633✔
70
    , m_start(0)
60,633✔
71
    , m_target(0)
60,633✔
72
    , m_current(0)
60,633✔
73
    , m_ready(false)
60,633✔
74
    , m_fadeTime(0)
60,633✔
75
    , m_elapsed(0)
121,266✔
76
{
77
    m_channels.append(channel);
60,633✔
78
    autoDetect(doc);
60,633✔
79
}
60,633✔
80

81
FadeChannel::~FadeChannel()
242,792✔
82
{
83
}
242,792✔
84

85
FadeChannel &FadeChannel::operator=(const FadeChannel &fc)
60,604✔
86
{
87
    if (this != &fc)
60,604✔
88
    {
89
        m_flags = fc.m_flags;
60,604✔
90
        m_fixture = fc.m_fixture;
60,604✔
91
        m_universe = fc.m_universe;
60,604✔
92
        m_primaryChannel = fc.m_primaryChannel;
60,604✔
93
        m_channels = fc.m_channels;
60,604✔
94
        m_channelRef = fc.m_channelRef;
60,604✔
95
        m_address = fc.m_address;
60,604✔
96
        m_start = fc.m_start;
60,604✔
97
        m_target = fc.m_target;
60,604✔
98
        m_current = fc.m_current;
60,604✔
99
        m_ready = fc.m_ready;
60,604✔
100
        m_fadeTime = fc.m_fadeTime;
60,604✔
101
        m_elapsed = fc.m_elapsed;
60,604✔
102
    }
103

104
    return *this;
60,604✔
105
}
106

107
bool FadeChannel::operator==(const FadeChannel& ch) const
2✔
108
{
109
    return (m_fixture == ch.m_fixture && channel() == ch.channel());
2✔
110
}
111

112
int FadeChannel::flags() const
11,620,398✔
113
{
114
    return m_flags;
11,620,398✔
115
}
116

117
void FadeChannel::setFlags(int flags)
60,633✔
118
{
119
    m_flags = flags;
60,633✔
120
}
60,633✔
121

122
void FadeChannel::addFlag(int flag)
173,121✔
123
{
124
    m_flags |= flag;
173,121✔
125
}
173,121✔
126

127
void FadeChannel::removeFlag(int flag)
320,129✔
128
{
129
    m_flags &= (~flag);
320,129✔
130
}
320,129✔
131

132
void FadeChannel::autoDetect(const Doc *doc)
60,633✔
133
{
134
    bool fixtureWasInvalid = false;
60,633✔
135
    // reset before autodetecting
136
    setFlags(0);
60,633✔
137
    m_universe = Universe::invalid();
60,633✔
138
    m_primaryChannel = QLCChannel::invalid();
60,633✔
139
    m_address = QLCChannel::invalid();
60,633✔
140

141
    /* on invalid fixture, channel number is most likely
142
     * absolute (SimpleDesk/CueStack do it this way), so attempt
143
     * a reverse lookup to try and find the Fixture ID */
144
    if (m_fixture == Fixture::invalidId())
60,633✔
145
    {
146
        fixtureWasInvalid = true;
60,020✔
147
        m_fixture = doc->fixtureForAddress(channel());
60,020✔
148
    }
149

150
    Fixture *fixture = doc->fixture(m_fixture);
60,633✔
151
    if (fixture == NULL)
60,633✔
152
    {
153
        addFlag(FadeChannel::HTP | FadeChannel::Intensity | FadeChannel::CanFade);
60,020✔
154
    }
155
    else
156
    {
157
        QLCFixtureMode *mode = fixture->fixtureMode();
613✔
158
        m_universe = fixture->universe();
613✔
159
        m_address = fixture->address();
613✔
160

161
        // if the fixture was invalid at the beginning of this method
162
        // it means channel was an absolute address, so, fix it
163
        if (fixtureWasInvalid)
613✔
164
            m_channels[0] -= fixture->address();
6✔
165

166
        quint32 chIndex = channel();
613✔
167
        m_primaryChannel = mode ? mode->primaryChannel(chIndex) : QLCChannel::invalid();
613✔
168
        m_channelRef = fixture->channel(chIndex);
613✔
169

170
        // non existing channel within fixture
171
        if (m_channelRef == NULL)
613✔
172
        {
173
            addFlag(FadeChannel::HTP | FadeChannel::Intensity | FadeChannel::CanFade);
3✔
174
            return;
3✔
175
        }
176

177
        // autodetect the channel type
178
        if (fixture->channelCanFade(chIndex))
610✔
179
            addFlag(FadeChannel::CanFade);
609✔
180

181
        if (m_channelRef != NULL && m_channelRef->group() == QLCChannel::Intensity)
610✔
182
            addFlag(FadeChannel::HTP | FadeChannel::Intensity);
139✔
183
        else
184
            addFlag(FadeChannel::LTP);
471✔
185

186
        if (fixture->forcedHTPChannels().contains(int(chIndex)))
610✔
187
        {
188
            removeFlag(FadeChannel::LTP);
1✔
189
            addFlag(FadeChannel::HTP);
1✔
190
        }
191
        else if (fixture->forcedLTPChannels().contains(int(chIndex)))
609✔
192
        {
193
            removeFlag(FadeChannel::HTP);
1✔
194
            addFlag(FadeChannel::LTP);
1✔
195
        }
196
    }
197
}
198

199
quint32 FadeChannel::fixture() const
855,250✔
200
{
201
    return m_fixture;
855,250✔
202
}
203

204
quint32 FadeChannel::universe() const
5✔
205
{
206
    if (m_universe == Universe::invalid())
5✔
207
        return address() / UNIVERSE_SIZE;
2✔
208
    return m_universe;
3✔
209
}
210

211
void FadeChannel::addChannel(quint32 num)
×
212
{
213
    m_channels.append(num);
×
214
    //qDebug() << "[FadeChannel] ADD channel" << num << "count:" << m_channels.count();
215

216
    // on secondary channel, shift values 8bits up
217
    if (m_channels.count() > 1)
×
218
    {
219
        m_start = m_start << 8;
×
220
        m_target = m_target << 8;
×
221
        m_current = m_current << 8;
×
222
    }
223
}
×
224

225
int FadeChannel::channelCount() const
11,622,329✔
226
{
227
    if (m_channels.isEmpty())
11,622,329✔
228
        return 1;
×
229

230
    return m_channels.count();
11,622,329✔
231
}
232

233
quint32 FadeChannel::channel() const
12,596,834✔
234
{
235
    return m_channels.isEmpty() ? QLCChannel::invalid() : m_channels.first();
12,596,834✔
236
}
237

238
int FadeChannel::channelIndex(quint32 channel) const
529✔
239
{
240
    int idx = m_channels.indexOf(channel);
529✔
241
    return idx < 0 ? 0 : idx;
529✔
242
}
243

244
quint32 FadeChannel::primaryChannel() const
855,226✔
245
{
246
    return m_primaryChannel;
855,226✔
247
}
248

249
quint32 FadeChannel::address() const
11,680,935✔
250
{
251
    if (m_address == QLCChannel::invalid())
11,680,935✔
252
        return channel();
9,957,869✔
253

254
    return (m_address + channel());
1,723,066✔
255
}
256

257
quint32 FadeChannel::addressInUniverse() const
11,620,330✔
258
{
259
    quint32 addr = address();
11,620,330✔
260
    if (addr == QLCChannel::invalid())
11,620,330✔
261
        return QLCChannel::invalid();
2✔
262

263
    return addr % UNIVERSE_SIZE;
11,620,328✔
264
}
265

266
/************************************************************************
267
 * Values
268
 ************************************************************************/
269

270
void FadeChannel::setStart(uchar value, int index)
529✔
271
{
272
    ((uchar *)&m_start)[channelCount() - 1 - index] = value;
529✔
273
}
529✔
274

275
void FadeChannel::setStart(quint32 value)
854,976✔
276
{
277
    m_start = value;
854,976✔
278
}
854,976✔
279

280
uchar FadeChannel::start(int index) const
×
281
{
282
    return ((uchar *)&m_start)[channelCount() - 1 - index];
×
283
}
284

285
quint32 FadeChannel::start() const
526✔
286
{
287
    return m_start;
526✔
288
}
289

290
void FadeChannel::setTarget(uchar value, int index)
531✔
291
{
292
    ((uchar *)&m_target)[channelCount() - 1 - index] = value;
531✔
293
}
531✔
294

295
void FadeChannel::setTarget(quint32 value)
854,986✔
296
{
297
    m_target = value;
854,986✔
298
}
854,986✔
299

300
uchar FadeChannel::target(int index) const
×
301
{
302
    return ((uchar *)&m_target)[channelCount() - 1 - index];
×
303
}
304

305
quint32 FadeChannel::target() const
19,780✔
306
{
307
    return m_target;
19,780✔
308
}
309

310
void FadeChannel::setCurrent(uchar value, int index)
413✔
311
{
312
    ((uchar *)&m_current)[channelCount() - 1 - index] = value;
413✔
313
}
413✔
314

315
void FadeChannel::setCurrent(quint32 value)
915,228✔
316
{
317
    m_current = value;
915,228✔
318
}
915,228✔
319

320
uchar FadeChannel::current(int index) const
529✔
321
{
322
    return ((uchar *)&m_current)[channelCount() - 1 - index];
529✔
323
}
324

325
quint32 FadeChannel::current() const
13,030,105✔
326
{
327
    return m_current;
13,030,105✔
328
}
329

330
uchar FadeChannel::current(qreal intensity, int index) const
×
331
{
332
    return uchar(floor((qreal(current(index)) * intensity) + 0.5));
×
333
}
334

335
quint32 FadeChannel::current(qreal intensity) const
6,581,737✔
336
{
337
    return quint32(floor((qreal(m_current) * intensity) + 0.5));
6,581,737✔
338
}
339

340
void FadeChannel::setReady(bool rdy)
6,415,163✔
341
{
342
    m_ready = rdy;
6,415,163✔
343
}
6,415,163✔
344

345
bool FadeChannel::isReady() const
3,467✔
346
{
347
    return m_ready;
3,467✔
348
}
349

350
bool FadeChannel::canFade() const
11,620,874✔
351
{
352
    return (m_flags & CanFade) ? true : false;
11,620,874✔
353
}
354

355
void FadeChannel::setFadeTime(uint ms)
60,896✔
356
{
357
    m_fadeTime = ms;
60,896✔
358
}
60,896✔
359

360
uint FadeChannel::fadeTime() const
11,620,493✔
361
{
362
    return m_fadeTime;
11,620,493✔
363
}
364

365
void FadeChannel::setElapsed(uint time)
12,475,105✔
366
{
367
    m_elapsed = time;
12,475,105✔
368
}
12,475,105✔
369

370
uint FadeChannel::elapsed() const
34,861,185✔
371
{
372
    return m_elapsed;
34,861,185✔
373
}
374

375
uchar FadeChannel::nextStep(uint ms)
11,620,394✔
376
{
377
    if (elapsed() < UINT_MAX)
11,620,394✔
378
        setElapsed(elapsed() + ms);
11,620,389✔
379

380
    return calculateCurrent(fadeTime(), elapsed());
11,620,394✔
381
}
382

383
uchar FadeChannel::calculateCurrent(uint fadeTime, uint elapsedTime)
11,621,450✔
384
{
385
    if (elapsedTime >= fadeTime || m_ready == true)
11,621,450✔
386
    {
387
        // Return the target value if all time has been consumed
388
        // or if the channel has been marked ready.
389
        m_current = m_target;
5,560,443✔
390
        setReady(true);
5,560,443✔
391
    }
392
    else if (elapsedTime == 0)
6,061,007✔
393
    {
394
        m_current = m_start;
5✔
395
    }
396
    else
397
    {
398
        bool rampUp = m_target > m_start ? true : false;
6,061,002✔
399
        m_current = rampUp ? m_target - m_start : m_start - m_target;
6,061,002✔
400
        m_current = m_current * (qreal(elapsedTime) / qreal(fadeTime));
6,061,002✔
401
        m_current = rampUp ? m_start + m_current : m_start - m_current;
6,061,002✔
402
        //qDebug() << "channel" << channel() << "start" << m_start << "target" << m_target << "current" << m_current << "fade" << fadeTime << "elapsed" << elapsedTime ;
403
    }
404

405
    return uchar(m_current);
11,621,450✔
406
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc