2013-10-27 18:04:37 +01:00
// Qt includes
# include <QDateTime>
# include "LinearColorSmoothing.h"
2014-09-22 21:28:38 +02:00
LinearColorSmoothing : : LinearColorSmoothing (
2014-09-25 22:05:01 +02:00
LedDevice * ledDevice ,
2014-09-22 21:28:38 +02:00
double ledUpdateFrequency_hz ,
int settlingTime_ms ,
unsigned updateDelay ) :
2013-10-27 18:04:37 +01:00
QObject ( ) ,
LedDevice ( ) ,
_ledDevice ( ledDevice ) ,
2013-10-27 21:06:35 +01:00
_updateInterval ( 1000 / ledUpdateFrequency_hz ) ,
_settlingTime ( settlingTime_ms ) ,
2014-09-22 21:28:38 +02:00
_timer ( ) ,
_outputDelay ( updateDelay )
2013-10-27 18:04:37 +01:00
{
_timer . setSingleShot ( false ) ;
_timer . setInterval ( _updateInterval ) ;
connect ( & _timer , SIGNAL ( timeout ( ) ) , this , SLOT ( updateLeds ( ) ) ) ;
2014-09-25 22:31:20 +02:00
2016-03-23 17:40:34 +01:00
std : : cout < < " HYPERION (CS) INFO: Created linear-smoothing(interval_ms= " < < _updateInterval < < " ;settlingTime_ms= " < < settlingTime_ms < < " ;updateDelay= " < < _outputDelay < < std : : endl ;
2013-10-27 18:04:37 +01:00
}
LinearColorSmoothing : : ~ LinearColorSmoothing ( )
{
2014-09-30 21:00:42 +02:00
// Make sure to switch off the underlying led-device (because switchOff is no longer forwarded)
_ledDevice - > switchOff ( ) ;
2013-10-27 18:04:37 +01:00
delete _ledDevice ;
}
2013-11-11 10:00:37 +01:00
int LinearColorSmoothing : : write ( const std : : vector < ColorRgb > & ledValues )
2013-10-27 18:04:37 +01:00
{
// received a new target color
2014-09-22 21:28:38 +02:00
if ( _previousValues . empty ( ) )
2013-10-27 18:04:37 +01:00
{
// not initialized yet
_targetTime = QDateTime : : currentMSecsSinceEpoch ( ) + _settlingTime ;
_targetValues = ledValues ;
_previousTime = QDateTime : : currentMSecsSinceEpoch ( ) ;
_previousValues = ledValues ;
_timer . start ( ) ;
}
else
{
_targetTime = QDateTime : : currentMSecsSinceEpoch ( ) + _settlingTime ;
2013-11-11 10:00:37 +01:00
memcpy ( _targetValues . data ( ) , ledValues . data ( ) , ledValues . size ( ) * sizeof ( ColorRgb ) ) ;
2013-10-27 18:04:37 +01:00
}
return 0 ;
}
int LinearColorSmoothing : : switchOff ( )
{
2014-09-25 22:05:01 +02:00
// We will keep updating the leds (but with pure-black)
2014-09-22 21:28:38 +02:00
// Clear the smoothing parameters
std : : fill ( _targetValues . begin ( ) , _targetValues . end ( ) , ColorRgb : : BLACK ) ;
2013-10-27 18:04:37 +01:00
_targetTime = 0 ;
2014-09-22 21:28:38 +02:00
// Erase the output-queue
for ( unsigned i = 0 ; i < _outputQueue . size ( ) ; + + i )
{
_outputQueue . push_back ( _targetValues ) ;
_outputQueue . pop_front ( ) ;
}
return 0 ;
2013-10-27 18:04:37 +01:00
}
void LinearColorSmoothing : : updateLeds ( )
{
int64_t now = QDateTime : : currentMSecsSinceEpoch ( ) ;
int deltaTime = _targetTime - now ;
if ( deltaTime < 0 )
{
2013-11-11 10:00:37 +01:00
memcpy ( _previousValues . data ( ) , _targetValues . data ( ) , _targetValues . size ( ) * sizeof ( ColorRgb ) ) ;
2013-10-27 18:04:37 +01:00
_previousTime = now ;
2014-09-22 21:28:38 +02:00
queueColors ( _previousValues ) ;
2013-10-27 18:04:37 +01:00
}
else
{
float k = 1.0f - 1.0f * deltaTime / ( _targetTime - _previousTime ) ;
for ( size_t i = 0 ; i < _previousValues . size ( ) ; + + i )
{
2013-11-11 10:00:37 +01:00
ColorRgb & prev = _previousValues [ i ] ;
ColorRgb & target = _targetValues [ i ] ;
2013-10-27 18:04:37 +01:00
prev . red + = k * ( target . red - prev . red ) ;
prev . green + = k * ( target . green - prev . green ) ;
prev . blue + = k * ( target . blue - prev . blue ) ;
}
_previousTime = now ;
2014-09-22 21:28:38 +02:00
queueColors ( _previousValues ) ;
}
}
void LinearColorSmoothing : : queueColors ( const std : : vector < ColorRgb > & ledColors )
{
if ( _outputDelay = = 0 )
{
2014-09-25 22:05:01 +02:00
// No output delay => immediate write
2014-09-22 21:28:38 +02:00
_ledDevice - > write ( ledColors ) ;
}
else
{
2014-09-25 22:05:01 +02:00
// Push the new colors in the delay-buffer
2014-09-22 21:28:38 +02:00
_outputQueue . push_back ( ledColors ) ;
2014-09-25 22:05:01 +02:00
// If the delay-buffer is filled pop the front and write to device
2014-09-22 21:28:38 +02:00
if ( _outputQueue . size ( ) > _outputDelay )
{
_ledDevice - > write ( _outputQueue . front ( ) ) ;
_outputQueue . pop_front ( ) ;
}
2013-10-27 18:04:37 +01:00
}
}