@@ -284,13 +284,32 @@ void sACNEffectEngine::setRate(qreal hz)
284284
285285void sACNEffectEngine::timerTick ()
286286{
287- m_index++;
288287 char line[32 ];
289288
289+ // Returns true if the tracked value should be incremented
290+ const auto checkDwellTime = [this ](quint8 value, quint8 holdValue) {
291+ if (m_dwellTime == 0 ) return true ;
292+
293+ if (value == holdValue)
294+ {
295+ if (m_dwellTimeTracker.elapsed () >= m_dwellTime * 1000 )
296+ {
297+ m_dwellTimeTracker.restart ();
298+ return true ;
299+ }
300+ else
301+ {
302+ return false ;
303+ }
304+ }
305+ m_dwellTimeTracker.restart ();
306+ return true ;
307+ };
308+
290309 switch (m_mode)
291310 {
292311 case FxRamp:
293- m_data++;
312+ if ( checkDwellTime (m_data, 255 )) m_data++;
294313 QMetaObject::invokeMethod (
295314 m_sender,
296315 " setLevelRange" ,
@@ -300,7 +319,7 @@ void sACNEffectEngine::timerTick()
300319 emit fxLevelChange (m_data);
301320 break ;
302321 case FxInverseRamp:
303- m_data--;
322+ if ( checkDwellTime (m_data, 255 )) m_data--;
304323 QMetaObject::invokeMethod (
305324 m_sender,
306325 " setLevelRange" ,
@@ -310,8 +329,12 @@ void sACNEffectEngine::timerTick()
310329 emit fxLevelChange (m_data);
311330 break ;
312331 case FxSinewave:
313- if (m_index >= sizeof (sinetable)) m_index = 0 ;
314- m_data = sinetable[m_index];
332+ if (checkDwellTime (m_data, 255 ))
333+ {
334+ m_index++;
335+ if (m_index >= sizeof (sinetable)) m_index = 0 ;
336+ m_data = sinetable[m_index];
337+ }
315338 QMetaObject::invokeMethod (
316339 m_sender,
317340 " setLevelRange" ,
@@ -321,68 +344,72 @@ void sACNEffectEngine::timerTick()
321344 emit fxLevelChange (m_data);
322345 break ;
323346 case FxChaseSnap:
324- QMetaObject::invokeMethod (
325- m_sender,
326- " setLevelRange" ,
327- Q_ARG (quint16, m_start),
328- Q_ARG (quint16, m_end),
329- Q_ARG (quint8, 0 ));
330- QMetaObject::invokeMethod (
331- m_sender,
332- " setLevel" ,
333- Q_ARG (quint16, m_index_chase),
334- Q_ARG (quint8, m_manualLevel));
335-
336- if (m_index_chase < m_start) m_index_chase = m_start;
337-
338- if (++m_index_chase > m_end) m_index_chase = m_start;
347+ if (checkDwellTime (m_index_chase, m_index_chase))
348+ {
349+ if (m_index_chase < m_start) m_index_chase = m_start;
350+ if (++m_index_chase > m_end) m_index_chase = m_start;
339351
352+ QMetaObject::invokeMethod (
353+ m_sender,
354+ " setLevelRange" ,
355+ Q_ARG (quint16, m_start),
356+ Q_ARG (quint16, m_end),
357+ Q_ARG (quint8, 0 ));
358+ QMetaObject::invokeMethod (
359+ m_sender,
360+ " setLevel" ,
361+ Q_ARG (quint16, m_index_chase),
362+ Q_ARG (quint8, m_manualLevel));
363+ }
340364 break ;
341365
342366 case FxChaseRamp:
343- if (m_index > std::numeric_limits<decltype (m_data)>::max ())
367+ {
368+ if (m_data < 255 )
344369 {
345- m_index = std::numeric_limits<decltype (m_data)>::min ();
370+ m_data++;
371+ m_dwellTimeTracker.restart ();
372+ }
373+ else if (checkDwellTime (m_data, 255 ))
374+ {
375+ m_data++;
346376 if (++m_index_chase > m_end) m_index_chase = m_start;
377+ if (m_index_chase < m_start) m_index_chase = m_start;
347378 }
348379
349- if (m_index_chase < m_start) m_index_chase = m_start;
350-
351- m_data = m_index;
352-
380+ auto levels = QByteArray (512 , 0 );
381+ levels[m_index_chase] = m_data;
353382 QMetaObject::invokeMethod (
354- m_sender,
355- " setLevelRange" ,
356- Q_ARG (quint16, m_start),
357- Q_ARG (quint16, m_end),
358- Q_ARG (quint8, 0 ));
359- QMetaObject::invokeMethod (m_sender, " setLevel" , Q_ARG (quint16, m_index_chase), Q_ARG (quint8, m_data));
383+ m_sender,
384+ " setLevel" ,
385+ Q_ARG (QByteArray, levels));
360386 emit fxLevelChange (m_data);
361387
362388 break ;
363-
389+ }
364390 case FxChaseSine:
365- if (m_index >= sizeof (sinetable))
391+ {
392+ if (checkDwellTime (m_data, 255 ))
366393 {
367- m_index = 0 ;
368- if (++m_index_chase > m_end) m_index_chase = m_start;
394+ m_index++;
395+ if (m_index >= sizeof (sinetable))
396+ {
397+ m_index = 0 ;
398+ if (++m_index_chase > m_end) m_index_chase = m_start;
399+ if (m_index_chase < m_start) m_index_chase = m_start;
400+ }
401+ m_data = sinetable[m_index];
369402 }
370-
371- if (m_index_chase < m_start) m_index_chase = m_start;
372-
373- m_data = sinetable[m_index];
374-
403+ auto levels = QByteArray (512 , 0 );
404+ levels[m_index_chase] = m_data;
375405 QMetaObject::invokeMethod (
376406 m_sender,
377- " setLevelRange" ,
378- Q_ARG (quint16, m_start),
379- Q_ARG (quint16, m_end),
380- Q_ARG (quint8, 0 ));
381- QMetaObject::invokeMethod (m_sender, " setLevel" , Q_ARG (quint16, m_index_chase), Q_ARG (quint8, m_data));
407+ " setLevel" ,
408+ Q_ARG (QByteArray, levels));
382409 emit fxLevelChange (m_data);
383410
384411 break ;
385-
412+ }
386413 case FxManual:
387414 QMetaObject::invokeMethod (
388415 m_sender,
@@ -394,7 +421,7 @@ void sACNEffectEngine::timerTick()
394421 case FxText:
395422 if (m_image)
396423 {
397- if (m_index > m_imageWidth) m_index = 0 ;
424+ if (++ m_index > m_imageWidth) m_index = 0 ;
398425
399426 for (int i = 0 ; i < 16 ; i++)
400427 {
@@ -427,11 +454,11 @@ void sACNEffectEngine::timerTick()
427454 }
428455 break ;
429456 case FxVerticalBar:
430- if (m_index > 31 ) m_index = 0 ;
457+ if (++ m_index > 31 ) m_index = 0 ;
431458 QMetaObject::invokeMethod (m_sender, " setVerticalBar" , Q_ARG (quint16, m_index), Q_ARG (quint8, 255 ));
432459 break ;
433460 case FxHorizontalBar:
434- if (m_index > 15 ) m_index = 0 ;
461+ if (++ m_index > 15 ) m_index = 0 ;
435462 QMetaObject::invokeMethod (m_sender, " setHorizontalBar" , Q_ARG (quint16, m_index), Q_ARG (quint8, 255 ));
436463 break ;
437464 }
@@ -456,3 +483,9 @@ void sACNEffectEngine::slotCountChanged()
456483{
457484 setEndAddress (m_end);
458485}
486+
487+ void sACNEffectEngine::setDwellTime (quint16 seconds)
488+ {
489+ m_dwellTime = seconds;
490+ m_dwellTimeTracker.restart ();
491+ }
0 commit comments