2013-11-11 10:00:37 +01:00
// STL includes
2016-06-17 01:25:40 +02:00
# include <exception>
2016-07-01 23:20:41 +02:00
# include <sstream>
2013-11-11 10:00:37 +01:00
2013-08-21 16:25:27 +02:00
// QT includes
2013-11-22 11:48:10 +01:00
# include <QString>
# include <QStringList>
2019-07-14 22:43:22 +02:00
# include <QThread>
2013-08-14 17:02:09 +02:00
2013-07-26 22:38:34 +02:00
// hyperion include
# include <hyperion/Hyperion.h>
2018-12-27 23:11:32 +01:00
# include <hyperion/MessageForwarder.h>
2016-12-19 23:59:50 +01:00
# include <hyperion/ImageProcessor.h>
2016-04-02 00:04:11 +02:00
# include <hyperion/ColorAdjustment.h>
2013-07-26 22:38:34 +02:00
2018-12-27 23:11:32 +01:00
// utils
# include <utils/hyperion.h>
2019-07-29 19:09:26 +02:00
# include <utils/GlobalSignals.h>
2020-08-02 10:44:42 +02:00
# include <utils/Logger.h>
2018-12-27 23:11:32 +01:00
2013-12-17 19:50:15 +01:00
// Leddevice includes
2019-01-01 19:47:07 +01:00
# include <leddevice/LedDeviceWrapper.h>
2013-08-13 11:10:45 +02:00
2018-12-27 23:11:32 +01:00
# include <hyperion/MultiColorAdjustment.h>
2013-10-27 18:04:37 +01:00
# include "LinearColorSmoothing.h"
2013-11-24 16:10:48 +01:00
// effect engine includes
# include <effectengine/EffectEngine.h>
2018-12-27 23:11:32 +01:00
// settingsManagaer
# include <hyperion/SettingsManager.h>
// BGEffectHandler
# include <hyperion/BGEffectHandler.h>
// CaptureControl (Daemon capture)
# include <hyperion/CaptureCont.h>
2017-01-10 19:58:41 +01:00
2018-12-28 18:12:45 +01:00
// Boblight
# include <boblightserver/BoblightServer.h>
2020-08-08 13:09:15 +02:00
Hyperion : : Hyperion ( quint8 instance )
2019-07-14 22:43:22 +02:00
: QObject ( )
, _instIndex ( instance )
, _settingsManager ( new SettingsManager ( instance , this ) )
2018-12-27 23:11:32 +01:00
, _componentRegister ( this )
, _ledString ( hyperion : : createLedString ( getSetting ( settings : : LEDS ) . array ( ) , hyperion : : createColorOrder ( getSetting ( settings : : DEVICE ) . object ( ) ) ) )
, _imageProcessor ( new ImageProcessor ( _ledString , this ) )
2020-07-19 15:13:41 +02:00
, _muxer ( _ledString . leds ( ) . size ( ) , this )
2018-12-27 23:11:32 +01:00
, _raw2ledAdjustment ( hyperion : : createLedColorsAdjustment ( _ledString . leds ( ) . size ( ) , getSetting ( settings : : COLOR ) . object ( ) ) )
2016-07-15 23:08:55 +02:00
, _effectEngine ( nullptr )
2019-07-20 11:28:16 +02:00
, _messageForwarder ( nullptr )
2018-12-27 23:11:32 +01:00
, _log ( Logger : : getInstance ( " HYPERION " ) )
, _hwLedCount ( )
, _ledGridSize ( hyperion : : getLedLayoutGridSize ( getSetting ( settings : : LEDS ) . array ( ) ) )
, _ledBuffer ( _ledString . leds ( ) . size ( ) , ColorRgb : : BLACK )
2019-07-14 22:43:22 +02:00
{
}
Hyperion : : ~ Hyperion ( )
{
2020-08-02 22:32:00 +02:00
freeObjects ( ) ;
2019-07-14 22:43:22 +02:00
}
void Hyperion : : start ( )
2013-07-26 22:38:34 +02:00
{
2019-07-12 16:54:26 +02:00
// forward settings changed to Hyperion
connect ( _settingsManager , & SettingsManager : : settingsChanged , this , & Hyperion : : settingsChanged ) ;
2019-07-14 22:43:22 +02:00
// get newVideoMode from HyperionIManager
connect ( this , & Hyperion : : newVideoMode , this , & Hyperion : : handleNewVideoMode ) ;
2016-04-02 00:04:11 +02:00
if ( ! _raw2ledAdjustment - > verifyAdjustments ( ) )
2019-07-14 22:43:22 +02:00
{
2018-12-27 23:11:32 +01:00
Warning ( _log , " At least one led has no color calibration, please add all leds from your led layout to an 'LED index' field! " ) ;
2019-07-14 22:43:22 +02:00
}
2017-03-21 17:55:46 +01:00
2018-12-27 23:11:32 +01:00
// handle hwLedCount
_hwLedCount = qMax ( unsigned ( getSetting ( settings : : DEVICE ) . object ( ) [ " hardwareLedCount " ] . toInt ( getLedCount ( ) ) ) , getLedCount ( ) ) ;
2017-06-24 11:52:22 +02:00
2018-12-27 23:11:32 +01:00
// init colororder vector
2020-08-02 10:44:42 +02:00
for ( const Led & led : _ledString . leds ( ) )
2018-12-27 23:11:32 +01:00
{
_ledStringColorOrder . push_back ( led . colorOrder ) ;
}
2017-06-24 11:52:22 +02:00
2019-07-14 22:43:22 +02:00
// connect Hyperion::update with Muxer visible priority changes as muxer updates independent
connect ( & _muxer , & PriorityMuxer : : visiblePriorityChanged , this , & Hyperion : : update ) ;
2020-10-19 10:54:41 +02:00
connect ( & _muxer , & PriorityMuxer : : visiblePriorityChanged , this , & Hyperion : : handlePriorityChangedLedDevice ) ;
2020-02-15 22:47:27 +01:00
connect ( & _muxer , & PriorityMuxer : : visibleComponentChanged , this , & Hyperion : : handleVisibleComponentChanged ) ;
2019-07-14 22:43:22 +02:00
2018-12-27 23:11:32 +01:00
// listens for ComponentRegister changes of COMP_ALL to perform core enable/disable actions
2020-02-15 22:47:27 +01:00
// connect(&_componentRegister, &ComponentRegister::updatedComponentState, this, &Hyperion::updatedComponentState);
2013-10-27 18:04:37 +01:00
2018-12-27 23:11:32 +01:00
// listen for settings updates of this instance (LEDS & COLOR)
connect ( _settingsManager , & SettingsManager : : settingsChanged , this , & Hyperion : : handleSettingsUpdate ) ;
2017-08-04 12:01:45 +02:00
2018-12-27 23:11:32 +01:00
// set color correction activity state
const QJsonObject color = getSetting ( settings : : COLOR ) . object ( ) ;
2013-08-14 17:02:09 +02:00
2018-12-27 23:11:32 +01:00
// initialize leddevices
2018-12-28 18:12:45 +01:00
QJsonObject ledDevice = getSetting ( settings : : DEVICE ) . object ( ) ;
2018-12-27 23:11:32 +01:00
ledDevice [ " currentLedCount " ] = int ( _hwLedCount ) ; // Inject led count info
2017-03-21 17:55:46 +01:00
2019-01-01 19:47:07 +01:00
_ledDeviceWrapper = new LedDeviceWrapper ( this ) ;
2020-02-26 18:54:56 +01:00
connect ( this , & Hyperion : : compStateChangeRequest , _ledDeviceWrapper , & LedDeviceWrapper : : handleComponentState ) ;
2020-02-10 15:21:58 +01:00
connect ( this , & Hyperion : : ledDeviceData , _ledDeviceWrapper , & LedDeviceWrapper : : updateLeds ) ;
2019-01-01 19:47:07 +01:00
_ledDeviceWrapper - > createLedDevice ( ledDevice ) ;
2017-06-24 11:52:22 +02:00
2019-01-01 19:47:07 +01:00
// smoothing
_deviceSmooth = new LinearColorSmoothing ( getSetting ( settings : : SMOOTHING ) , this ) ;
connect ( this , & Hyperion : : settingsChanged , _deviceSmooth , & LinearColorSmoothing : : handleSettingsUpdate ) ;
2018-12-27 23:11:32 +01:00
2019-07-20 11:28:16 +02:00
// create the message forwarder only on main instance
if ( _instIndex = = 0 )
_messageForwarder = new MessageForwarder ( this ) ;
2019-01-01 19:47:07 +01:00
// create the effect engine; needs to be initialized after smoothing!
2018-12-31 15:48:29 +01:00
_effectEngine = new EffectEngine ( this ) ;
2018-12-27 23:11:32 +01:00
connect ( _effectEngine , & EffectEngine : : effectListUpdated , this , & Hyperion : : effectListUpdated ) ;
2013-11-24 16:10:48 +01:00
2018-12-27 23:11:32 +01:00
// initial startup effect
hyperion : : handleInitialEffect ( this , getSetting ( settings : : FGEFFECT ) . object ( ) ) ;
2019-01-01 19:47:07 +01:00
2018-12-27 23:11:32 +01:00
// handle background effect
_BGEffectHandler = new BGEffectHandler ( this ) ;
2016-09-14 13:51:28 +02:00
2018-12-27 23:11:32 +01:00
// create the Daemon capture interface
_captureCont = new CaptureCont ( this ) ;
2017-06-24 11:52:22 +02:00
2019-07-29 19:09:26 +02:00
// forwards global signals to the corresponding slots
connect ( GlobalSignals : : getInstance ( ) , & GlobalSignals : : registerGlobalInput , this , & Hyperion : : registerInput ) ;
connect ( GlobalSignals : : getInstance ( ) , & GlobalSignals : : clearGlobalInput , this , & Hyperion : : clear ) ;
connect ( GlobalSignals : : getInstance ( ) , & GlobalSignals : : setGlobalColor , this , & Hyperion : : setColor ) ;
connect ( GlobalSignals : : getInstance ( ) , & GlobalSignals : : setGlobalImage , this , & Hyperion : : setInputImage ) ;
2018-12-27 23:11:32 +01:00
// if there is no startup / background eff and no sending capture interface we probably want to push once BLACK (as PrioMuxer won't emit a prioritiy change)
2013-08-18 13:33:56 +02:00
update ( ) ;
2018-12-28 18:12:45 +01:00
// boblight, can't live in global scope as it depends on layout
_boblightServer = new BoblightServer ( this , getSetting ( settings : : BOBLSERVER ) ) ;
connect ( this , & Hyperion : : settingsChanged , _boblightServer , & BoblightServer : : handleSettingsUpdate ) ;
2019-06-05 18:19:08 +02:00
2020-07-12 18:27:24 +02:00
// instance inited, enter thread event loop
2019-07-14 22:43:22 +02:00
emit started ( ) ;
2013-07-26 22:38:34 +02:00
}
2019-07-14 22:43:22 +02:00
void Hyperion : : stop ( )
2017-08-04 12:01:45 +02:00
{
2019-07-14 22:43:22 +02:00
emit finished ( ) ;
2019-07-25 18:23:19 +02:00
thread ( ) - > wait ( ) ;
2017-08-04 12:01:45 +02:00
}
2020-08-02 22:32:00 +02:00
void Hyperion : : freeObjects ( )
2013-07-26 22:38:34 +02:00
{
2017-08-12 07:55:32 +02:00
// switch off all leds
2020-02-26 18:54:56 +01:00
clear ( - 1 , true ) ;
2017-08-12 07:55:32 +02:00
2016-07-01 23:20:41 +02:00
// delete components on exit of hyperion core
2018-12-28 18:12:45 +01:00
delete _boblightServer ;
2018-12-27 23:11:32 +01:00
delete _captureCont ;
2013-11-24 16:10:48 +01:00
delete _effectEngine ;
2016-04-02 00:04:11 +02:00
delete _raw2ledAdjustment ;
2019-07-20 11:28:16 +02:00
delete _messageForwarder ;
2018-12-27 23:11:32 +01:00
delete _settingsManager ;
2019-01-01 19:47:07 +01:00
delete _ledDeviceWrapper ;
2013-07-26 22:38:34 +02:00
}
2020-08-08 13:09:15 +02:00
void Hyperion : : handleSettingsUpdate ( settings : : type type , const QJsonDocument & config )
2016-10-10 23:08:01 +02:00
{
2020-02-10 15:21:58 +01:00
// std::cout << "Hyperion::handleSettingsUpdate" << std::endl;
// std::cout << config.toJson().toStdString() << std::endl;
2018-12-27 23:11:32 +01:00
if ( type = = settings : : COLOR )
{
const QJsonObject obj = config . object ( ) ;
// change in color recreate ledAdjustments
delete _raw2ledAdjustment ;
_raw2ledAdjustment = hyperion : : createLedColorsAdjustment ( _ledString . leds ( ) . size ( ) , obj ) ;
if ( ! _raw2ledAdjustment - > verifyAdjustments ( ) )
{
Warning ( _log , " At least one led has no color calibration, please add all leds from your led layout to an 'LED index' field! " ) ;
}
}
else if ( type = = settings : : LEDS )
{
const QJsonArray leds = config . array ( ) ;
// stop and cache all running effects, as effects depend heavily on ledlayout
_effectEngine - > cacheRunningEffects ( ) ;
2019-08-25 16:32:19 +02:00
// ledstring, img processor, muxer, ledGridSize (eff engine image based effects), _ledBuffer and ByteOrder of ledstring
2018-12-27 23:11:32 +01:00
_ledString = hyperion : : createLedString ( leds , hyperion : : createColorOrder ( getSetting ( settings : : DEVICE ) . object ( ) ) ) ;
_imageProcessor - > setLedString ( _ledString ) ;
_muxer . updateLedColorsLength ( _ledString . leds ( ) . size ( ) ) ;
_ledGridSize = hyperion : : getLedLayoutGridSize ( leds ) ;
std : : vector < ColorRgb > color ( _ledString . leds ( ) . size ( ) , ColorRgb { 0 , 0 , 0 } ) ;
_ledBuffer = color ;
_ledStringColorOrder . clear ( ) ;
2020-08-02 10:44:42 +02:00
for ( const Led & led : _ledString . leds ( ) )
2018-12-27 23:11:32 +01:00
{
_ledStringColorOrder . push_back ( led . colorOrder ) ;
}
// handle hwLedCount update
_hwLedCount = qMax ( unsigned ( getSetting ( settings : : DEVICE ) . object ( ) [ " hardwareLedCount " ] . toInt ( getLedCount ( ) ) ) , getLedCount ( ) ) ;
// change in leds are also reflected in adjustment
delete _raw2ledAdjustment ;
_raw2ledAdjustment = hyperion : : createLedColorsAdjustment ( _ledString . leds ( ) . size ( ) , getSetting ( settings : : COLOR ) . object ( ) ) ;
// start cached effects
_effectEngine - > startCachedEffects ( ) ;
}
else if ( type = = settings : : DEVICE )
{
2018-12-28 18:12:45 +01:00
QJsonObject dev = config . object ( ) ;
2018-12-27 23:11:32 +01:00
// handle hwLedCount update
_hwLedCount = qMax ( unsigned ( dev [ " hardwareLedCount " ] . toInt ( getLedCount ( ) ) ) , getLedCount ( ) ) ;
// force ledString update, if device ByteOrder changed
2019-01-01 19:47:07 +01:00
if ( _ledDeviceWrapper - > getColorOrder ( ) ! = dev [ " colorOrder " ] . toString ( " rgb " ) )
2018-12-27 23:11:32 +01:00
{
_ledString = hyperion : : createLedString ( getSetting ( settings : : LEDS ) . array ( ) , hyperion : : createColorOrder ( dev ) ) ;
_imageProcessor - > setLedString ( _ledString ) ;
2019-09-07 01:17:26 +02:00
_ledStringColorOrder . clear ( ) ;
2020-08-02 10:44:42 +02:00
for ( const Led & led : _ledString . leds ( ) )
2019-09-07 01:17:26 +02:00
{
_ledStringColorOrder . push_back ( led . colorOrder ) ;
}
2018-12-27 23:11:32 +01:00
}
2019-01-01 19:47:07 +01:00
// do always reinit until the led devices can handle dynamic changes
2018-12-27 23:11:32 +01:00
dev [ " currentLedCount " ] = int ( _hwLedCount ) ; // Inject led count info
2019-01-01 19:47:07 +01:00
_ledDeviceWrapper - > createLedDevice ( dev ) ;
2020-02-10 15:21:58 +01:00
// TODO: Check, if framegrabber frequency is lower than latchtime..., if yes, stop
}
else if ( type = = settings : : SMOOTHING )
{
_deviceSmooth - > handleSettingsUpdate ( type , config ) ;
2018-12-27 23:11:32 +01:00
}
2019-07-14 22:43:22 +02:00
2018-12-28 18:12:45 +01:00
// update once to push single color sets / adjustments/ ledlayout resizes and update ledBuffer color
2018-12-27 23:11:32 +01:00
update ( ) ;
2016-10-10 23:08:01 +02:00
}
2020-08-08 13:09:15 +02:00
QJsonDocument Hyperion : : getSetting ( settings : : type type ) const
2013-08-14 10:54:49 +02:00
{
2018-12-27 23:11:32 +01:00
return _settingsManager - > getSetting ( type ) ;
2013-08-14 10:54:49 +02:00
}
2020-08-08 23:12:43 +02:00
bool Hyperion : : saveSettings ( const QJsonObject & config , bool correct )
2017-03-21 17:55:46 +01:00
{
2018-12-27 23:11:32 +01:00
return _settingsManager - > saveSettings ( config , correct ) ;
2017-03-21 17:55:46 +01:00
}
2018-12-27 23:11:32 +01:00
int Hyperion : : getLatchTime ( ) const
{
2020-08-02 10:44:42 +02:00
return _ledDeviceWrapper - > getLatchTime ( ) ;
2017-03-21 17:55:46 +01:00
}
2018-12-27 23:11:32 +01:00
unsigned Hyperion : : addSmoothingConfig ( int settlingTime_ms , double ledUpdateFrequency_hz , unsigned updateDelay )
2017-03-21 17:55:46 +01:00
{
2018-12-27 23:11:32 +01:00
return _deviceSmooth - > addConfig ( settlingTime_ms , ledUpdateFrequency_hz , updateDelay ) ;
2017-03-21 17:55:46 +01:00
}
2020-02-10 15:21:58 +01:00
unsigned Hyperion : : updateSmoothingConfig ( unsigned id , int settlingTime_ms , double ledUpdateFrequency_hz , unsigned updateDelay )
{
return _deviceSmooth - > updateConfig ( id , settlingTime_ms , ledUpdateFrequency_hz , updateDelay ) ;
}
2018-12-27 23:11:32 +01:00
unsigned Hyperion : : getLedCount ( ) const
2017-03-21 17:55:46 +01:00
{
2018-12-27 23:11:32 +01:00
return _ledString . leds ( ) . size ( ) ;
2017-03-21 17:55:46 +01:00
}
2016-09-14 13:51:28 +02:00
2020-08-08 13:09:15 +02:00
void Hyperion : : setSourceAutoSelect ( bool state )
2016-07-31 22:21:35 +02:00
{
2020-03-26 17:59:41 +01:00
_muxer . setSourceAutoSelectEnabled ( state ) ;
2016-07-31 22:21:35 +02:00
}
2020-08-08 13:09:15 +02:00
bool Hyperion : : setVisiblePriority ( int priority )
2016-07-31 22:21:35 +02:00
{
2018-12-27 23:11:32 +01:00
return _muxer . setPriority ( priority ) ;
}
2016-07-31 22:21:35 +02:00
2020-08-08 23:12:43 +02:00
bool Hyperion : : sourceAutoSelectEnabled ( ) const
2018-12-27 23:11:32 +01:00
{
return _muxer . isSourceAutoSelectEnabled ( ) ;
2016-07-31 22:21:35 +02:00
}
2020-08-08 13:09:15 +02:00
void Hyperion : : setNewComponentState ( hyperion : : Components component , bool state )
2016-08-04 13:10:53 +02:00
{
2020-02-26 18:54:56 +01:00
_componentRegister . setNewComponentState ( component , state ) ;
2019-01-01 19:47:07 +01:00
}
2017-03-21 17:55:46 +01:00
2020-08-02 10:44:42 +02:00
std : : map < hyperion : : Components , bool > Hyperion : : getAllComponents ( ) const
2019-01-01 19:47:07 +01:00
{
2020-02-26 18:54:56 +01:00
return _componentRegister . getRegister ( ) ;
}
2020-08-08 23:12:43 +02:00
int Hyperion : : isComponentEnabled ( hyperion : : Components comp ) const
2020-02-26 18:54:56 +01:00
{
return _componentRegister . isComponentEnabled ( comp ) ;
2016-08-04 13:10:53 +02:00
}
2016-07-15 23:08:55 +02:00
2020-08-08 13:09:15 +02:00
void Hyperion : : registerInput ( int priority , hyperion : : Components component , const QString & origin , const QString & owner , unsigned smooth_cfg )
2013-07-26 22:38:34 +02:00
{
2018-12-27 23:11:32 +01:00
_muxer . registerInput ( priority , component , origin , owner , smooth_cfg ) ;
2013-08-18 13:33:56 +02:00
}
2013-07-26 22:38:34 +02:00
2020-08-08 13:09:15 +02:00
bool Hyperion : : setInput ( int priority , const std : : vector < ColorRgb > & ledColors , int timeout_ms , bool clearEffect )
2013-07-26 22:38:34 +02:00
{
2018-12-27 23:11:32 +01:00
if ( _muxer . setInput ( priority , ledColors , timeout_ms ) )
2013-12-08 17:45:26 +01:00
{
2018-12-27 23:11:32 +01:00
// clear effect if this call does not come from an effect
if ( clearEffect )
_effectEngine - > channelCleared ( priority ) ;
2013-12-08 17:45:26 +01:00
2018-12-27 23:11:32 +01:00
// if this priority is visible, update immediately
if ( priority = = _muxer . getCurrentPriority ( ) )
2020-02-10 15:21:58 +01:00
{
2018-12-27 23:11:32 +01:00
update ( ) ;
2020-02-10 15:21:58 +01:00
}
2013-07-26 22:38:34 +02:00
2018-12-27 23:11:32 +01:00
return true ;
2013-08-14 17:02:09 +02:00
}
2018-12-27 23:11:32 +01:00
return false ;
2013-08-14 17:02:09 +02:00
}
2020-08-08 13:09:15 +02:00
bool Hyperion : : setInputImage ( int priority , const Image < ColorRgb > & image , int64_t timeout_ms , bool clearEffect )
2016-12-18 19:00:14 +01:00
{
2019-07-29 19:09:26 +02:00
if ( ! _muxer . hasPriority ( priority ) )
{
emit GlobalSignals : : getInstance ( ) - > globalRegRequired ( priority ) ;
return false ;
}
2018-12-27 23:11:32 +01:00
if ( _muxer . setInputImage ( priority , image , timeout_ms ) )
2016-12-18 19:00:14 +01:00
{
2018-12-27 23:11:32 +01:00
// clear effect if this call does not come from an effect
if ( clearEffect )
_effectEngine - > channelCleared ( priority ) ;
// if this priority is visible, update immediately
if ( priority = = _muxer . getCurrentPriority ( ) )
2020-02-10 15:21:58 +01:00
{
2018-12-27 23:11:32 +01:00
update ( ) ;
2020-02-10 15:21:58 +01:00
}
2018-12-27 23:11:32 +01:00
return true ;
2016-12-18 19:00:14 +01:00
}
2018-12-27 23:11:32 +01:00
return false ;
}
2020-08-08 13:09:15 +02:00
bool Hyperion : : setInputInactive ( quint8 priority )
2018-12-28 18:12:45 +01:00
{
return _muxer . setInputInactive ( priority ) ;
}
2020-08-08 13:09:15 +02:00
void Hyperion : : setColor ( int priority , const std : : vector < ColorRgb > & ledColors , int timeout_ms , const QString & origin , bool clearEffects )
2018-12-27 23:11:32 +01:00
{
// clear effect if this call does not come from an effect
2020-02-26 18:54:56 +01:00
if ( clearEffects )
2018-12-27 23:11:32 +01:00
_effectEngine - > channelCleared ( priority ) ;
2020-02-26 18:54:56 +01:00
// create full led vector from single/multiple colors
2020-07-27 20:00:36 +02:00
size_t size = _ledString . leds ( ) . size ( ) ;
2020-02-26 18:54:56 +01:00
std : : vector < ColorRgb > newLedColors ;
2020-07-27 20:00:36 +02:00
while ( true )
{
for ( const auto & entry : ledColors )
{
newLedColors . emplace_back ( entry ) ;
if ( newLedColors . size ( ) = = size )
goto end ;
}
}
end :
2018-12-27 23:11:32 +01:00
2019-08-24 22:53:30 +02:00
if ( getPriorityInfo ( priority ) . componentId ! = hyperion : : COMP_COLOR )
clear ( priority ) ;
2018-12-27 23:11:32 +01:00
// register color
registerInput ( priority , hyperion : : COMP_COLOR , origin ) ;
2019-07-21 19:06:47 +02:00
// write color to muxer & queuePush
2020-02-26 18:54:56 +01:00
setInput ( priority , newLedColors , timeout_ms ) ;
if ( timeout_ms < = 0 )
2019-07-21 19:06:47 +02:00
_muxer . queuePush ( ) ;
2016-12-18 19:00:14 +01:00
}
2020-08-08 23:12:43 +02:00
QStringList Hyperion : : getAdjustmentIds ( ) const
2016-04-02 00:04:11 +02:00
{
return _raw2ledAdjustment - > getAdjustmentIds ( ) ;
}
2020-08-02 10:44:42 +02:00
ColorAdjustment * Hyperion : : getAdjustment ( const QString & id ) const
2016-04-02 00:04:11 +02:00
{
return _raw2ledAdjustment - > getAdjustment ( id ) ;
}
void Hyperion : : adjustmentsUpdated ( )
{
2018-12-27 23:11:32 +01:00
emit adjustmentChanged ( ) ;
2016-04-02 00:04:11 +02:00
update ( ) ;
}
2020-08-08 13:09:15 +02:00
bool Hyperion : : clear ( int priority , bool forceClearAll )
2013-08-18 13:33:56 +02:00
{
2020-02-26 18:54:56 +01:00
if ( priority < 0 )
{
_muxer . clearAll ( forceClearAll ) ;
2018-12-27 23:11:32 +01:00
2020-02-26 18:54:56 +01:00
// send clearall signal to the effect engine
_effectEngine - > allChannelsCleared ( ) ;
2018-12-27 23:11:32 +01:00
return true ;
2020-02-26 18:54:56 +01:00
}
else
{
// send clear signal to the effect engine
// (outside the check so the effect gets cleared even when the effect is not sending colors)
_effectEngine - > channelCleared ( priority ) ;
2018-12-27 23:11:32 +01:00
2020-02-26 18:54:56 +01:00
if ( _muxer . clearInput ( priority ) )
return true ;
}
2018-12-27 23:11:32 +01:00
return false ;
2013-08-18 13:33:56 +02:00
}
2016-05-30 22:39:12 +02:00
int Hyperion : : getCurrentPriority ( ) const
{
2018-12-27 23:11:32 +01:00
return _muxer . getCurrentPriority ( ) ;
2016-05-30 22:39:12 +02:00
}
2020-08-08 13:09:15 +02:00
bool Hyperion : : isCurrentPriority ( int priority ) const
2017-09-01 08:50:37 +02:00
{
return getCurrentPriority ( ) = = priority ;
}
2013-08-19 20:33:36 +02:00
QList < int > Hyperion : : getActivePriorities ( ) const
{
return _muxer . getPriorities ( ) ;
}
2020-08-08 13:09:15 +02:00
Hyperion : : InputInfo Hyperion : : getPriorityInfo ( int priority ) const
2013-08-19 20:33:36 +02:00
{
return _muxer . getInputInfo ( priority ) ;
}
2020-03-26 17:59:41 +01:00
QString Hyperion : : saveEffect ( const QJsonObject & obj )
2018-12-31 15:48:29 +01:00
{
2020-03-26 17:59:41 +01:00
return _effectEngine - > saveEffect ( obj ) ;
2018-12-31 15:48:29 +01:00
}
2020-03-26 17:59:41 +01:00
QString Hyperion : : deleteEffect ( const QString & effectName )
2016-11-20 18:41:10 +01:00
{
2020-03-26 17:59:41 +01:00
return _effectEngine - > deleteEffect ( effectName ) ;
2016-11-20 18:41:10 +01:00
}
2020-08-08 23:12:43 +02:00
std : : list < EffectDefinition > Hyperion : : getEffects ( ) const
2013-11-24 16:10:48 +01:00
{
return _effectEngine - > getEffects ( ) ;
}
2020-08-08 23:12:43 +02:00
std : : list < ActiveEffectDefinition > Hyperion : : getActiveEffects ( ) const
2016-04-24 17:07:31 +02:00
{
return _effectEngine - > getActiveEffects ( ) ;
}
2020-08-08 23:12:43 +02:00
std : : list < EffectSchema > Hyperion : : getEffectSchemas ( ) const
2016-10-24 23:52:53 +02:00
{
return _effectEngine - > getEffectSchemas ( ) ;
}
2020-08-08 23:12:43 +02:00
QJsonObject Hyperion : : getQJsonConfig ( ) const
2018-12-27 23:11:32 +01:00
{
return _settingsManager - > getSettings ( ) ;
}
2017-03-01 15:23:53 +01:00
int Hyperion : : setEffect ( const QString & effectName , int priority , int timeout , const QString & origin )
2013-11-24 16:10:48 +01:00
{
2017-03-01 15:23:53 +01:00
return _effectEngine - > runEffect ( effectName , priority , timeout , origin ) ;
2013-11-24 16:10:48 +01:00
}
2019-01-06 19:49:56 +01:00
int Hyperion : : setEffect ( const QString & effectName , const QJsonObject & args , int priority , int timeout , const QString & pythonScript , const QString & origin , const QString & imageData )
2013-12-01 14:09:01 +01:00
{
2019-01-06 19:49:56 +01:00
return _effectEngine - > runEffect ( effectName , args , priority , timeout , pythonScript , origin , 0 , imageData ) ;
2013-12-01 14:09:01 +01:00
}
2020-08-08 13:09:15 +02:00
void Hyperion : : setLedMappingType ( int mappingType )
2018-12-27 23:11:32 +01:00
{
if ( mappingType ! = _imageProcessor - > getUserLedMappingType ( ) )
{
_imageProcessor - > setLedMappingType ( mappingType ) ;
emit imageToLedsMappingChanged ( mappingType ) ;
}
}
2020-08-02 10:44:42 +02:00
int Hyperion : : getLedMappingType ( ) const
2016-12-19 23:59:50 +01:00
{
2018-12-27 23:11:32 +01:00
return _imageProcessor - > getUserLedMappingType ( ) ;
2016-12-19 23:59:50 +01:00
}
2020-08-08 13:09:15 +02:00
void Hyperion : : setVideoMode ( VideoMode mode )
2017-08-04 23:08:15 +02:00
{
emit videoMode ( mode ) ;
}
2020-08-02 10:44:42 +02:00
VideoMode Hyperion : : getCurrentVideoMode ( ) const
2018-12-27 23:11:32 +01:00
{
2019-07-14 22:43:22 +02:00
return _currVideoMode ;
2018-12-27 23:11:32 +01:00
}
2017-08-04 23:08:15 +02:00
2020-08-02 10:44:42 +02:00
QString Hyperion : : getActiveDeviceType ( ) const
2017-06-24 11:52:22 +02:00
{
2019-12-08 13:12:01 +01:00
return _ledDeviceWrapper - > getActiveDeviceType ( ) ;
2018-12-27 23:11:32 +01:00
}
2020-08-08 13:09:15 +02:00
void Hyperion : : handleVisibleComponentChanged ( hyperion : : Components comp )
2018-12-27 23:11:32 +01:00
{
2020-02-15 22:47:27 +01:00
_imageProcessor - > setBlackbarDetectDisable ( ( comp = = hyperion : : COMP_EFFECT ) ) ;
_imageProcessor - > setHardLedMappingType ( ( comp = = hyperion : : COMP_EFFECT ) ? 0 : - 1 ) ;
_raw2ledAdjustment - > setBacklightEnabled ( ( comp ! = hyperion : : COMP_COLOR & & comp ! = hyperion : : COMP_EFFECT ) ) ;
2017-06-24 11:52:22 +02:00
}
2020-10-19 10:54:41 +02:00
void Hyperion : : handlePriorityChangedLedDevice ( const quint8 & priority )
2020-09-14 17:19:14 +02:00
{
quint8 previousPriority = _muxer . getPreviousPriority ( ) ;
Debug ( _log , " priority[%u], previousPriority[%u] " , priority , previousPriority ) ;
if ( priority = = PriorityMuxer : : LOWEST_PRIORITY )
{
Debug ( _log , " No source left -> switch LED-Device off " ) ;
emit _ledDeviceWrapper - > switchOff ( ) ;
}
else
{
if ( previousPriority = = PriorityMuxer : : LOWEST_PRIORITY )
{
Debug ( _log , " new source available -> switch LED-Device on " ) ;
emit _ledDeviceWrapper - > switchOn ( ) ;
}
}
}
2013-08-14 17:02:09 +02:00
void Hyperion : : update ( )
{
2018-12-27 23:11:32 +01:00
// Obtain the current priority channel
int priority = _muxer . getCurrentPriority ( ) ;
const PriorityMuxer : : InputInfo priorityInfo = _muxer . getInputInfo ( priority ) ;
2018-12-20 15:12:45 +01:00
2018-12-27 23:11:32 +01:00
// copy image & process OR copy ledColors from muxer
Image < ColorRgb > image = priorityInfo . image ;
if ( image . size ( ) > 3 )
2016-08-08 00:17:00 +02:00
{
2018-12-27 23:11:32 +01:00
emit currentImage ( image ) ;
2019-07-02 19:06:36 +02:00
_ledBuffer = _imageProcessor - > process ( image ) ;
2016-08-08 00:17:00 +02:00
}
2018-12-27 23:11:32 +01:00
else
2020-08-02 10:44:42 +02:00
{
2018-12-27 23:11:32 +01:00
_ledBuffer = priorityInfo . ledColors ;
2020-08-02 10:44:42 +02:00
}
2018-12-31 15:48:29 +01:00
// emit rawLedColors before transform
emit rawLedColors ( _ledBuffer ) ;
2018-12-27 23:11:32 +01:00
_raw2ledAdjustment - > applyAdjustment ( _ledBuffer ) ;
2017-06-24 11:52:22 +02:00
2015-01-01 19:31:04 +01:00
int i = 0 ;
2016-07-01 23:20:41 +02:00
for ( ColorRgb & color : _ledBuffer )
2013-08-21 21:50:17 +02:00
{
2013-11-04 20:52:57 +01:00
// correct the color byte order
2016-08-08 00:17:00 +02:00
switch ( _ledStringColorOrder . at ( i ) )
2013-10-27 10:18:31 +01:00
{
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_RGB :
2013-11-04 20:52:57 +01:00
// leave as it is
break ;
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_BGR :
2013-10-27 10:18:31 +01:00
std : : swap ( color . red , color . blue ) ;
2013-11-04 20:52:57 +01:00
break ;
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_RBG :
2013-11-04 20:52:57 +01:00
std : : swap ( color . green , color . blue ) ;
break ;
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_GRB :
2013-11-04 20:52:57 +01:00
std : : swap ( color . red , color . green ) ;
break ;
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_GBR :
2016-05-22 00:30:53 +02:00
std : : swap ( color . red , color . green ) ;
std : : swap ( color . green , color . blue ) ;
2013-11-04 20:52:57 +01:00
break ;
2017-01-10 19:58:41 +01:00
2020-06-28 23:05:32 +02:00
case ColorOrder : : ORDER_BRG :
2016-05-22 00:30:53 +02:00
std : : swap ( color . red , color . blue ) ;
std : : swap ( color . green , color . blue ) ;
2013-11-04 20:52:57 +01:00
break ;
}
2015-01-01 19:31:04 +01:00
i + + ;
2013-08-21 21:50:17 +02:00
}
2019-07-02 19:06:36 +02:00
// fill additional hw leds with black
2016-07-01 23:20:41 +02:00
if ( _hwLedCount > _ledBuffer . size ( ) )
{
_ledBuffer . resize ( _hwLedCount , ColorRgb : : BLACK ) ;
}
2017-06-24 11:52:22 +02:00
2013-08-14 17:02:09 +02:00
// Write the data to the device
2019-01-01 19:47:07 +01:00
if ( _ledDeviceWrapper - > enabled ( ) )
2017-03-21 17:55:46 +01:00
{
2019-12-08 13:12:01 +01:00
// Smoothing is disabled
2017-03-30 06:20:20 +02:00
if ( ! _deviceSmooth - > enabled ( ) )
2019-12-08 13:12:01 +01:00
{
2020-02-10 15:21:58 +01:00
//std::cout << "Hyperion::update()> Non-Smoothing - "; LedDevice::printLedValues ( _ledBuffer);
2019-01-01 19:47:07 +01:00
emit ledDeviceData ( _ledBuffer ) ;
2019-12-08 13:12:01 +01:00
}
2020-02-10 15:21:58 +01:00
else
{
_deviceSmooth - > selectConfig ( priorityInfo . smooth_cfg ) ;
// feed smoothing in pause mode to maintain a smooth transistion back to smooth mode
if ( _deviceSmooth - > enabled ( ) | | _deviceSmooth - > pause ( ) )
{
_deviceSmooth - > updateLedValues ( _ledBuffer ) ;
}
}
2019-12-08 13:12:01 +01:00
}
2020-02-10 15:21:58 +01:00
//else
//{
// /LEDDevice is disabled
// Debug(_log, "LEDDevice is disabled - no update required");
//}
2013-07-26 22:38:34 +02:00
}