mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Merged branch master into master
This commit is contained in:
		
							
								
								
									
										19
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -1,7 +1,16 @@ | ||||
| notifications: | ||||
|   email: false | ||||
| language: cpp | ||||
| sudo: required | ||||
| dist: trusty | ||||
| matrix: | ||||
|   include: | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       sudo: required | ||||
| #    - os: osx | ||||
| #      osx_image: xcode7.3 | ||||
| before_install: | ||||
|   - sudo apt-get -qq update | ||||
|   - sudo apt-get install -qq -y qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev | ||||
| script: mkdir build && cd build && cmake -DPLATFORM=x86 -DCMAKE_BUILD_TYPE=Release .. && make -j 2 | ||||
|   - chmod +x ./.travis/travis_install.sh | ||||
|   - ./.travis/travis_install.sh | ||||
| script: | ||||
|   - chmod +x ./.travis/travis_build.sh | ||||
|   - ./.travis/travis_build.sh | ||||
|   | ||||
							
								
								
									
										11
									
								
								.travis/travis_build.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								.travis/travis_build.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| #!/bin/bash | ||||
| # compile hyperion on osx | ||||
| if [[ $TRAVIS_OS_NAME == 'osx' ]]; then | ||||
| 	cmake . -DCMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.6.1-1 | ||||
| 	mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTS=ON -Wno-dev .. && make -j$(nproc) package | ||||
| fi | ||||
|  | ||||
| # compile hyperion on linux | ||||
| if [[ $TRAVIS_OS_NAME == 'linux' ]]; then | ||||
| 	mkdir build && cd build && cmake -DPLATFORM=x86 -DCMAKE_BUILD_TYPE=Release -DENABLE_AMLOGIC=ON -DENABLE_TESTS=ON -DENABLE_SPIDEV=ON -Wno-dev .. && make -j$(nproc) package | ||||
| fi | ||||
							
								
								
									
										16
									
								
								.travis/travis_install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.travis/travis_install.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| #!/bin/bash | ||||
| # install osx deps for hyperion compile | ||||
| if [[ $TRAVIS_OS_NAME == 'osx' ]]; then | ||||
| 	echo "Install OSX deps" | ||||
| 	brew update | ||||
| 	brew install qt5 | ||||
| 	brew install libusb | ||||
| 	brew install cmake | ||||
| fi | ||||
|  | ||||
| # install linux deps for hyperion compile | ||||
| if [[ $TRAVIS_OS_NAME == 'linux' ]]; then | ||||
| 	echo "Install linux deps" | ||||
| 	sudo apt-get -qq update ; sudo apt-get install -qq -y qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev | ||||
| fi | ||||
|  | ||||
| @@ -8,6 +8,10 @@ IF ( POLICY CMP0026 ) | ||||
| 	CMAKE_POLICY( SET CMP0026 OLD ) | ||||
| ENDIF() | ||||
|  | ||||
| IF ( POLICY CMP0043 ) | ||||
| 	CMAKE_POLICY( SET CMP0043 OLD ) | ||||
| ENDIF() | ||||
|  | ||||
| SET ( HYPERION_VERSION_STABLE OFF ) | ||||
| SET ( HYPERION_VERSION_MAJOR 2 ) | ||||
| SET ( HYPERION_VERSION_MINOR 0 ) | ||||
| @@ -21,11 +25,12 @@ SET ( DEFAULT_X11        OFF ) | ||||
| SET ( DEFAULT_SPIDEV     OFF ) | ||||
| SET ( DEFAULT_WS2812BPWM OFF ) | ||||
| SET ( DEFAULT_WS281XPWM  OFF ) | ||||
| SET ( DEFAULT_ZEROCONF   ON ) | ||||
| SET ( DEFAULT_V4L2       ON  ) | ||||
| SET ( DEFAULT_USE_SHARED_AVAHI_LIBS  OFF ) | ||||
|  | ||||
| if (APPLE) | ||||
| 	SET ( DEFAULT_OSX ON ) | ||||
| 	SET ( DEFAULT_OSX  ON ) | ||||
| 	SET ( DEFAULT_V4l2 OFF ) | ||||
| else () | ||||
| 	if ( "${PLATFORM}" STREQUAL "rpi" ) | ||||
| 		SET ( DEFAULT_DISPMANX   ON ) | ||||
| @@ -48,8 +53,6 @@ else () | ||||
| endif () | ||||
|  | ||||
| # set the build options | ||||
| SET(ENABLE_ZEROCONF ON ) | ||||
|  | ||||
| option(ENABLE_AMLOGIC "Enable the AMLOGIC video grabber" ${DEFAULT_AMLOGIC} ) | ||||
| message(STATUS "ENABLE_AMLOGIC = " ${ENABLE_AMLOGIC}) | ||||
|  | ||||
| @@ -68,7 +71,7 @@ message(STATUS "ENABLE_SPIDEV   = " ${ENABLE_SPIDEV}) | ||||
| option(ENABLE_TINKERFORGE "Enable the TINKERFORGE device" ON) | ||||
| message(STATUS "ENABLE_TINKERFORGE = " ${ENABLE_TINKERFORGE}) | ||||
|  | ||||
| option(ENABLE_V4L2 "Enable the V4L2 grabber" ON) | ||||
| option(ENABLE_V4L2 "Enable the V4L2 grabber" ${DEFAULT_V4L2}) | ||||
| message(STATUS "ENABLE_V4L2 = " ${ENABLE_V4L2}) | ||||
|  | ||||
| option(ENABLE_WS2812BPWM   "Enable the WS2812b-PWM device" ${DEFAULT_WS2812BPWM} ) | ||||
|   | ||||
| @@ -27,9 +27,6 @@ | ||||
| // Define to enable the osx grabber | ||||
| #cmakedefine ENABLE_OSX | ||||
|  | ||||
| // Define to enable the bonjour/zeroconf publishing | ||||
| #cmakedefine ENABLE_ZEROCONF | ||||
|  | ||||
| // Define to enable profiler for development purpose | ||||
| #cmakedefine ENABLE_PROFILER | ||||
|  | ||||
|   | ||||
							
								
								
									
										12
									
								
								bin/service/hyperion.systemd.OE.LE.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								bin/service/hyperion.systemd.OE.LE.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| [Unit] | ||||
| Description=Hyperion ambient light systemd service for OpenELEC/LibreELEC/RasPlex | ||||
| After=graphical.target | ||||
|  | ||||
| [Service] | ||||
| ExecStart=/bin/sh -c "exec sh /storage/hyperion/bin/hyperiond.sh /storage/.config/hyperion/hyperion.config.json" | ||||
| TimeoutStopSec=2 | ||||
| Restart=always | ||||
| RestartSec=2 | ||||
|  | ||||
| [Install] | ||||
| WantedBy=default.target | ||||
| @@ -1,15 +1,15 @@ | ||||
| [Unit] | ||||
| Description=Hyperion Systemd service | ||||
| Description=Hyperion ambient light systemd service | ||||
|  | ||||
| [Service] | ||||
| Type=simple | ||||
| User=root | ||||
| Group=root | ||||
| UMask=007 | ||||
| User=hyperion | ||||
| Group=hyperion | ||||
| ExecStart=/usr/bin/hyperiond /etc/hyperion/hyperion.config.json | ||||
| ExecReload=/bin/kill -HUP $MAINPID | ||||
| Restart=on-failure | ||||
| TimeoutStopSec=10 | ||||
| TimeoutStopSec=2 | ||||
| Restart=always | ||||
| RestartSec=2 | ||||
|   | ||||
| [Install] | ||||
| WantedBy=multi-user.target | ||||
|   | ||||
| @@ -20,7 +20,7 @@ install_file() | ||||
| echo "--- hyperion ambilight postinstall ---" | ||||
| echo "- install configuration template" | ||||
| mkdir -p /etc/hyperion | ||||
| install_file /usr/share/hyperion/config/hyperion.config.json.example /etc/hyperion/hyperion.config.json | ||||
| install_file /usr/share/hyperion/config/hyperion.config.json.default /etc/hyperion/hyperion.config.json | ||||
|  | ||||
|  | ||||
| HYPERION_RUNNING=false | ||||
|   | ||||
| @@ -4,6 +4,12 @@ | ||||
|  | ||||
|  | ||||
| { | ||||
| 	/// set log level: silent warn verbose debug | ||||
| 	"logger" : | ||||
| 	{ | ||||
| 		"level" : "warn" | ||||
| 	}, | ||||
|  | ||||
| 	/// Device configuration contains the following fields:  | ||||
| 	/// * 'name'       : The user friendly name of the device (only used for display purposes) | ||||
| 	/// * 'type'       : The type of the device or leds (known types for now are | ||||
|   | ||||
| @@ -1,4 +1,9 @@ | ||||
| { | ||||
| 	"logger" : | ||||
| 	{ | ||||
| 		"level" : "warn" | ||||
| 	}, | ||||
|  | ||||
| 	"device" : | ||||
| 	{ | ||||
| 		"name"       : "DefaultHyperionConfig", | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -9,6 +9,7 @@ | ||||
|  | ||||
| // Hyperion includes | ||||
| #include <hyperion/Hyperion.h> | ||||
| #include <utils/Logger.h> | ||||
|  | ||||
| class BoblightClientConnection; | ||||
|  | ||||
| @@ -32,6 +33,24 @@ public: | ||||
| 	/// @return the port number on which this TCP listens for incoming connections | ||||
| 	/// | ||||
| 	uint16_t getPort() const; | ||||
| 	 | ||||
| 	/// @return true if server is active (bind to a port) | ||||
| 	/// | ||||
| 	bool active() { return _isActive; }; | ||||
| 	 | ||||
| public slots: | ||||
| 	/// | ||||
| 	/// bind server to network | ||||
| 	/// | ||||
| 	void start(); | ||||
| 	 | ||||
| 	/// | ||||
| 	/// close server | ||||
| 	/// | ||||
| 	void stop(); | ||||
|  | ||||
| signals: | ||||
| 	void statusChanged(bool isActive); | ||||
|  | ||||
| private slots: | ||||
| 	/// | ||||
| @@ -57,4 +76,12 @@ private: | ||||
|  | ||||
| 	/// hyperion priority | ||||
| 	const int _priority; | ||||
|  | ||||
| 	/// Logger instance | ||||
| 	Logger * _log; | ||||
|  | ||||
| 	/// state of connection | ||||
| 	bool _isActive; | ||||
|  | ||||
| 	uint16_t      _port; | ||||
| }; | ||||
|   | ||||
							
								
								
									
										4
									
								
								include/grabber/AmlogicGrabber.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										4
									
								
								include/grabber/AmlogicGrabber.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| // STL includes | ||||
| #include <cstdint> | ||||
|  | ||||
| #include <utils/Logger.h> | ||||
| // Utils includes | ||||
| #include <utils/Image.h> | ||||
| #include <utils/ColorBgr.h> | ||||
| @@ -55,4 +55,6 @@ private: | ||||
|  | ||||
| 	/** The snapshot/capture device of the amlogic video chip */ | ||||
| 	int _amlogicCaptureDev; | ||||
| 	 | ||||
| 	Logger * _log; | ||||
| }; | ||||
|   | ||||
							
								
								
									
										4
									
								
								include/grabber/X11Grabber.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										4
									
								
								include/grabber/X11Grabber.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -3,7 +3,7 @@ | ||||
| #include <utils/Image.h> | ||||
| #include <utils/ColorRgb.h> | ||||
| #include <utils/ImageResampler.h> | ||||
|  | ||||
| #include <utils/Logger.h> | ||||
| // X11 includes | ||||
| #include <X11/Xlib.h> | ||||
| #include <X11/extensions/Xrender.h> | ||||
| @@ -64,4 +64,6 @@ private: | ||||
| 	void setupResources(); | ||||
| 	 | ||||
| 	int updateScreenDimensions(); | ||||
| 	 | ||||
| 	Logger * _log; | ||||
| }; | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| #include <string> | ||||
|  | ||||
| // Utils includes | ||||
| #include <utils/RgbChannelCorrection.h> | ||||
| #include <utils/RgbChannelAdjustment.h> | ||||
|  | ||||
| class ColorCorrection | ||||
| { | ||||
| @@ -14,5 +14,5 @@ public: | ||||
| 	std::string _id; | ||||
|  | ||||
| 	/// The RGB correction | ||||
| 	RgbChannelCorrection _rgbCorrection; | ||||
| 	RgbChannelAdjustment _rgbCorrection; | ||||
| }; | ||||
|   | ||||
| @@ -9,6 +9,8 @@ | ||||
|  | ||||
| // hyperion-utils includes | ||||
| #include <utils/Image.h> | ||||
| #include <utils/ColorRgb.h> | ||||
| #include <utils/Logger.h> | ||||
|  | ||||
| // Hyperion includes | ||||
| #include <hyperion/LedString.h> | ||||
| @@ -33,7 +35,6 @@ class RgbChannelCorrection; | ||||
| class RgbChannelAdjustment; | ||||
| class MultiColorTransform; | ||||
| class MultiColorCorrection; | ||||
| class MultiColorTemperature; | ||||
| class MultiColorAdjustment; | ||||
| /// | ||||
| /// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through | ||||
| @@ -138,12 +139,6 @@ public slots: | ||||
| 	/// | ||||
| 	const std::vector<std::string> & getTransformIds() const; | ||||
| 	 | ||||
| 	/// | ||||
| 	/// Returns the list with unique correction identifiers | ||||
| 	/// @return The list with correction identifiers | ||||
| 	/// | ||||
| 	const std::vector<std::string> & getCorrectionIds() const; | ||||
| 	 | ||||
| 	/// | ||||
| 	/// Returns the list with unique correction identifiers | ||||
| 	/// @return The list with correction identifiers | ||||
| @@ -162,12 +157,6 @@ public slots: | ||||
| 	/// | ||||
| 	ColorTransform * getTransform(const std::string& id); | ||||
| 	 | ||||
| 	/// | ||||
| 	/// Returns the ColorCorrection with the given identifier | ||||
| 	/// @return The correction with the given identifier (or nullptr if the identifier does not exist) | ||||
| 	/// | ||||
| 	ColorCorrection * getCorrection(const std::string& id); | ||||
| 	 | ||||
| 	/// | ||||
| 	/// Returns the ColorCorrection with the given identifier | ||||
| 	/// @return The correction with the given identifier (or nullptr if the identifier does not exist) | ||||
| @@ -238,7 +227,6 @@ public: | ||||
| 	static LedString createLedString(const Json::Value & ledsConfig, const ColorOrder deviceOrder); | ||||
|  | ||||
| 	static MultiColorTransform * createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorTransformConfig); | ||||
| 	static MultiColorCorrection * createLedColorsCorrection(const unsigned ledCnt, const Json::Value & colorCorrectionConfig); | ||||
| 	static MultiColorCorrection * createLedColorsTemperature(const unsigned ledCnt, const Json::Value & colorTemperatureConfig); | ||||
| 	static MultiColorAdjustment * createLedColorsAdjustment(const unsigned ledCnt, const Json::Value & colorAdjustmentConfig); | ||||
| 	static ColorTransform * createColorTransform(const Json::Value & transformConfig); | ||||
| @@ -247,7 +235,7 @@ public: | ||||
| 	static HsvTransform * createHsvTransform(const Json::Value & hsvConfig); | ||||
| 	static HslTransform * createHslTransform(const Json::Value & hslConfig); | ||||
| 	static RgbChannelTransform * createRgbChannelTransform(const Json::Value& colorConfig); | ||||
| 	static RgbChannelCorrection * createRgbChannelCorrection(const Json::Value& colorConfig); | ||||
| 	static RgbChannelAdjustment * createRgbChannelCorrection(const Json::Value& colorConfig); | ||||
| 	static RgbChannelAdjustment * createRgbChannelAdjustment(const Json::Value& colorConfig, const RgbChannel color); | ||||
|  | ||||
| 	static LedDevice * createColorSmoothing(const Json::Value & smoothingConfig, LedDevice * ledDevice); | ||||
| @@ -287,9 +275,6 @@ private: | ||||
| 	/// The transformation from raw colors to led colors | ||||
| 	MultiColorTransform * _raw2ledTransform; | ||||
| 	 | ||||
| 	/// The correction from raw colors to led colors | ||||
| 	MultiColorCorrection * _raw2ledCorrection; | ||||
| 	 | ||||
| 	/// The temperature from raw colors to led colors | ||||
| 	MultiColorCorrection * _raw2ledTemperature; | ||||
| 	 | ||||
| @@ -313,4 +298,13 @@ private: | ||||
|  | ||||
| 	/// The timer for handling priority channel timeouts | ||||
| 	QTimer _timer; | ||||
| 	 | ||||
| 	/// buffer for leds | ||||
| 	std::vector<ColorRgb> _ledBuffer; | ||||
| 	 | ||||
| 	/// Logger instance | ||||
| 	Logger * _log; | ||||
| 	 | ||||
| 	/// count of hardware leds | ||||
| 	unsigned _hwLedCount; | ||||
| }; | ||||
|   | ||||
| @@ -27,12 +27,14 @@ class Logger | ||||
| public: | ||||
| 	enum LogLevel { UNSET=0,DEBUG=1, INFO=2,WARNING=3,ERROR=4,OFF=5 }; | ||||
|  | ||||
| 	static Logger* getInstance(std::string name="", LogLevel minLevel=Logger::INFO); | ||||
| 	static void deleteInstance(std::string name=""); | ||||
| 	static void setLogLevel(LogLevel level,std::string name=""); | ||||
| 	static Logger*  getInstance(std::string name="", LogLevel minLevel=Logger::INFO); | ||||
| 	static void     deleteInstance(std::string name=""); | ||||
| 	static void     setLogLevel(LogLevel level,std::string name=""); | ||||
| 	static LogLevel getLogLevel(std::string name=""); | ||||
|  | ||||
| 	void Message(LogLevel level, const char* sourceFile, const char* func, unsigned int line, const char* fmt, ...); | ||||
| 	void setMinLevel(LogLevel level) { _minLevel = level; }; | ||||
| 	void     Message(LogLevel level, const char* sourceFile, const char* func, unsigned int line, const char* fmt, ...); | ||||
| 	void     setMinLevel(LogLevel level) { _minLevel = level; }; | ||||
| 	LogLevel getMinLevel() { return _minLevel; }; | ||||
|  | ||||
| protected: | ||||
| 	Logger( std::string name="", LogLevel minLevel=INFO); | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| #include "utils/Logger.h" | ||||
| #include <string> | ||||
| #include <stdio.h> | ||||
| #include <stdarg.h> | ||||
| #include <time.h> | ||||
| #include <map> | ||||
| #include <utils/Logger.h> | ||||
| #include <HyperionConfig.h> | ||||
|  | ||||
| #ifndef ENABLE_PROFILER | ||||
| 	#error "Profiler is not for productive code, enable it via cmake or remove header include" | ||||
|   | ||||
| @@ -15,29 +15,34 @@ public: | ||||
| 	/// @param adjustR   | ||||
| 	/// @param adjustG  | ||||
| 	/// @param adjustB  | ||||
|  | ||||
| 	RgbChannelAdjustment(int adjustR, int adjustG, int adjustB); | ||||
| 	RgbChannelAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB); | ||||
|  | ||||
| 	/// Destructor | ||||
| 	~RgbChannelAdjustment(); | ||||
|  | ||||
| 	/// setAdjustment RGB | ||||
| 	/// @param adjustR   | ||||
| 	/// @param adjustG  | ||||
| 	/// @param adjustB  | ||||
| 	void setAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB); | ||||
|  | ||||
| 	/// @return The current adjustR value | ||||
| 	uint8_t getadjustmentR() const; | ||||
| 	uint8_t getAdjustmentR() const; | ||||
|  | ||||
| 	/// @param threshold New adjustR value | ||||
| 	void setadjustmentR(uint8_t adjustR); | ||||
| 	void setAdjustmentR(uint8_t adjustR); | ||||
|  | ||||
| 	/// @return The current adjustG value | ||||
| 	uint8_t getadjustmentG() const; | ||||
| 	uint8_t getAdjustmentG() const; | ||||
|  | ||||
| 	/// @param gamma New adjustG value | ||||
| 	void setadjustmentG(uint8_t adjustG); | ||||
| 	void setAdjustmentG(uint8_t adjustG); | ||||
|  | ||||
| 	/// @return The current adjustB value | ||||
| 	uint8_t getadjustmentB() const; | ||||
| 	uint8_t getAdjustmentB() const; | ||||
|  | ||||
| 	/// @param blacklevel New adjustB value | ||||
| 	void setadjustmentB(uint8_t adjustB); | ||||
| 	void setAdjustmentB(uint8_t adjustB); | ||||
|  | ||||
| 	/// Transform the given array value | ||||
| 	/// @param input The input color bytes | ||||
| @@ -48,19 +53,15 @@ public: | ||||
|  | ||||
|  | ||||
| private: | ||||
| 	/// color channels | ||||
| 	enum ColorChannel { RED=0,GREEN=1, BLUE=2 }; | ||||
|  | ||||
| 	/// (re)-initilize the color mapping | ||||
| 	void initializeMapping(); | ||||
|  | ||||
| private: | ||||
| 	/// The adjustment of R channel | ||||
| 	int _adjustR; | ||||
| 	/// The adjustment of G channel | ||||
| 	int _adjustG; | ||||
| 	/// The adjustment of B channel | ||||
| 	int _adjustB; | ||||
| 	 | ||||
| 	/// The adjustment of RGB channel | ||||
| 	uint8_t _adjust[3]; | ||||
| 	 | ||||
| 	/// The mapping from input color to output color | ||||
| 	int _mappingR[256]; | ||||
| 	int _mappingG[256]; | ||||
| 	int _mappingB[256]; | ||||
| 	uint8_t _mapping[3][256]; | ||||
| }; | ||||
|   | ||||
| @@ -1,66 +0,0 @@ | ||||
| #pragma once | ||||
|  | ||||
| // STL includes | ||||
| #include <cstdint> | ||||
|  | ||||
| /// Correction for a single color byte value | ||||
| /// All configuration values are unsigned int and assume the color value to be between 0 and 255 | ||||
| class RgbChannelCorrection | ||||
| { | ||||
| public: | ||||
| 	/// Default constructor | ||||
| 	RgbChannelCorrection(); | ||||
| 	 | ||||
| 	/// Constructor | ||||
| 	/// @param correctionR   | ||||
| 	/// @param correctionG  | ||||
| 	/// @param correctionB  | ||||
|  | ||||
| 	RgbChannelCorrection(int correctionR, int correctionG, int correctionB); | ||||
|  | ||||
| 	/// Destructor | ||||
| 	~RgbChannelCorrection(); | ||||
|  | ||||
| 	/// @return The current correctionR value | ||||
| 	uint8_t getcorrectionR() const; | ||||
|  | ||||
| 	/// @param threshold New correctionR value | ||||
| 	void setcorrectionR(uint8_t correctionR); | ||||
|  | ||||
| 	/// @return The current correctionG value | ||||
| 	uint8_t getcorrectionG() const; | ||||
|  | ||||
| 	/// @param gamma New correctionG value | ||||
| 	void setcorrectionG(uint8_t correctionG); | ||||
|  | ||||
| 	/// @return The current correctionB value | ||||
| 	uint8_t getcorrectionB() const; | ||||
|  | ||||
| 	/// @param blacklevel New correctionB value | ||||
| 	void setcorrectionB(uint8_t correctionB); | ||||
|  | ||||
| 	/// Transform the given array value | ||||
| 	/// @param input The input color bytes | ||||
| 	/// @return The corrected byte value | ||||
| 	uint8_t correctionR(uint8_t inputR) const; | ||||
| 	uint8_t correctionG(uint8_t inputG) const; | ||||
| 	uint8_t correctionB(uint8_t inputB) const; | ||||
|  | ||||
|  | ||||
| private: | ||||
| 	/// (re)-initilize the color mapping | ||||
| 	void initializeMapping(); | ||||
|  | ||||
| private: | ||||
| 	/// The correction of R channel | ||||
| 	int _correctionR; | ||||
| 	/// The correction of G channel | ||||
| 	int _correctionG; | ||||
| 	/// The correction of B channel | ||||
| 	int _correctionB; | ||||
| 	 | ||||
| 	/// The mapping from input color to output color | ||||
| 	int _mappingR[256]; | ||||
| 	int _mappingG[256]; | ||||
| 	int _mappingB[256]; | ||||
| }; | ||||
| @@ -28,6 +28,13 @@ public: | ||||
| 	/// Destructor | ||||
| 	~RgbChannelTransform(); | ||||
|  | ||||
| 	/// setAdjustment RGB | ||||
| 	/// @param threshold  The minimum threshold | ||||
| 	/// @param gamma The gamma of the gamma-curve correction | ||||
| 	/// @param blacklevel The minimum value for the RGB-Channel | ||||
| 	/// @param whitelevel The maximum value for the RGB-Channel | ||||
| 	void setTransform(double threshold, double gamma, double blacklevel, double whitelevel); | ||||
|  | ||||
| 	/// @return The current threshold value | ||||
| 	double getThreshold() const; | ||||
|  | ||||
|   | ||||
| @@ -22,15 +22,16 @@ | ||||
| // project includes | ||||
| #include "BoblightClientConnection.h" | ||||
|  | ||||
| BoblightClientConnection::BoblightClientConnection(QTcpSocket *socket, const int priority, Hyperion * hyperion) : | ||||
| 	QObject(), | ||||
| 	_locale(QLocale::C), | ||||
| 	_socket(socket), | ||||
| 	_imageProcessor(ImageProcessorFactory::getInstance().newImageProcessor()), | ||||
| 	_hyperion(hyperion), | ||||
| 	_receiveBuffer(), | ||||
| 	_priority(priority), | ||||
| 	_ledColors(hyperion->getLedCount(), ColorRgb::BLACK) | ||||
| BoblightClientConnection::BoblightClientConnection(QTcpSocket *socket, const int priority, Hyperion * hyperion) | ||||
| 	: QObject() | ||||
| 	, _locale(QLocale::C) | ||||
| 	, _socket(socket) | ||||
| 	, _imageProcessor(ImageProcessorFactory::getInstance().newImageProcessor()) | ||||
| 	, _hyperion(hyperion) | ||||
| 	, _receiveBuffer() | ||||
| 	, _priority(priority) | ||||
| 	, _ledColors(hyperion->getLedCount(), ColorRgb::BLACK) | ||||
| 	, _log(Logger::getInstance("BOBLIGHT")) | ||||
| { | ||||
| 	// initalize the locale. Start with the default C-locale | ||||
| 	_locale.setNumberOptions(QLocale::OmitGroupSeparator | QLocale::RejectGroupSeparator); | ||||
| @@ -70,7 +71,7 @@ void BoblightClientConnection::readData() | ||||
| 		// drop messages if the buffer is too full | ||||
| 		if (_receiveBuffer.size() > 100*1024) | ||||
| 		{ | ||||
| 			std::cout << "BOBLIGHT INFO: server drops messages (buffer full)" << std::endl; | ||||
| 			Debug(_log, "server drops messages (buffer full)"); | ||||
| 			_receiveBuffer.clear(); | ||||
| 		} | ||||
|  | ||||
| @@ -208,7 +209,7 @@ void BoblightClientConnection::handleMessage(const QString & message) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	std::cout << "BOBLIGHT INFO: unknown boblight message: " << message.toStdString() << std::endl; | ||||
| 	Debug(_log, "unknown boblight message: %s", message.toStdString().c_str()); | ||||
| } | ||||
|  | ||||
| void BoblightClientConnection::sendMessage(const std::string & message) | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
|  | ||||
| // Hyperion includes | ||||
| #include <hyperion/Hyperion.h> | ||||
| #include <utils/Logger.h> | ||||
|  | ||||
| class ImageProcessor; | ||||
|  | ||||
| @@ -100,4 +101,7 @@ private: | ||||
|  | ||||
| 	/// The latest led color data | ||||
| 	std::vector<ColorRgb> _ledColors; | ||||
| 	 | ||||
| 	/// logger instance | ||||
| 	Logger * _log; | ||||
| }; | ||||
|   | ||||
| @@ -5,29 +5,53 @@ | ||||
| #include <boblightserver/BoblightServer.h> | ||||
| #include "BoblightClientConnection.h" | ||||
|  | ||||
| BoblightServer::BoblightServer(const int priority,uint16_t port) : | ||||
| 	QObject(), | ||||
| 	_hyperion(Hyperion::getInstance()), | ||||
| 	_server(), | ||||
| 	_openConnections(), | ||||
| 	_priority(priority) | ||||
| BoblightServer::BoblightServer(const int priority, uint16_t port) | ||||
| 	: QObject() | ||||
| 	, _hyperion(Hyperion::getInstance()) | ||||
| 	, _server() | ||||
| 	, _openConnections() | ||||
| 	, _priority(priority) | ||||
| 	, _log(Logger::getInstance("BOBLIGHT")) | ||||
| 	, _isActive(false) | ||||
| 	, _port(port) | ||||
| { | ||||
| 	if (!_server.listen(QHostAddress::Any, port)) | ||||
| 	{ | ||||
| 		throw std::runtime_error("BOBLIGHT ERROR: server could not bind to port"); | ||||
| 	} | ||||
|  | ||||
| 	// Set trigger for incoming connections | ||||
| 	connect(&_server, SIGNAL(newConnection()), this, SLOT(newConnection())); | ||||
| } | ||||
|  | ||||
| BoblightServer::~BoblightServer() | ||||
| { | ||||
| 	stop(); | ||||
| } | ||||
|  | ||||
| void BoblightServer::start() | ||||
| { | ||||
| 	if ( active() ) | ||||
| 		return; | ||||
| 		 | ||||
| 	if (!_server.listen(QHostAddress::Any, _port)) | ||||
| 	{ | ||||
| 		throw std::runtime_error("BOBLIGHT ERROR: server could not bind to port"); | ||||
| 	} | ||||
| 	Info(_log, "Boblight server started on port %d", _port); | ||||
|  | ||||
| 	_isActive = true; | ||||
| 	emit statusChanged(_isActive); | ||||
| } | ||||
|  | ||||
| void BoblightServer::stop() | ||||
| { | ||||
| 	if ( ! active() ) | ||||
| 		return; | ||||
| 		 | ||||
| 	foreach (BoblightClientConnection * connection, _openConnections) { | ||||
| 		delete connection; | ||||
| 	} | ||||
| 	_isActive = false; | ||||
| 	emit statusChanged(_isActive); | ||||
| } | ||||
|  | ||||
|  | ||||
| uint16_t BoblightServer::getPort() const | ||||
| { | ||||
| 	return _server.serverPort(); | ||||
| @@ -39,7 +63,7 @@ void BoblightServer::newConnection() | ||||
|  | ||||
| 	if (socket != nullptr) | ||||
| 	{ | ||||
| 		std::cout << "BOBLIGHT INFO: new connection" << std::endl; | ||||
| 		Info(_log, "new connection"); | ||||
| 		BoblightClientConnection * connection = new BoblightClientConnection(socket, _priority, _hyperion); | ||||
| 		_openConnections.insert(connection); | ||||
|  | ||||
| @@ -50,7 +74,7 @@ void BoblightServer::newConnection() | ||||
|  | ||||
| void BoblightServer::closedConnection(BoblightClientConnection *connection) | ||||
| { | ||||
| 	std::cout << "BOBLIGHT INFO: connection closed" << std::endl; | ||||
| 	Debug(_log, "connection closed"); | ||||
| 	_openConnections.remove(connection); | ||||
|  | ||||
| 	// schedule to delete the connection object | ||||
|   | ||||
							
								
								
									
										18
									
								
								libsrc/grabber/amlogic/AmlogicGrabber.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										18
									
								
								libsrc/grabber/amlogic/AmlogicGrabber.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -3,7 +3,7 @@ | ||||
| #include <algorithm> | ||||
| #include <cassert> | ||||
| #include <iostream> | ||||
|  | ||||
| #include <utils/Logger.h> | ||||
| // Linux includes | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| @@ -30,7 +30,7 @@ AmlogicGrabber::AmlogicGrabber(const unsigned width, const unsigned height) : | ||||
| 	_height(std::max(160u, height)), | ||||
| 	_amlogicCaptureDev(-1) | ||||
| { | ||||
| 	std::cout << "AMLOGICGRABBER INFO: [" << __PRETTY_FUNCTION__ << "] constructed(" << _width << "x" << _height << ")" << std::endl; | ||||
| 	Info(_log, "[%s] constructed(%s x %s)",__PRETTY_FUNCTION__,_width,_height); | ||||
| } | ||||
|  | ||||
| AmlogicGrabber::~AmlogicGrabber() | ||||
| @@ -39,7 +39,7 @@ AmlogicGrabber::~AmlogicGrabber() | ||||
| 	{ | ||||
| 		if (close(_amlogicCaptureDev) == -1) | ||||
| 		{ | ||||
| 			std::cerr << "AMLOGICGRABBER ERROR: [" << __PRETTY_FUNCTION__ << "] Failed to close device (" << errno << ")" << std::endl; | ||||
| 			Error(_log, "[%s] Failed to close device (%s)",__PRETTY_FUNCTION__,errno); | ||||
| 		} | ||||
| 		_amlogicCaptureDev = -1; | ||||
| 	} | ||||
| @@ -69,7 +69,7 @@ bool AmlogicGrabber::isVideoPlaying() | ||||
| 	int video_fd = open(videoDevice.c_str(), O_RDONLY); | ||||
| 	if (video_fd < 0) | ||||
| 	{ | ||||
| 		std::cerr << "AMLOGICGRABBER ERROR: Failed to open video device(" << videoDevice << "): " << strerror(errno) << std::endl; | ||||
| 		Error(_log, "Failed to open video device(%s): %s",videoDevice.c_str(),strerror(errno)); | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| @@ -77,7 +77,7 @@ bool AmlogicGrabber::isVideoPlaying() | ||||
| 	int videoDisabled; | ||||
| 	if (ioctl(video_fd, AMSTREAM_IOC_GET_VIDEO_DISABLE, &videoDisabled) == -1) | ||||
| 	{ | ||||
| 		std::cerr << "AMLOGICGRABBER ERROR: Failed to retrieve video state from device: " << strerror(errno) << std::endl; | ||||
| 		Error(_log, "Failed to retrieve video state from device: %s",strerror(errno)); | ||||
| 		close(video_fd); | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -111,7 +111,7 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image) | ||||
| 		// If the device is still not open, there is something wrong | ||||
| 		if (_amlogicCaptureDev == -1) | ||||
| 		{ | ||||
| 			std::cerr << "AMLOGICGRABBER ERROR:[" << __PRETTY_FUNCTION__ << "] Failed to open the AMLOGIC device (" << errno << "): " << strerror(errno) << std::endl; | ||||
| 			Error(_log,"[%s] Failed to open the AMLOGIC device ():",__PRETTY_FUNCTION__,errno,strerror(errno)); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| @@ -121,7 +121,7 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image) | ||||
| 		ioctl(_amlogicCaptureDev, AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT, _height) == -1) | ||||
| 	{ | ||||
| 		// Failed to configure frame width | ||||
| 		std::cerr << "AMLOGICGRABBER ERROR: [" << __PRETTY_FUNCTION__ << "] Failed to configure capture size (" << errno << "): " << strerror(errno) << std::endl; | ||||
| 		Error(_log,"[%s] Failed to configure capture size (%s)",__PRETTY_FUNCTION__,errno,strerror(errno)); | ||||
| 		close(_amlogicCaptureDev); | ||||
| 		_amlogicCaptureDev = -1; | ||||
| 		return -1; | ||||
| @@ -134,7 +134,7 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image) | ||||
| 	const ssize_t bytesRead   = pread(_amlogicCaptureDev, image_ptr, bytesToRead, 0); | ||||
| 	if (bytesRead == -1) | ||||
| 	{ | ||||
| 		std::cerr << "AMLOGICGRABBER ERROR: [" << __PRETTY_FUNCTION__ << "] Read of device failed (erno=" << errno << "): " << strerror(errno) << std::endl; | ||||
| 		Error(_log,"[%s] Read of device failed (erno=%s): %s",__PRETTY_FUNCTION__,errno,strerror(errno)); | ||||
| 		close(_amlogicCaptureDev); | ||||
| 		_amlogicCaptureDev = -1; | ||||
| 		return -1; | ||||
| @@ -142,7 +142,7 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image) | ||||
| 	else if (bytesToRead != bytesRead) | ||||
| 	{ | ||||
| 		// Read of snapshot failed | ||||
| 		std::cerr << "AMLOGICGRABBER ERROR: [" << __PRETTY_FUNCTION__ << "] Capture failed to grab entire image [bytesToRead(" << bytesToRead << ") != bytesRead(" << bytesRead << ")]" << std::endl; | ||||
| 		Error(_log,"[%s] Capture failed to grab entire image [bytesToRead(%s) != bytesRead(%s)]",__PRETTY_FUNCTION__,bytesToRead,bytesRead); | ||||
| 		close(_amlogicCaptureDev); | ||||
| 		_amlogicCaptureDev = -1; | ||||
| 		return -1; | ||||
|   | ||||
							
								
								
									
										14
									
								
								libsrc/grabber/x11/X11Grabber.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										14
									
								
								libsrc/grabber/x11/X11Grabber.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -1,6 +1,7 @@ | ||||
| // STL includes | ||||
| #include <iostream> | ||||
| #include <cstdint> | ||||
| #include <utils/Logger.h> | ||||
|  | ||||
| // X11Grabber includes | ||||
| #include <grabber/X11Grabber.h> | ||||
| @@ -22,7 +23,8 @@ X11Grabber::X11Grabber(bool useXGetImage, int cropLeft, int cropRight, int cropT | ||||
| 	_screenHeight(0), | ||||
| 	_croppedWidth(0), | ||||
| 	_croppedHeight(0), | ||||
| 	_image(0,0) | ||||
| 	_image(0,0), | ||||
| 	_log(Logger::getInstance("X11GRABBER")) | ||||
| { | ||||
| 	_imageResampler.setHorizontalPixelDecimation(horizontalPixelDecimation); | ||||
| 	_imageResampler.setVerticalPixelDecimation(verticalPixelDecimation); | ||||
| @@ -94,11 +96,11 @@ bool X11Grabber::Setup() | ||||
| 	_x11Display = XOpenDisplay(NULL); | ||||
| 	if (_x11Display == nullptr) | ||||
| 	{ | ||||
| 		std::cerr << "X11GRABBER ERROR: Unable to open display"; | ||||
| 		Error(_log, "Unable to open display"); | ||||
| 		if (getenv("DISPLAY")) { | ||||
| 			std::cerr <<  " " << std::string(getenv("DISPLAY")) << std::endl; | ||||
| 			Error(_log, "%s",getenv("DISPLAY")); | ||||
| 		} else { | ||||
| 			std::cerr << ". DISPLAY environment variable not set" << std::endl; | ||||
| 			Error(_log, "DISPLAY environment variable not set"); | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -151,7 +153,7 @@ Image<ColorRgb> & X11Grabber::grab() | ||||
|  | ||||
| 	if (_xImage == nullptr) | ||||
| 	{ | ||||
| 		std::cerr << "X11GRABBER ERROR: Grab failed" << std::endl; | ||||
| 		Error(_log, "Grab Failed!"); | ||||
| 		return _image; | ||||
| 	} | ||||
|  | ||||
| @@ -165,7 +167,7 @@ int X11Grabber::updateScreenDimensions() | ||||
| 	const Status status = XGetWindowAttributes(_x11Display, _window, &_windowAttr); | ||||
| 	if (status == 0) | ||||
| 	{ | ||||
| 		std::cerr << "X11GRABBER ERROR: Failed to obtain window attributes" << std::endl; | ||||
| 		Error(_log, "Failed to obtain window attributes"); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| // STL includes | ||||
| #include <cassert> | ||||
| #include <exception> | ||||
| #include <sstream> | ||||
|  | ||||
| // QT includes | ||||
| #include <QDateTime> | ||||
| @@ -53,41 +54,29 @@ Hyperion* Hyperion::getInstance() | ||||
|  | ||||
| ColorOrder Hyperion::createColorOrder(const Json::Value &deviceConfig) | ||||
| { | ||||
| 	// deprecated: force BGR when the deprecated flag is present and set to true | ||||
| 	if (deviceConfig.get("bgr-output", false).asBool()) | ||||
| 	{ | ||||
| 		return ORDER_BGR; | ||||
| 	} | ||||
|  | ||||
| 	std::string order = deviceConfig.get("colorOrder", "rgb").asString(); | ||||
| 	if (order == "rgb") | ||||
| 	{ | ||||
| 		return ORDER_RGB; | ||||
| 	} | ||||
| 	else if (order == "bgr") | ||||
| 	if (order == "bgr") | ||||
| 	{ | ||||
| 		return ORDER_BGR; | ||||
| 	} | ||||
| 	else if (order == "rbg") | ||||
| 	if (order == "rbg") | ||||
| 	{ | ||||
| 		return ORDER_RBG; | ||||
| 	} | ||||
| 	else if (order == "brg") | ||||
| 	if (order == "brg") | ||||
| 	{ | ||||
| 		return ORDER_BRG; | ||||
| 	} | ||||
| 	else if (order == "gbr") | ||||
| 	if (order == "gbr") | ||||
| 	{ | ||||
| 		return ORDER_GBR; | ||||
| 	} | ||||
| 	else if (order == "grb") | ||||
| 	if (order == "grb") | ||||
| 	{ | ||||
| 		return ORDER_GRB; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		std::cout << "HYPERION ERROR: Unknown color order defined (" << order << "). Using RGB." << std::endl; | ||||
| 	} | ||||
|  | ||||
| 	WarningIf( order != "rgb", Logger::getInstance("Core"), "Unknown color order defined (%s). Using RGB.", order.c_str()); | ||||
|  | ||||
| 	return ORDER_RGB; | ||||
| } | ||||
| @@ -127,7 +116,7 @@ ColorCorrection * Hyperion::createColorCorrection(const Json::Value & correction | ||||
| { | ||||
| 	const std::string id = correctionConfig.get("id", "default").asString(); | ||||
|  | ||||
| 	RgbChannelCorrection * rgbCorrection   = createRgbChannelCorrection(correctionConfig["correctionValues"]); | ||||
| 	RgbChannelAdjustment * rgbCorrection   = createRgbChannelCorrection(correctionConfig["correctionValues"]); | ||||
|  | ||||
| 	ColorCorrection * correction = new ColorCorrection(); | ||||
| 	correction->_id = id; | ||||
| @@ -167,6 +156,7 @@ MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt, | ||||
| { | ||||
| 	// Create the result, the transforms are added to this | ||||
| 	MultiColorTransform * transform = new MultiColorTransform(ledCnt); | ||||
| 	Logger * log = Logger::getInstance("Core"); | ||||
|  | ||||
| 	const Json::Value transformConfig = colorConfig.get("transform", Json::nullValue); | ||||
| 	if (transformConfig.isNull()) | ||||
| @@ -197,18 +187,17 @@ MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt, | ||||
| 			{ | ||||
| 				// Special case for indices '*' => all leds | ||||
| 				transform->setTransformForLed(colorTransform->_id, 0, ledCnt-1); | ||||
| 				std::cout << "HYPERION INFO: ColorTransform '" << colorTransform->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl; | ||||
|  				Info(log, "ColorTransform '%s' => [0; %d]", colorTransform->_id.c_str(), ledCnt-1); | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			if (!overallExp.exactMatch(ledIndicesStr)) | ||||
| 			{ | ||||
| 				std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl; | ||||
| 				Error(log, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str()); | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			std::cout << "HYPERION INFO: ColorTransform '" << colorTransform->_id << "' => ["; | ||||
|  | ||||
| 			std::stringstream ss; | ||||
| 			const QStringList ledIndexList = ledIndicesStr.split(","); | ||||
| 			for (int i=0; i<ledIndexList.size(); ++i) { | ||||
| 				if (i > 0) | ||||
| @@ -231,92 +220,20 @@ MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt, | ||||
| 					std::cout << index; | ||||
| 				} | ||||
| 			} | ||||
| 			std::cout << "]" << std::endl; | ||||
| 			Info(log, "ColorTransform '%s' => [%s]", colorTransform->_id.c_str(), ss.str().c_str());  | ||||
| 		} | ||||
| 	} | ||||
| 	return transform; | ||||
| } | ||||
|  | ||||
| MultiColorCorrection * Hyperion::createLedColorsCorrection(const unsigned ledCnt, const Json::Value & colorConfig) | ||||
| { | ||||
| 	// Create the result, the corrections are added to this | ||||
| 	MultiColorCorrection * correction = new MultiColorCorrection(ledCnt); | ||||
|  | ||||
| 	const Json::Value correctionConfig = colorConfig.get("correction", Json::nullValue); | ||||
| 	if (correctionConfig.isNull()) | ||||
| 	{ | ||||
| 		// Old style color correction config (just one for all leds) | ||||
| 		ColorCorrection * colorCorrection = createColorCorrection(colorConfig); | ||||
| 		correction->addCorrection(colorCorrection); | ||||
| 		correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1); | ||||
| 	} | ||||
| 	else if (!correctionConfig.isArray()) | ||||
| 	{ | ||||
| 		ColorCorrection * colorCorrection = createColorCorrection(correctionConfig); | ||||
| 		correction->addCorrection(colorCorrection); | ||||
| 		correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		const QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*"); | ||||
|  | ||||
| 		for (Json::UInt i = 0; i < correctionConfig.size(); ++i) | ||||
| 		{ | ||||
| 			const Json::Value & config = correctionConfig[i]; | ||||
| 			ColorCorrection * colorCorrection = createColorCorrection(config); | ||||
| 			correction->addCorrection(colorCorrection); | ||||
|  | ||||
| 			const QString ledIndicesStr = QString(config.get("leds", "").asCString()).trimmed(); | ||||
| 			if (ledIndicesStr.compare("*") == 0) | ||||
| 			{ | ||||
| 				// Special case for indices '*' => all leds | ||||
| 				correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1); | ||||
| 				std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl; | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			if (!overallExp.exactMatch(ledIndicesStr)) | ||||
| 			{ | ||||
| 				std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl; | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => ["; | ||||
|  | ||||
| 			const QStringList ledIndexList = ledIndicesStr.split(","); | ||||
| 			for (int i=0; i<ledIndexList.size(); ++i) { | ||||
| 				if (i > 0) | ||||
| 				{ | ||||
| 					std::cout << ", "; | ||||
| 				} | ||||
| 				if (ledIndexList[i].contains("-")) | ||||
| 				{ | ||||
| 					QStringList ledIndices = ledIndexList[i].split("-"); | ||||
| 					int startInd = ledIndices[0].toInt(); | ||||
| 					int endInd   = ledIndices[1].toInt(); | ||||
|  | ||||
| 					correction->setCorrectionForLed(colorCorrection->_id, startInd, endInd); | ||||
| 					std::cout << startInd << "-" << endInd; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					int index = ledIndexList[i].toInt(); | ||||
| 					correction->setCorrectionForLed(colorCorrection->_id, index, index); | ||||
| 					std::cout << index; | ||||
| 				} | ||||
| 			} | ||||
| 			std::cout << "]" << std::endl; | ||||
| 		} | ||||
| 	} | ||||
| 	return correction; | ||||
| } | ||||
|  | ||||
| MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCnt, const Json::Value & colorConfig) | ||||
| { | ||||
| 	// Create the result, the corrections are added to this | ||||
| 	MultiColorCorrection * correction = new MultiColorCorrection(ledCnt); | ||||
| 	Logger * log = Logger::getInstance("Core"); | ||||
|  | ||||
| 	const Json::Value correctionConfig = colorConfig.get("temperature", Json::nullValue); | ||||
| 	const std::string jsonKey = colorConfig.isMember("temperature") ? "temperature" : "correction"; | ||||
| 	const Json::Value correctionConfig = colorConfig.get(jsonKey, Json::nullValue); | ||||
| 	if (correctionConfig.isNull()) | ||||
| 	{ | ||||
| 		// Old style color correction config (just one for all leds) | ||||
| @@ -345,23 +262,22 @@ MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCn | ||||
| 			{ | ||||
| 				// Special case for indices '*' => all leds | ||||
| 				correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1); | ||||
| 				std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl; | ||||
|  				Info(log, "ColorTemperature '%s' => [0; %d]", colorCorrection->_id.c_str(), ledCnt-1); | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			if (!overallExp.exactMatch(ledIndicesStr)) | ||||
| 			{ | ||||
| 				std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl; | ||||
| 				Error(log, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str()); | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => ["; | ||||
|  | ||||
| 			std::stringstream ss; | ||||
| 			const QStringList ledIndexList = ledIndicesStr.split(","); | ||||
| 			for (int i=0; i<ledIndexList.size(); ++i) { | ||||
| 				if (i > 0) | ||||
| 				{ | ||||
| 					std::cout << ", "; | ||||
| 					ss << ", "; | ||||
| 				} | ||||
| 				if (ledIndexList[i].contains("-")) | ||||
| 				{ | ||||
| @@ -370,25 +286,27 @@ MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCn | ||||
| 					int endInd   = ledIndices[1].toInt(); | ||||
|  | ||||
| 					correction->setCorrectionForLed(colorCorrection->_id, startInd, endInd); | ||||
| 					std::cout << startInd << "-" << endInd; | ||||
| 					ss << startInd << "-" << endInd; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					int index = ledIndexList[i].toInt(); | ||||
| 					correction->setCorrectionForLed(colorCorrection->_id, index, index); | ||||
| 					std::cout << index; | ||||
| 					ss << index; | ||||
| 				} | ||||
| 			} | ||||
| 			std::cout << "]" << std::endl; | ||||
| 			Info(log, "ColorTemperature '%s' => [%s]", colorCorrection->_id.c_str(), ss.str().c_str());  | ||||
| 		} | ||||
| 	} | ||||
| 	return correction; | ||||
| } | ||||
|  | ||||
|  | ||||
| MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt, const Json::Value & colorConfig) | ||||
| { | ||||
| 	// Create the result, the transforms are added to this | ||||
| 	MultiColorAdjustment * adjustment = new MultiColorAdjustment(ledCnt); | ||||
| 	Logger * log = Logger::getInstance("Core"); | ||||
|  | ||||
| 	const Json::Value adjustmentConfig = colorConfig.get("channelAdjustment", Json::nullValue); | ||||
| 	if (adjustmentConfig.isNull()) | ||||
| @@ -419,23 +337,22 @@ MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt | ||||
| 			{ | ||||
| 				// Special case for indices '*' => all leds | ||||
| 				adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1); | ||||
| 				std::cout << "HYPERION INFO: ColorAdjustment '" << colorAdjustment->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl; | ||||
|  				Info(log, "ColorAdjustment '%s' => [0; %d]", colorAdjustment->_id.c_str(), ledCnt-1); | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			if (!overallExp.exactMatch(ledIndicesStr)) | ||||
| 			{ | ||||
| 				std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl; | ||||
| 				Error(log, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str()); | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			std::cout << "HYPERION INFO: ColorAdjustment '" << colorAdjustment->_id << "' => ["; | ||||
|  | ||||
| 			std::stringstream ss; | ||||
| 			const QStringList ledIndexList = ledIndicesStr.split(","); | ||||
| 			for (int i=0; i<ledIndexList.size(); ++i) { | ||||
| 				if (i > 0) | ||||
| 				{ | ||||
| 					std::cout << ", "; | ||||
| 					ss << ", "; | ||||
| 				} | ||||
| 				if (ledIndexList[i].contains("-")) | ||||
| 				{ | ||||
| @@ -444,16 +361,16 @@ MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt | ||||
| 					int endInd   = ledIndices[1].toInt(); | ||||
|  | ||||
| 					adjustment->setAdjustmentForLed(colorAdjustment->_id, startInd, endInd); | ||||
| 					std::cout << startInd << "-" << endInd; | ||||
| 					ss << startInd << "-" << endInd; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					int index = ledIndexList[i].toInt(); | ||||
| 					adjustment->setAdjustmentForLed(colorAdjustment->_id, index, index); | ||||
| 					std::cout << index; | ||||
| 					ss << index; | ||||
| 				} | ||||
| 			} | ||||
| 			std::cout << "]" << std::endl; | ||||
| 			Info(log, "ColorAdjustment '%s' => [%s]", colorAdjustment->_id.c_str(), ss.str().c_str());  | ||||
| 		} | ||||
| 	} | ||||
| 	return adjustment; | ||||
| @@ -487,13 +404,13 @@ RgbChannelTransform* Hyperion::createRgbChannelTransform(const Json::Value& colo | ||||
| 	return transform; | ||||
| } | ||||
|  | ||||
| RgbChannelCorrection* Hyperion::createRgbChannelCorrection(const Json::Value& colorConfig) | ||||
| RgbChannelAdjustment* Hyperion::createRgbChannelCorrection(const Json::Value& colorConfig) | ||||
| { | ||||
| 	const int varR = colorConfig.get("red", 255).asInt(); | ||||
| 	const int varG = colorConfig.get("green", 255).asInt(); | ||||
| 	const int varB = colorConfig.get("blue", 255).asInt(); | ||||
|  | ||||
| 	RgbChannelCorrection* correction = new RgbChannelCorrection(varR, varG, varB); | ||||
| 	RgbChannelAdjustment* correction = new RgbChannelAdjustment(varR, varG, varB); | ||||
| 	return correction; | ||||
| } | ||||
|  | ||||
| @@ -611,7 +528,7 @@ MessageForwarder * Hyperion::createMessageForwarder(const Json::Value & forwarde | ||||
| 			{ | ||||
| 				for (const Json::Value& addr : forwarderConfig["json"]) | ||||
| 				{ | ||||
| 					std::cout << "HYPERION INFO: Json forward to " << addr.asString() << std::endl; | ||||
| 					Info(Logger::getInstance("Core"), "Json forward to %s", addr.asString().c_str()); | ||||
| 					forwarder->addJsonSlave(addr.asString()); | ||||
| 				} | ||||
| 			} | ||||
| @@ -620,7 +537,7 @@ MessageForwarder * Hyperion::createMessageForwarder(const Json::Value & forwarde | ||||
| 			{ | ||||
| 				for (const Json::Value& addr : forwarderConfig["proto"]) | ||||
| 				{ | ||||
| 					std::cout << "HYPERION INFO: Proto forward to " << addr.asString() << std::endl; | ||||
| 					Info(Logger::getInstance("Core"), "Proto forward to %s", addr.asString().c_str()); | ||||
| 					forwarder->addProtoSlave(addr.asString()); | ||||
| 				} | ||||
| 			} | ||||
| @@ -638,7 +555,6 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile) | ||||
| 	_ledString(createLedString(jsonConfig["leds"], createColorOrder(jsonConfig["device"]))), | ||||
| 	_muxer(_ledString.leds().size()), | ||||
| 	_raw2ledTransform(createLedColorsTransform(_ledString.leds().size(), jsonConfig["color"])), | ||||
| 	_raw2ledCorrection(createLedColorsCorrection(_ledString.leds().size(), jsonConfig["color"])), | ||||
| 	_raw2ledTemperature(createLedColorsTemperature(_ledString.leds().size(), jsonConfig["color"])), | ||||
| 	_raw2ledAdjustment(createLedColorsAdjustment(_ledString.leds().size(), jsonConfig["color"])), | ||||
| 	_device(LedDeviceFactory::construct(jsonConfig["device"])), | ||||
| @@ -646,16 +562,14 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile) | ||||
| 	_messageForwarder(createMessageForwarder(jsonConfig["forwarder"])), | ||||
| 	_jsonConfig(jsonConfig), | ||||
| 	_configFile(configFile), | ||||
| 	_timer() | ||||
| 	_timer(), | ||||
| 	_log(Logger::getInstance("Core")), | ||||
| 	_hwLedCount(_ledString.leds().size()) | ||||
| { | ||||
| 	if (!_raw2ledAdjustment->verifyAdjustments()) | ||||
| 	{ | ||||
| 		throw std::runtime_error("HYPERION ERROR: Color adjustment incorrectly set"); | ||||
| 	} | ||||
| 	if (!_raw2ledCorrection->verifyCorrections()) | ||||
| 	{ | ||||
| 		throw std::runtime_error("HYPERION ERROR: Color correction incorrectly set"); | ||||
| 	} | ||||
| 	if (!_raw2ledTemperature->verifyCorrections()) | ||||
| 	{ | ||||
| 		throw std::runtime_error("HYPERION ERROR: Color temperature incorrectly set"); | ||||
| @@ -679,6 +593,11 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile) | ||||
|  | ||||
| 	// create the effect engine | ||||
| 	_effectEngine = new EffectEngine(this, jsonConfig["effects"]); | ||||
| 	 | ||||
| 	unsigned int hwLedCount = jsonConfig["device"].get("ledCount",getLedCount()).asUInt(); | ||||
| 	_hwLedCount = std::max(hwLedCount, getLedCount()); | ||||
| 	Debug(_log,"configured leds: %d hw leds: %d", getLedCount(), _hwLedCount); | ||||
| 	WarningIf(hwLedCount < getLedCount(), _log, "more leds configured than available. check 'ledCount' in 'device' section"); | ||||
|  | ||||
| 	// initialize the leds | ||||
| 	update(); | ||||
| @@ -691,25 +610,12 @@ Hyperion::~Hyperion() | ||||
| 	clearall(); | ||||
| 	_device->switchOff(); | ||||
|  | ||||
| 	// delete the effect engine | ||||
| 	// delete components on exit of hyperion core | ||||
| 	delete _effectEngine; | ||||
|  | ||||
| 	// Delete the Led-String | ||||
| 	delete _device; | ||||
|  | ||||
| 	// delete the color transform | ||||
| 	delete _raw2ledTransform; | ||||
| 	 | ||||
| 	// delete the color correction | ||||
| 	delete _raw2ledCorrection; | ||||
|  | ||||
| 	// delete the color temperature correction | ||||
| 	delete _raw2ledTemperature; | ||||
| 	 | ||||
| 	// delete the color adjustment | ||||
| 	delete _raw2ledAdjustment; | ||||
|  | ||||
| 	// delete the message forwarder | ||||
| 	delete _messageForwarder; | ||||
| } | ||||
|  | ||||
| @@ -756,11 +662,6 @@ const std::vector<std::string> & Hyperion::getTransformIds() const | ||||
| 	return _raw2ledTransform->getTransformIds(); | ||||
| } | ||||
|  | ||||
| const std::vector<std::string> & Hyperion::getCorrectionIds() const | ||||
| { | ||||
| 	return _raw2ledCorrection->getCorrectionIds(); | ||||
| } | ||||
|  | ||||
| const std::vector<std::string> & Hyperion::getTemperatureIds() const | ||||
| { | ||||
| 	return _raw2ledTemperature->getCorrectionIds(); | ||||
| @@ -776,11 +677,6 @@ ColorTransform * Hyperion::getTransform(const std::string& id) | ||||
| 	return _raw2ledTransform->getTransform(id); | ||||
| } | ||||
|  | ||||
| ColorCorrection * Hyperion::getCorrection(const std::string& id) | ||||
| { | ||||
| 	return _raw2ledCorrection->getCorrection(id); | ||||
| } | ||||
|  | ||||
| ColorCorrection * Hyperion::getTemperature(const std::string& id) | ||||
| { | ||||
| 	return _raw2ledTemperature->getCorrection(id); | ||||
| @@ -884,15 +780,20 @@ void Hyperion::update() | ||||
| 	int priority = _muxer.getCurrentPriority(); | ||||
| 	const PriorityMuxer::InputInfo & priorityInfo  = _muxer.getInputInfo(priority); | ||||
|  | ||||
| 	// copy ledcolors to local buffer | ||||
| 	_ledBuffer.reserve(_hwLedCount); | ||||
| 	_ledBuffer = priorityInfo.ledColors; | ||||
|  | ||||
| 	// Apply the correction and the transform to each led and color-channel | ||||
| 	// Avoid applying correction, the same task is performed by adjustment | ||||
| 	// std::vector<ColorRgb> correctedColors = _raw2ledCorrection->applyCorrection(priorityInfo.ledColors); | ||||
| 	std::vector<ColorRgb> transformColors =_raw2ledTransform->applyTransform(priorityInfo.ledColors); | ||||
| 	std::vector<ColorRgb> adjustedColors = _raw2ledAdjustment->applyAdjustment(transformColors); | ||||
| 	std::vector<ColorRgb> ledColors = _raw2ledTemperature->applyCorrection(adjustedColors); | ||||
| 	_raw2ledTransform->applyTransform(_ledBuffer); | ||||
| 	_raw2ledAdjustment->applyAdjustment(_ledBuffer); | ||||
| 	_raw2ledTemperature->applyCorrection(_ledBuffer); | ||||
|  | ||||
| 	const std::vector<Led>& leds = _ledString.leds(); | ||||
|  | ||||
| 	int i = 0; | ||||
| 	for (ColorRgb& color : ledColors) | ||||
| 	for (ColorRgb& color : _ledBuffer) | ||||
| 	{ | ||||
| 		const ColorOrder ledColorOrder = leds.at(i).colorOrder; | ||||
| 		// correct the color byte order | ||||
| @@ -926,8 +827,13 @@ void Hyperion::update() | ||||
| 		i++; | ||||
| 	} | ||||
|  | ||||
| 	if ( _hwLedCount > _ledBuffer.size() ) | ||||
| 	{ | ||||
| 		_ledBuffer.resize(_hwLedCount, ColorRgb::BLACK); | ||||
| 	} | ||||
| 	 | ||||
| 	// Write the data to the device | ||||
| 	_device->write(ledColors); | ||||
| 	_device->write(_ledBuffer); | ||||
|  | ||||
| 	// Start the timeout-timer | ||||
| 	if (priorityInfo.timeoutTime_ms == -1) | ||||
|   | ||||
| @@ -3,10 +3,11 @@ | ||||
| #include <cassert> | ||||
|  | ||||
| // Hyperion includes | ||||
| #include <utils/Logger.h> | ||||
| #include "MultiColorAdjustment.h" | ||||
|  | ||||
| MultiColorAdjustment::MultiColorAdjustment(const unsigned ledCnt) : | ||||
| 	_ledAdjustments(ledCnt, nullptr) | ||||
| MultiColorAdjustment::MultiColorAdjustment(const unsigned ledCnt) | ||||
| 	: _ledAdjustments(ledCnt, nullptr) | ||||
| { | ||||
| } | ||||
|  | ||||
| @@ -40,16 +41,15 @@ void MultiColorAdjustment::setAdjustmentForLed(const std::string& id, const unsi | ||||
|  | ||||
| bool MultiColorAdjustment::verifyAdjustments() const | ||||
| { | ||||
| 	bool allLedsSet = true; | ||||
| 	for (unsigned iLed=0; iLed<_ledAdjustments.size(); ++iLed) | ||||
| 	{ | ||||
| 		if (_ledAdjustments[iLed] == nullptr) | ||||
| 		{ | ||||
| 			std::cerr << "HYPERION (C.adjustment) ERROR: No adjustment set for " << iLed << std::endl; | ||||
| 			allLedsSet = false; | ||||
| 			Warning(Logger::getInstance("ColorAdjust"), "No adjustment set for %d", iLed); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 	return allLedsSet; | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| const std::vector<std::string> & MultiColorAdjustment::getAdjustmentIds() | ||||
| @@ -72,12 +72,9 @@ ColorAdjustment* MultiColorAdjustment::getAdjustment(const std::string& id) | ||||
| 	return nullptr; | ||||
| } | ||||
|  | ||||
| std::vector<ColorRgb> MultiColorAdjustment::applyAdjustment(const std::vector<ColorRgb>& rawColors) | ||||
| void MultiColorAdjustment::applyAdjustment(std::vector<ColorRgb>& ledColors) | ||||
| { | ||||
| 	// Create a copy, as we will do the rest of the adjustment in place | ||||
| 	std::vector<ColorRgb> ledColors(rawColors); | ||||
|  | ||||
| 	const size_t itCnt = std::min(_ledAdjustments.size(), rawColors.size()); | ||||
| 	const size_t itCnt = std::min(_ledAdjustments.size(), ledColors.size()); | ||||
| 	for (size_t i=0; i<itCnt; ++i) | ||||
| 	{ | ||||
| 		ColorAdjustment* adjustment = _ledAdjustments[i]; | ||||
| @@ -101,11 +98,11 @@ std::vector<ColorRgb> MultiColorAdjustment::applyAdjustment(const std::vector<Co | ||||
| 		int BB = adjustment->_rgbBlueAdjustment.adjustmentB(color.blue); | ||||
| 				 | ||||
| 		int ledR = RR + GR + BR; | ||||
| 		int maxR = (int)adjustment->_rgbRedAdjustment.getadjustmentR(); | ||||
| 		int maxR = (int)adjustment->_rgbRedAdjustment.getAdjustmentR(); | ||||
| 		int ledG = RG + GG + BG; | ||||
| 		int maxG = (int)adjustment->_rgbGreenAdjustment.getadjustmentG(); | ||||
| 		int maxG = (int)adjustment->_rgbGreenAdjustment.getAdjustmentG(); | ||||
| 		int ledB = RB + GB + BB; | ||||
| 		int maxB = (int)adjustment->_rgbBlueAdjustment.getadjustmentB(); | ||||
| 		int maxB = (int)adjustment->_rgbBlueAdjustment.getAdjustmentB(); | ||||
| 		 | ||||
| 		if (ledR > maxR) | ||||
| 		  color.red = (uint8_t)maxR; | ||||
| @@ -122,5 +119,4 @@ std::vector<ColorRgb> MultiColorAdjustment::applyAdjustment(const std::vector<Co | ||||
| 		else | ||||
| 		  color.blue = (uint8_t)ledB; | ||||
| 	} | ||||
| 	return ledColors; | ||||
| } | ||||
|   | ||||
| @@ -48,11 +48,9 @@ public: | ||||
| 	/// | ||||
| 	/// Performs the color adjustment from raw-color to led-color | ||||
| 	/// | ||||
| 	/// @param rawColors The list with raw colors | ||||
| 	/// @param ledColors The list with raw colors | ||||
| 	/// | ||||
| 	/// @return The list with led-colors | ||||
| 	/// | ||||
| 	std::vector<ColorRgb> applyAdjustment(const std::vector<ColorRgb>& rawColors); | ||||
| 	void applyAdjustment(std::vector<ColorRgb>& ledColors); | ||||
|  | ||||
| private: | ||||
| 	/// List with transform ids | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #include <cassert> | ||||
|  | ||||
| // Hyperion includes | ||||
| #include <utils/Logger.h> | ||||
| #include "MultiColorCorrection.h" | ||||
|  | ||||
| MultiColorCorrection::MultiColorCorrection(const unsigned ledCnt) : | ||||
| @@ -40,16 +41,15 @@ void MultiColorCorrection::setCorrectionForLed(const std::string& id, const unsi | ||||
|  | ||||
| bool MultiColorCorrection::verifyCorrections() const | ||||
| { | ||||
| 	bool allLedsSet = true; | ||||
| 	for (unsigned iLed=0; iLed<_ledCorrections.size(); ++iLed) | ||||
| 	{ | ||||
| 		if (_ledCorrections[iLed] == nullptr) | ||||
| 		{ | ||||
| 			std::cerr << "HYPERION (C.correction) ERROR: No correction set for " << iLed << std::endl; | ||||
| 			allLedsSet = false; | ||||
| 			Warning(Logger::getInstance("ColorCorrect"), "No adjustment set for %d", iLed); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 	return allLedsSet; | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| const std::vector<std::string> & MultiColorCorrection::getCorrectionIds() | ||||
| @@ -72,12 +72,9 @@ ColorCorrection* MultiColorCorrection::getCorrection(const std::string& id) | ||||
| 	return nullptr; | ||||
| } | ||||
|  | ||||
| std::vector<ColorRgb> MultiColorCorrection::applyCorrection(const std::vector<ColorRgb>& rawColors) | ||||
| void MultiColorCorrection::applyCorrection(std::vector<ColorRgb>& ledColors) | ||||
| { | ||||
| 	// Create a copy, as we will do the rest of the correction in place | ||||
| 	std::vector<ColorRgb> ledColors(rawColors); | ||||
|  | ||||
| 	const size_t itCnt = std::min(_ledCorrections.size(), rawColors.size()); | ||||
| 	const size_t itCnt = std::min(_ledCorrections.size(), ledColors.size()); | ||||
| 	for (size_t i=0; i<itCnt; ++i) | ||||
| 	{ | ||||
| 		ColorCorrection * correction = _ledCorrections[i]; | ||||
| @@ -88,9 +85,8 @@ std::vector<ColorRgb> MultiColorCorrection::applyCorrection(const std::vector<Co | ||||
| 		} | ||||
| 		ColorRgb& color = ledColors[i]; | ||||
|  | ||||
| 		color.red   = correction->_rgbCorrection.correctionR(color.red); | ||||
| 		color.green = correction->_rgbCorrection.correctionG(color.green); | ||||
| 		color.blue  = correction->_rgbCorrection.correctionB(color.blue); | ||||
| 		color.red   = correction->_rgbCorrection.adjustmentR(color.red); | ||||
| 		color.green = correction->_rgbCorrection.adjustmentG(color.green); | ||||
| 		color.blue  = correction->_rgbCorrection.adjustmentB(color.blue); | ||||
| 	} | ||||
| 	return ledColors; | ||||
| } | ||||
|   | ||||
| @@ -48,11 +48,9 @@ public: | ||||
| 	/// | ||||
| 	/// Performs the color transoformation from raw-color to led-color | ||||
| 	/// | ||||
| 	/// @param rawColors The list with raw colors | ||||
| 	/// @param ledColors The list with led colors | ||||
| 	/// | ||||
| 	/// @return The list with led-colors | ||||
| 	/// | ||||
| 	std::vector<ColorRgb> applyCorrection(const std::vector<ColorRgb>& rawColors); | ||||
| 	void applyCorrection(std::vector<ColorRgb>& ledColors); | ||||
|  | ||||
| private: | ||||
| 	/// List with Correction ids | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #include <cassert> | ||||
|  | ||||
| // Hyperion includes | ||||
| #include <utils/Logger.h> | ||||
| #include "MultiColorTransform.h" | ||||
|  | ||||
| MultiColorTransform::MultiColorTransform(const unsigned ledCnt) : | ||||
| @@ -40,16 +41,15 @@ void MultiColorTransform::setTransformForLed(const std::string& id, const unsign | ||||
|  | ||||
| bool MultiColorTransform::verifyTransforms() const | ||||
| { | ||||
| 	bool allLedsSet = true; | ||||
| 	for (unsigned iLed=0; iLed<_ledTransforms.size(); ++iLed) | ||||
| 	{ | ||||
| 		if (_ledTransforms[iLed] == nullptr) | ||||
| 		{ | ||||
| 			std::cerr << "HYPERION (C.transform) ERROR: No transform set for " << iLed << std::endl; | ||||
| 			allLedsSet = false; | ||||
| 			Warning(Logger::getInstance("ColorTransform"), "No adjustment set for %d", iLed); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 	return allLedsSet; | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| const std::vector<std::string> & MultiColorTransform::getTransformIds() | ||||
| @@ -72,12 +72,9 @@ ColorTransform* MultiColorTransform::getTransform(const std::string& id) | ||||
| 	return nullptr; | ||||
| } | ||||
|  | ||||
| std::vector<ColorRgb> MultiColorTransform::applyTransform(const std::vector<ColorRgb>& rawColors) | ||||
| void MultiColorTransform::applyTransform(std::vector<ColorRgb>& ledColors) | ||||
| { | ||||
| 	// Create a copy, as we will do the rest of the transformation in place | ||||
| 	std::vector<ColorRgb> ledColors(rawColors); | ||||
|  | ||||
| 	const size_t itCnt = std::min(_ledTransforms.size(), rawColors.size()); | ||||
| 	const size_t itCnt = std::min(_ledTransforms.size(), ledColors.size()); | ||||
| 	for (size_t i=0; i<itCnt; ++i) | ||||
| 	{ | ||||
| 		ColorTransform* transform = _ledTransforms[i]; | ||||
| @@ -94,5 +91,4 @@ std::vector<ColorRgb> MultiColorTransform::applyTransform(const std::vector<Colo | ||||
| 		color.green = transform->_rgbGreenTransform.transform(color.green); | ||||
| 		color.blue  = transform->_rgbBlueTransform.transform(color.blue); | ||||
| 	} | ||||
| 	return ledColors; | ||||
| } | ||||
|   | ||||
| @@ -48,11 +48,9 @@ public: | ||||
| 	/// | ||||
| 	/// Performs the color transoformation from raw-color to led-color | ||||
| 	/// | ||||
| 	/// @param rawColors The list with raw colors | ||||
| 	/// @param ledColors The list with raw colors | ||||
| 	/// | ||||
| 	/// @return The list with led-colors | ||||
| 	/// | ||||
| 	std::vector<ColorRgb> applyTransform(const std::vector<ColorRgb>& rawColors); | ||||
| 	void applyTransform(std::vector<ColorRgb>& ledColors); | ||||
|  | ||||
| private: | ||||
| 	/// List with transform ids | ||||
|   | ||||
| @@ -251,8 +251,6 @@ void JsonClientConnection::handleMessage(const std::string &messageString) | ||||
| 		handleClearallCommand(message); | ||||
| 	else if (command == "transform") | ||||
| 		handleTransformCommand(message); | ||||
| 	else if (command == "correction") | ||||
| 		handleCorrectionCommand(message); | ||||
| 	else if (command == "temperature") | ||||
| 		handleTemperatureCommand(message); | ||||
| 	else if (command == "adjustment") | ||||
| @@ -398,26 +396,6 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &) | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	// collect correction information | ||||
| 	Json::Value & correctionArray = info["correction"]; | ||||
| 	for (const std::string& correctionId : _hyperion->getCorrectionIds()) | ||||
| 	{ | ||||
| 		const ColorCorrection * colorCorrection = _hyperion->getCorrection(correctionId); | ||||
| 		if (colorCorrection == nullptr) | ||||
| 		{ | ||||
| 			std::cerr << "JSONCLIENT ERROR: Incorrect color correction id: " << correctionId << std::endl; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		Json::Value & correction = correctionArray.append(Json::Value()); | ||||
| 		correction["id"] = correctionId; | ||||
| 		 | ||||
| 		Json::Value & corrValues = correction["correctionValues"]; | ||||
| 		corrValues.append(colorCorrection->_rgbCorrection.getcorrectionR()); | ||||
| 		corrValues.append(colorCorrection->_rgbCorrection.getcorrectionG()); | ||||
| 		corrValues.append(colorCorrection->_rgbCorrection.getcorrectionB()); | ||||
| 	} | ||||
| 	 | ||||
| 	// collect temperature correction information | ||||
| 	Json::Value & temperatureArray = info["temperature"]; | ||||
| 	for (const std::string& tempId : _hyperion->getTemperatureIds()) | ||||
| @@ -433,9 +411,9 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &) | ||||
| 		temperature["id"] = tempId; | ||||
| 		 | ||||
| 		Json::Value & tempValues = temperature["correctionValues"]; | ||||
| 		tempValues.append(colorTemp->_rgbCorrection.getcorrectionR()); | ||||
| 		tempValues.append(colorTemp->_rgbCorrection.getcorrectionG()); | ||||
| 		tempValues.append(colorTemp->_rgbCorrection.getcorrectionB()); | ||||
| 		tempValues.append(colorTemp->_rgbCorrection.getAdjustmentR()); | ||||
| 		tempValues.append(colorTemp->_rgbCorrection.getAdjustmentG()); | ||||
| 		tempValues.append(colorTemp->_rgbCorrection.getAdjustmentB()); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @@ -492,17 +470,17 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &) | ||||
| 		adjustment["id"] = adjustmentId; | ||||
|  | ||||
| 		Json::Value & redAdjust = adjustment["redAdjust"]; | ||||
| 		redAdjust.append(colorAdjustment->_rgbRedAdjustment.getadjustmentR()); | ||||
| 		redAdjust.append(colorAdjustment->_rgbRedAdjustment.getadjustmentG()); | ||||
| 		redAdjust.append(colorAdjustment->_rgbRedAdjustment.getadjustmentB()); | ||||
| 		redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentR()); | ||||
| 		redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentG()); | ||||
| 		redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentB()); | ||||
| 		Json::Value & greenAdjust = adjustment["greenAdjust"]; | ||||
| 		greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getadjustmentR()); | ||||
| 		greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getadjustmentG()); | ||||
| 		greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getadjustmentB()); | ||||
| 		greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentR()); | ||||
| 		greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentG()); | ||||
| 		greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentB()); | ||||
| 		Json::Value & blueAdjust = adjustment["blueAdjust"]; | ||||
| 		blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getadjustmentR()); | ||||
| 		blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getadjustmentG()); | ||||
| 		blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getadjustmentB()); | ||||
| 		blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentR()); | ||||
| 		blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentG()); | ||||
| 		blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentB()); | ||||
| 	} | ||||
|  | ||||
| 	// collect effect info | ||||
| @@ -706,32 +684,7 @@ void JsonClientConnection::handleTransformCommand(const Json::Value &message) | ||||
| 	sendSuccessReply(); | ||||
| } | ||||
|  | ||||
| void JsonClientConnection::handleCorrectionCommand(const Json::Value &message) | ||||
| { | ||||
| 	const Json::Value & correction = message["correction"]; | ||||
|  | ||||
| 	const std::string correctionId = correction.get("id", _hyperion->getCorrectionIds().front()).asString(); | ||||
| 	ColorCorrection * colorCorrection = _hyperion->getCorrection(correctionId); | ||||
| 	if (colorCorrection == nullptr) | ||||
| 	{ | ||||
| 		//sendErrorReply(std::string("Incorrect correction identifier: ") + correctionId); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (correction.isMember("correctionValues")) | ||||
| 	{ | ||||
| 		const Json::Value & values = correction["correctionValues"]; | ||||
| 		colorCorrection->_rgbCorrection.setcorrectionR(values[0u].asInt()); | ||||
| 		colorCorrection->_rgbCorrection.setcorrectionG(values[1u].asInt()); | ||||
| 		colorCorrection->_rgbCorrection.setcorrectionB(values[2u].asInt()); | ||||
| 	} | ||||
| 	 | ||||
| 	// commit the changes | ||||
| 	_hyperion->correctionsUpdated(); | ||||
|  | ||||
| 	sendSuccessReply(); | ||||
| } | ||||
| 	 | ||||
| void JsonClientConnection::handleTemperatureCommand(const Json::Value &message) | ||||
| { | ||||
| 	const Json::Value & temperature = message["temperature"]; | ||||
| @@ -747,9 +700,9 @@ void JsonClientConnection::handleTemperatureCommand(const Json::Value &message) | ||||
| 	if (temperature.isMember("correctionValues")) | ||||
| 	{ | ||||
| 		const Json::Value & values = temperature["correctionValues"]; | ||||
| 		colorTemperature->_rgbCorrection.setcorrectionR(values[0u].asInt()); | ||||
| 		colorTemperature->_rgbCorrection.setcorrectionG(values[1u].asInt()); | ||||
| 		colorTemperature->_rgbCorrection.setcorrectionB(values[2u].asInt()); | ||||
| 		colorTemperature->_rgbCorrection.setAdjustmentR(values[0u].asInt()); | ||||
| 		colorTemperature->_rgbCorrection.setAdjustmentG(values[1u].asInt()); | ||||
| 		colorTemperature->_rgbCorrection.setAdjustmentB(values[2u].asInt()); | ||||
| 	} | ||||
| 	 | ||||
| 	// commit the changes | ||||
| @@ -773,25 +726,25 @@ void JsonClientConnection::handleAdjustmentCommand(const Json::Value &message) | ||||
| 	if (adjustment.isMember("redAdjust")) | ||||
| 	{ | ||||
| 		const Json::Value & values = adjustment["redAdjust"]; | ||||
| 		colorAdjustment->_rgbRedAdjustment.setadjustmentR(values[0u].asInt()); | ||||
| 		colorAdjustment->_rgbRedAdjustment.setadjustmentG(values[1u].asInt()); | ||||
| 		colorAdjustment->_rgbRedAdjustment.setadjustmentB(values[2u].asInt()); | ||||
| 		colorAdjustment->_rgbRedAdjustment.setAdjustmentR(values[0u].asInt()); | ||||
| 		colorAdjustment->_rgbRedAdjustment.setAdjustmentG(values[1u].asInt()); | ||||
| 		colorAdjustment->_rgbRedAdjustment.setAdjustmentB(values[2u].asInt()); | ||||
| 	} | ||||
|  | ||||
| 	if (adjustment.isMember("greenAdjust")) | ||||
| 	{ | ||||
| 		const Json::Value & values = adjustment["greenAdjust"]; | ||||
| 		colorAdjustment->_rgbGreenAdjustment.setadjustmentR(values[0u].asInt()); | ||||
| 		colorAdjustment->_rgbGreenAdjustment.setadjustmentG(values[1u].asInt()); | ||||
| 		colorAdjustment->_rgbGreenAdjustment.setadjustmentB(values[2u].asInt()); | ||||
| 		colorAdjustment->_rgbGreenAdjustment.setAdjustmentR(values[0u].asInt()); | ||||
| 		colorAdjustment->_rgbGreenAdjustment.setAdjustmentG(values[1u].asInt()); | ||||
| 		colorAdjustment->_rgbGreenAdjustment.setAdjustmentB(values[2u].asInt()); | ||||
| 	} | ||||
|  | ||||
| 	if (adjustment.isMember("blueAdjust")) | ||||
| 	{ | ||||
| 		const Json::Value & values = adjustment["blueAdjust"]; | ||||
| 		colorAdjustment->_rgbBlueAdjustment.setadjustmentR(values[0u].asInt()); | ||||
| 		colorAdjustment->_rgbBlueAdjustment.setadjustmentG(values[1u].asInt()); | ||||
| 		colorAdjustment->_rgbBlueAdjustment.setadjustmentB(values[2u].asInt()); | ||||
| 		colorAdjustment->_rgbBlueAdjustment.setAdjustmentR(values[0u].asInt()); | ||||
| 		colorAdjustment->_rgbBlueAdjustment.setAdjustmentG(values[1u].asInt()); | ||||
| 		colorAdjustment->_rgbBlueAdjustment.setAdjustmentB(values[2u].asInt()); | ||||
| 	}	 | ||||
| 	// commit the changes | ||||
| 	_hyperion->adjustmentsUpdated(); | ||||
|   | ||||
| @@ -113,13 +113,6 @@ private: | ||||
| 	/// | ||||
| 	void handleTransformCommand(const Json::Value & message); | ||||
| 	 | ||||
| 	/// | ||||
| 	/// Handle an incoming JSON Correction message | ||||
| 	/// | ||||
| 	/// @param message the incoming message | ||||
| 	/// | ||||
| 	void handleCorrectionCommand(const Json::Value & message); | ||||
| 	 | ||||
| 	/// | ||||
| 	/// Handle an incoming JSON Temperature message | ||||
| 	/// | ||||
|   | ||||
| @@ -79,6 +79,7 @@ if(ENABLE_SPIDEV) | ||||
| 		${CURRENT_SOURCE_DIR}/LedDeviceP9813.h | ||||
| 		${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h | ||||
| 		${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.h | ||||
| 		${CURRENT_SOURCE_DIR}/LedDeviceSk6812SPI.h | ||||
| 		${CURRENT_SOURCE_DIR}/LedDeviceAPA102.h | ||||
| 	) | ||||
| 	SET(Leddevice_SOURCES | ||||
| @@ -89,6 +90,7 @@ if(ENABLE_SPIDEV) | ||||
| 		${CURRENT_SOURCE_DIR}/LedDeviceP9813.cpp | ||||
| 		${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp | ||||
| 		${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.cpp | ||||
| 		${CURRENT_SOURCE_DIR}/LedDeviceSk6812SPI.cpp | ||||
| 		${CURRENT_SOURCE_DIR}/LedDeviceAPA102.cpp | ||||
| 	) | ||||
| endif() | ||||
|   | ||||
| @@ -12,20 +12,18 @@ | ||||
| // hyperion local includes | ||||
| #include "LedDeviceAPA102.h" | ||||
|  | ||||
| LedDeviceAPA102::LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate, const unsigned ledcount) : | ||||
| 	LedSpiDevice(outputDevice, baudrate, 500000), | ||||
| 	_ledBuffer(0) | ||||
| LedDeviceAPA102::LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate) | ||||
| 	: LedSpiDevice(outputDevice, baudrate, 500000) | ||||
| 	, _ledBuffer(0) | ||||
| { | ||||
| 	_HW_ledcount = ledcount; | ||||
| } | ||||
|  | ||||
| int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues) | ||||
| { | ||||
| 	_mLedCount = ledValues.size(); | ||||
| 	const unsigned int max_leds = std::max(_mLedCount, _HW_ledcount); | ||||
| 	const unsigned int startFrameSize = 4; | ||||
| 	const unsigned int endFrameSize = std::max<unsigned int>(((max_leds + 15) / 16), 4); | ||||
| 	const unsigned int APAbufferSize = (max_leds * 4) + startFrameSize + endFrameSize; | ||||
| 	const unsigned int endFrameSize = std::max<unsigned int>(((_mLedCount + 15) / 16), 4); | ||||
| 	const unsigned int APAbufferSize = (_mLedCount * 4) + startFrameSize + endFrameSize; | ||||
|  | ||||
| 	if(_ledBuffer.size() != APAbufferSize){ | ||||
| 		_ledBuffer.resize(APAbufferSize, 0xFF); | ||||
| @@ -35,8 +33,7 @@ int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues) | ||||
| 		_ledBuffer[3] = 0x00;  | ||||
| 	} | ||||
| 	 | ||||
| 	unsigned iLed=0; | ||||
| 	for (iLed=0; iLed < _mLedCount; ++iLed) { | ||||
| 	for (unsigned iLed=0; iLed < _mLedCount; ++iLed) { | ||||
| 		const ColorRgb& rgb = ledValues[iLed]; | ||||
| 		_ledBuffer[4+iLed*4]   = 0xFF; | ||||
| 		_ledBuffer[4+iLed*4+1] = rgb.red; | ||||
| @@ -44,13 +41,6 @@ int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues) | ||||
| 		_ledBuffer[4+iLed*4+3] = rgb.blue; | ||||
| 	} | ||||
|  | ||||
| 	for ( ; iLed < max_leds; ++iLed) { | ||||
| 		_ledBuffer[4+iLed*4]   = 0xFF; | ||||
| 		_ledBuffer[4+iLed*4+1] = 0x00; | ||||
| 		_ledBuffer[4+iLed*4+2] = 0x00; | ||||
| 		_ledBuffer[4+iLed*4+3] = 0x00; | ||||
| 	} | ||||
|  | ||||
| 	return writeBytes(_ledBuffer.size(), _ledBuffer.data()); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -17,11 +17,10 @@ public: | ||||
| 	/// | ||||
| 	/// Constructs the LedDevice for a string containing leds of the type APA102 | ||||
| 	/// | ||||
| 	/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0') | ||||
| 	/// @param outputDevice The name of the output device (eg '/dev/spidev.0.0') | ||||
| 	/// @param baudrate The used baudrate for writing to the output device | ||||
| 	/// | ||||
| 	LedDeviceAPA102(const std::string& outputDevice, | ||||
| 					const unsigned baudrate, const unsigned ledcount ); | ||||
| 	LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate ); | ||||
|  | ||||
|  | ||||
| 	/// | ||||
| @@ -39,7 +38,6 @@ private: | ||||
|  | ||||
| 	/// The buffer containing the packed RGB values | ||||
| 	std::vector<uint8_t> _ledBuffer; | ||||
| 	unsigned int _HW_ledcount; | ||||
| 	unsigned int _mLedCount; | ||||
|  | ||||
| }; | ||||
|   | ||||
| @@ -17,6 +17,7 @@ | ||||
| 	#include "LedDeviceP9813.h" | ||||
| 	#include "LedDeviceWs2801.h" | ||||
| 	#include "LedDeviceWs2812SPI.h" | ||||
| 	#include "LedDeviceSk6812SPI.h" | ||||
| 	#include "LedDeviceAPA102.h" | ||||
| #endif | ||||
|  | ||||
| @@ -119,9 +120,8 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) | ||||
| 	{ | ||||
| 		const std::string output = deviceConfig["output"].asString(); | ||||
| 		const unsigned rate      = deviceConfig["rate"].asInt(); | ||||
| 		const unsigned ledcount  = deviceConfig.get("leds",0).asInt(); | ||||
|  | ||||
| 		LedDeviceAPA102* deviceAPA102 = new LedDeviceAPA102(output, rate, ledcount); | ||||
| 		LedDeviceAPA102* deviceAPA102 = new LedDeviceAPA102(output, rate); | ||||
| 		deviceAPA102->open(); | ||||
|  | ||||
| 		device = deviceAPA102; | ||||
| @@ -147,6 +147,16 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) | ||||
|  | ||||
| 		device = deviceWs2812SPI; | ||||
| 	} | ||||
| 	else if (type == "sk6812spi") | ||||
| 	{ | ||||
| 		const std::string output = deviceConfig["output"].asString(); | ||||
| 		const unsigned rate      = deviceConfig.get("rate",2857143).asInt(); | ||||
|  | ||||
| 		LedDeviceSk6812SPI* deviceSk6812SPI = new LedDeviceSk6812SPI(output, rate); | ||||
| 		deviceSk6812SPI->open(); | ||||
|  | ||||
| 		device = deviceSk6812SPI; | ||||
| 	} | ||||
| #endif | ||||
| #ifdef ENABLE_TINKERFORGE | ||||
| 	else if (type=="tinkerforge") | ||||
| @@ -215,7 +225,7 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) | ||||
| 		const Json::Value gpioMapping = deviceConfig.get("gpiomap", Json::nullValue); | ||||
|  | ||||
| 		if (assignment.length() > 0) { | ||||
| 			std::cout << "ERROR: Sorry, the configuration syntax has changed in this version." << std::endl; | ||||
| 			Error(log, "Piblaster: The piblaster configuration syntax has changed in this version."); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 		if (! gpioMapping.isNull() ) { | ||||
| @@ -224,7 +234,7 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) | ||||
|  | ||||
| 			device = devicePiBlaster; | ||||
| 		} else { | ||||
| 			std::cout << "ERROR: no gpiomap defined." << std::endl; | ||||
| 			Error(log, "Piblaster: no gpiomap defined."); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										67
									
								
								libsrc/leddevice/LedDeviceSk6812SPI.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								libsrc/leddevice/LedDeviceSk6812SPI.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
|  | ||||
| // STL includes | ||||
| #include <cstring> | ||||
| #include <cstdio> | ||||
| #include <iostream> | ||||
|  | ||||
| // Linux includes | ||||
| #include <fcntl.h> | ||||
| #include <sys/ioctl.h> | ||||
|  | ||||
| // hyperion local includes | ||||
| #include "LedDeviceSk6812SPI.h" | ||||
|  | ||||
| LedDeviceSk6812SPI::LedDeviceSk6812SPI(const std::string& outputDevice, const unsigned baudrate) : | ||||
| 	LedSpiDevice(outputDevice, baudrate, 0), | ||||
| 	mLedCount(0), | ||||
| 	bitpair_to_byte { | ||||
| 		0b10001000, | ||||
| 		0b10001100, | ||||
| 		0b11001000, | ||||
| 		0b11001100, | ||||
| 	} | ||||
|  | ||||
| { | ||||
| 	// empty | ||||
| } | ||||
|  | ||||
| int LedDeviceSk6812SPI::write(const std::vector<ColorRgb> &ledValues) | ||||
| { | ||||
| 	mLedCount = ledValues.size(); | ||||
|  | ||||
| // 4 colours, 4 spi bytes per colour + 3 frame end latch bytes | ||||
| #define COLOURS_PER_LED		3 | ||||
| #define SPI_BYTES_PER_COLOUR	4 | ||||
| #define SPI_BYTES_PER_LED 	COLOURS_PER_LED * SPI_BYTES_PER_COLOUR | ||||
|  | ||||
| 	unsigned spi_size = mLedCount * SPI_BYTES_PER_LED + 3; | ||||
| 	if(_spiBuffer.size() != spi_size){ | ||||
|                 _spiBuffer.resize(spi_size, 0x00); | ||||
| 	} | ||||
|  | ||||
| 	unsigned spi_ptr = 0; | ||||
|         for (unsigned i=0; i< mLedCount; ++i) { | ||||
| 		uint8_t white = 0; | ||||
| 		uint32_t colorBits =  | ||||
| 			((unsigned int)ledValues[i].red << 24) | | ||||
| 			((unsigned int)ledValues[i].green << 16) | | ||||
| 			((unsigned int)ledValues[i].blue << 8) | | ||||
| 			white; | ||||
|  | ||||
| 		for (int j=SPI_BYTES_PER_LED - 1; j>=0; j--) { | ||||
| 			_spiBuffer[spi_ptr+j] = bitpair_to_byte[ colorBits & 0x3 ]; | ||||
| 			colorBits >>= 2; | ||||
| 		} | ||||
| 		spi_ptr += SPI_BYTES_PER_LED; | ||||
|         } | ||||
| 	_spiBuffer[spi_ptr++] = 0; | ||||
| 	_spiBuffer[spi_ptr++] = 0; | ||||
| 	_spiBuffer[spi_ptr++] = 0; | ||||
|  | ||||
| 	return writeBytes(spi_size, _spiBuffer.data()); | ||||
| } | ||||
|  | ||||
| int LedDeviceSk6812SPI::switchOff() | ||||
| { | ||||
| 	return write(std::vector<ColorRgb>(mLedCount, ColorRgb{0,0,0})); | ||||
| } | ||||
							
								
								
									
										43
									
								
								libsrc/leddevice/LedDeviceSk6812SPI.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								libsrc/leddevice/LedDeviceSk6812SPI.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| #pragma once | ||||
|  | ||||
| // STL includes | ||||
| #include <string> | ||||
|  | ||||
| // hyperion incluse | ||||
| #include "LedSpiDevice.h" | ||||
|  | ||||
| /// | ||||
| /// Implementation of the LedDevice interface for writing to Sk6801 led device. | ||||
| /// | ||||
| class LedDeviceSk6812SPI : public LedSpiDevice | ||||
| { | ||||
| public: | ||||
| 	/// | ||||
| 	/// Constructs the LedDevice for a string containing leds of the type Sk6812SPI | ||||
| 	/// | ||||
| 	/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0') | ||||
| 	/// @param baudrate The used baudrate for writing to the output device | ||||
| 	/// | ||||
|  | ||||
| 	LedDeviceSk6812SPI(const std::string& outputDevice, | ||||
| 					const unsigned baudrate); | ||||
|  | ||||
| 	/// | ||||
| 	/// Writes the led color values to the led-device | ||||
| 	/// | ||||
| 	/// @param ledValues The color-value per led | ||||
| 	/// @return Zero on succes else negative | ||||
| 	/// | ||||
| 	virtual int write(const std::vector<ColorRgb> &ledValues); | ||||
|  | ||||
| 	/// Switch the leds off | ||||
| 	virtual int switchOff(); | ||||
|  | ||||
| private: | ||||
|  | ||||
| 	/// the number of leds (needed when switching off) | ||||
| 	size_t mLedCount; | ||||
| 	std::vector<uint8_t> _spiBuffer; | ||||
|  | ||||
|         uint8_t bitpair_to_byte[4]; | ||||
| }; | ||||
| @@ -22,8 +22,6 @@ int update_number; | ||||
| int fragment_number; | ||||
|  | ||||
| LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate, const unsigned protocol, const unsigned maxPacket)  | ||||
| //LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate) : | ||||
| //	_ofs(output.empty()?"/home/pi/LedDevice.out":output.c_str()) | ||||
| { | ||||
| 	std::string hostname; | ||||
| 	std::string port; | ||||
| @@ -33,7 +31,6 @@ LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate, c | ||||
| 		leds_per_pkt = 200; | ||||
| 	} | ||||
|  | ||||
| //printf ("leds_per_pkt is %d\n", leds_per_pkt); | ||||
| 	int got_colon=0; | ||||
| 	for (unsigned int i=0; i<output.length(); i++) { | ||||
| 		if (output[i] == ':') { | ||||
| @@ -44,7 +41,6 @@ LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate, c | ||||
| 			port+=output[i]; | ||||
| 		} | ||||
| 	} | ||||
| 	//std::cout << "output " << output << " hostname " << hostname << " port " << port <<std::endl; | ||||
| 	assert(got_colon==1); | ||||
|  | ||||
| 	int rv; | ||||
| @@ -62,7 +58,8 @@ LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate, c | ||||
| 	for(p = servinfo; p != NULL; p = p->ai_next) { | ||||
| 		if ((sockfd = socket(p->ai_family, p->ai_socktype, | ||||
| 				p->ai_protocol)) == -1) { | ||||
| 			perror("talker: socket"); | ||||
| 			Error(_log,"talker: socket %s", strerror(errno)); | ||||
| //			perror("talker: socket"); | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| @@ -98,7 +95,6 @@ int LedDeviceUdp::write(const std::vector<ColorRgb> & ledValues) | ||||
| 				udpbuffer[i++] = color.green; | ||||
| 				udpbuffer[i++] = color.blue; | ||||
| 			} | ||||
| 			//printf ("c.red %d sz c.red %d\n", color.red, sizeof(color.red)); | ||||
| 		} | ||||
| 		sendto(sockfd, udpbuffer, i, 0, p->ai_addr, p->ai_addrlen); | ||||
| 	} | ||||
|   | ||||
| @@ -11,13 +11,6 @@ | ||||
| // hyperion local includes | ||||
| #include "LedDeviceUdpRaw.h" | ||||
|  | ||||
| LedDeviceUdpRaw::LedDeviceUdpRaw(const std::string& outputDevice, const unsigned baudrate) : | ||||
| 	LedUdpDevice(outputDevice, baudrate, 500000), | ||||
| 	mLedCount(0) | ||||
| { | ||||
| 	// empty | ||||
| } | ||||
|  | ||||
| LedDeviceUdpRaw::LedDeviceUdpRaw(const std::string& outputDevice, const unsigned baudrate, const unsigned latchTime) : | ||||
| 	LedUdpDevice(outputDevice, baudrate, latchTime), | ||||
| 	mLedCount(0) | ||||
|   | ||||
| @@ -18,8 +18,6 @@ public: | ||||
| 	/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0') | ||||
| 	/// @param baudrate The used baudrate for writing to the output device | ||||
| 	/// | ||||
| 	LedDeviceUdpRaw(const std::string& outputDevice, | ||||
| 					const unsigned baudrate); | ||||
|  | ||||
| 	LedDeviceUdpRaw(const std::string& outputDevice, | ||||
| 					const unsigned baudrate, | ||||
|   | ||||
| @@ -313,7 +313,6 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues) | ||||
| 	unsigned int wireBit = 1;			// Holds the current bit we will set in PWMWaveform, start with 1 and skip the other two for speed | ||||
|  | ||||
| 	// Copy PWM waveform to DMA's data buffer | ||||
| 	//printf("Copying %d words to DMA data buffer\n", NUM_DATA_WORDS); | ||||
| 	struct control_data_s *ctl = (struct control_data_s *)virtbase; | ||||
| 	dma_cb_t *cbp = ctl->cb; | ||||
|  | ||||
| @@ -335,10 +334,7 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues) | ||||
| 	for(size_t i=0; i<mLedCount; i++) | ||||
| 	{ | ||||
| 		// Create bits necessary to represent one color triplet (in GRB, not RGB, order) | ||||
| 		//printf("RGB: %d, %d, %d\n", ledValues[i].red, ledValues[i].green, ledValues[i].blue); | ||||
| 		colorBits = ((unsigned int)ledValues[i].red << 8) | ((unsigned int)ledValues[i].green << 16) | ledValues[i].blue; | ||||
| 		//printBinary(colorBits, 24); | ||||
| 		//printf(" (binary, GRB order)\n"); | ||||
|  | ||||
| 		// Iterate through color bits to get wire bits | ||||
| 		for(int j=23; j>=0; j--) { | ||||
| @@ -380,7 +376,6 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues) | ||||
| #ifdef WS2812_ASM_OPTI | ||||
| 	// calculate the bits manually since it is not needed with asm | ||||
| 	//wireBit += mLedCount * 24 *3; | ||||
| 	//printf(" %d\n", wireBit); | ||||
| #endif | ||||
| 	//remove one to undo optimization | ||||
| 	wireBit --; | ||||
| @@ -390,9 +385,6 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues) | ||||
| 	startbitPattern = (1 << (rest-1)); // set new bitpattern to start at the benigining of one bit (3 bit in wave form) | ||||
| 	rest += 32; // add one int extra for pwm | ||||
|  | ||||
| //	printBinary(startbitPattern, 32); | ||||
| //	printf(" startbit\n"); | ||||
|  | ||||
| 	unsigned int oldwireBitValue = wireBit; | ||||
| 	unsigned int oldbitPattern = startbitPattern; | ||||
|  | ||||
|   | ||||
| @@ -11,13 +11,6 @@ | ||||
| // hyperion local includes | ||||
| #include "LedDeviceWs2801.h" | ||||
|  | ||||
| LedDeviceWs2801::LedDeviceWs2801(const std::string& outputDevice, const unsigned baudrate) : | ||||
| 	LedSpiDevice(outputDevice, baudrate, 500000), | ||||
| 	mLedCount(0) | ||||
| { | ||||
| 	// empty | ||||
| } | ||||
|  | ||||
| LedDeviceWs2801::LedDeviceWs2801(const std::string& outputDevice, const unsigned baudrate, const unsigned latchTime) : | ||||
| 	LedSpiDevice(outputDevice, baudrate, latchTime), | ||||
| 	mLedCount(0) | ||||
|   | ||||
| @@ -18,8 +18,6 @@ public: | ||||
| 	/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0') | ||||
| 	/// @param baudrate The used baudrate for writing to the output device | ||||
| 	/// | ||||
| 	LedDeviceWs2801(const std::string& outputDevice, | ||||
| 					const unsigned baudrate); | ||||
|  | ||||
| 	LedDeviceWs2801(const std::string& outputDevice, | ||||
| 					const unsigned baudrate, | ||||
|   | ||||
| @@ -21,10 +21,6 @@ public: | ||||
| 	LedDeviceWs2812SPI(const std::string& outputDevice, | ||||
| 					const unsigned baudrate); | ||||
|  | ||||
| 	LedDeviceWs2812SPI(const std::string& outputDevice, | ||||
| 					const unsigned baudrate, | ||||
| 					const unsigned latchTime); | ||||
|  | ||||
| 	/// | ||||
| 	/// Writes the led color values to the led-device | ||||
| 	/// | ||||
|   | ||||
| @@ -36,8 +36,6 @@ add_library(hyperion-utils | ||||
| 	${CURRENT_SOURCE_DIR}/HslTransform.cpp | ||||
| 	${CURRENT_HEADER_DIR}/RgbChannelTransform.h | ||||
| 	${CURRENT_SOURCE_DIR}/RgbChannelTransform.cpp | ||||
| 	${CURRENT_HEADER_DIR}/RgbChannelCorrection.h | ||||
| 	${CURRENT_SOURCE_DIR}/RgbChannelCorrection.cpp | ||||
| 	${CURRENT_HEADER_DIR}/RgbChannelAdjustment.h | ||||
| 	${CURRENT_SOURCE_DIR}/RgbChannelAdjustment.cpp | ||||
|  | ||||
|   | ||||
							
								
								
									
										3
									
								
								libsrc/utils/ImageResampler.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										3
									
								
								libsrc/utils/ImageResampler.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -1,4 +1,5 @@ | ||||
| #include "utils/ImageResampler.h" | ||||
| #include <utils/Logger.h> | ||||
|  | ||||
| ImageResampler::ImageResampler() : | ||||
| 	_horizontalDecimation(1), | ||||
| @@ -124,7 +125,7 @@ void ImageResampler::processImage(const uint8_t * data, int width, int height, i | ||||
|                 } | ||||
|                 break; | ||||
|             case PIXELFORMAT_NO_CHANGE: | ||||
|                 std::cerr << "Invalid pixel format given" << std::endl; | ||||
| 				Error(Logger::getInstance("ImageResampler"), "Invalid pixel format given"); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -75,6 +75,16 @@ void Logger::setLogLevel(LogLevel level,std::string name) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| Logger::LogLevel Logger::getLogLevel(std::string name) | ||||
| { | ||||
| 	if ( name.empty() ) | ||||
| 	{ | ||||
| 		return GLOBAL_MIN_LOG_LEVEL; | ||||
| 	} | ||||
|  | ||||
| 	Logger* log = Logger::getInstance(name); | ||||
| 	return log->getMinLevel(); | ||||
| } | ||||
|  | ||||
| Logger::Logger ( std::string name, LogLevel minLevel ): | ||||
| 	_name(name), | ||||
|   | ||||
| @@ -1,107 +1,84 @@ | ||||
| // STL includes | ||||
| #include <cmath> | ||||
| #include <cstdint> | ||||
| #include <algorithm> | ||||
|  | ||||
| // Utils includes | ||||
| #include <utils/RgbChannelAdjustment.h> | ||||
|  | ||||
| RgbChannelAdjustment::RgbChannelAdjustment() : | ||||
| 	_adjustR(255), | ||||
| 	_adjustG(255), | ||||
| 	_adjustB(255) | ||||
| RgbChannelAdjustment::RgbChannelAdjustment() | ||||
| { | ||||
| 	initializeMapping(); | ||||
| 	setAdjustment(UINT8_MAX, UINT8_MAX, UINT8_MAX); | ||||
| } | ||||
|  | ||||
| RgbChannelAdjustment::RgbChannelAdjustment(int adjustR, int adjustG, int adjustB) : | ||||
| 	_adjustR(adjustR), | ||||
| 	_adjustG(adjustG), | ||||
| 	_adjustB(adjustB) | ||||
| RgbChannelAdjustment::RgbChannelAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB) | ||||
| { | ||||
| 	initializeMapping(); | ||||
| 	setAdjustment(adjustR, adjustG, adjustB); | ||||
| } | ||||
|  | ||||
| RgbChannelAdjustment::~RgbChannelAdjustment() | ||||
| { | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelAdjustment::getadjustmentR() const | ||||
| void RgbChannelAdjustment::setAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB) | ||||
| { | ||||
| 	return _adjustR; | ||||
| } | ||||
|  | ||||
| void RgbChannelAdjustment::setadjustmentR(uint8_t adjustR) | ||||
| { | ||||
| 	_adjustR = adjustR; | ||||
| 	_adjust[RED] = adjustR; | ||||
| 	_adjust[GREEN] = adjustG; | ||||
| 	_adjust[BLUE] = adjustB; | ||||
| 	initializeMapping(); | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelAdjustment::getadjustmentG() const | ||||
| uint8_t RgbChannelAdjustment::getAdjustmentR() const | ||||
| { | ||||
| 	return _adjustG; | ||||
| 	return _adjust[RED]; | ||||
| } | ||||
|  | ||||
| void RgbChannelAdjustment::setadjustmentG(uint8_t adjustG) | ||||
| void RgbChannelAdjustment::setAdjustmentR(uint8_t adjustR) | ||||
| { | ||||
| 	_adjustG = adjustG; | ||||
| 	initializeMapping(); | ||||
| 	setAdjustment(adjustR, _adjust[GREEN], _adjust[BLUE]); | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelAdjustment::getadjustmentB() const | ||||
| uint8_t RgbChannelAdjustment::getAdjustmentG() const | ||||
| { | ||||
| 	return _adjustB; | ||||
| 	return _adjust[GREEN]; | ||||
| } | ||||
|  | ||||
| void RgbChannelAdjustment::setadjustmentB(uint8_t adjustB) | ||||
| void RgbChannelAdjustment::setAdjustmentG(uint8_t adjustG) | ||||
| { | ||||
| 	_adjustB = adjustB; | ||||
| 	initializeMapping(); | ||||
| 	setAdjustment(_adjust[RED], adjustG, _adjust[BLUE]); | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelAdjustment::getAdjustmentB() const | ||||
| { | ||||
| 	return _adjust[BLUE]; | ||||
| } | ||||
|  | ||||
| void RgbChannelAdjustment::setAdjustmentB(uint8_t adjustB) | ||||
| { | ||||
| 	setAdjustment(_adjust[RED], _adjust[GREEN], adjustB); | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelAdjustment::adjustmentR(uint8_t inputR) const | ||||
| { | ||||
| 	return _mappingR[inputR]; | ||||
| 	return _mapping[RED][inputR]; | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelAdjustment::adjustmentG(uint8_t inputG) const | ||||
| { | ||||
| 	return _mappingG[inputG]; | ||||
| 	return _mapping[GREEN][inputG]; | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelAdjustment::adjustmentB(uint8_t inputB) const | ||||
| { | ||||
| 	return _mappingB[inputB]; | ||||
| 	return _mapping[BLUE][inputB]; | ||||
| } | ||||
|  | ||||
| void RgbChannelAdjustment::initializeMapping() | ||||
| { | ||||
| 	// initialize the mapping | ||||
| 	for (int i = 0; i < 256; ++i) | ||||
| 	{ | ||||
| 		int outputR = (i * _adjustR) / 255; | ||||
|     		if (outputR > 255) | ||||
| 	// initialize linear mapping | ||||
| 	for (unsigned channel=0; channel<3; channel++) | ||||
| 		for (unsigned idx=0; idx<=UINT8_MAX; idx++) | ||||
| 		{ | ||||
| 			outputR = 255; | ||||
| 			_mapping[channel][idx] = std::min( ((idx * _adjust[channel]) / UINT8_MAX), (unsigned)UINT8_MAX); | ||||
| 		} | ||||
| 		_mappingR[i] = outputR; | ||||
| 	} | ||||
| 	for (int i = 0; i < 256; ++i) | ||||
| 	{ | ||||
| 		int outputG = (i * _adjustG) / 255; | ||||
| 		if (outputG > 255) | ||||
| 		{ | ||||
| 			outputG = 255; | ||||
| 		} | ||||
| 		_mappingG[i] = outputG; | ||||
| 	} | ||||
| 	for (int i = 0; i < 256; ++i) | ||||
| 	{ | ||||
| 		int outputB = (i * _adjustB) / 255; | ||||
| 		if (outputB > 255) | ||||
| 		{ | ||||
| 			outputB = 255; | ||||
| 		} | ||||
| 		_mappingB[i] = outputB; | ||||
| 	} | ||||
| 		 | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,120 +0,0 @@ | ||||
| // STL includes | ||||
| #include <cmath> | ||||
|  | ||||
| // Utils includes | ||||
| #include <utils/RgbChannelCorrection.h> | ||||
|  | ||||
| RgbChannelCorrection::RgbChannelCorrection() : | ||||
| 	_correctionR(255), | ||||
| 	_correctionG(255), | ||||
| 	_correctionB(255) | ||||
| { | ||||
| 	initializeMapping(); | ||||
| } | ||||
|  | ||||
| RgbChannelCorrection::RgbChannelCorrection(int correctionR, int correctionG, int correctionB) : | ||||
| 	_correctionR(correctionR), | ||||
| 	_correctionG(correctionG), | ||||
| 	_correctionB(correctionB) | ||||
| { | ||||
| 	initializeMapping(); | ||||
| } | ||||
|  | ||||
| RgbChannelCorrection::~RgbChannelCorrection() | ||||
| { | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelCorrection::getcorrectionR() const | ||||
| { | ||||
| 	return _correctionR; | ||||
| } | ||||
|  | ||||
| void RgbChannelCorrection::setcorrectionR(uint8_t correctionR) | ||||
| { | ||||
| 	_correctionR = correctionR; | ||||
| 	initializeMapping(); | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelCorrection::getcorrectionG() const | ||||
| { | ||||
| 	return _correctionG; | ||||
| } | ||||
|  | ||||
| void RgbChannelCorrection::setcorrectionG(uint8_t correctionG) | ||||
| { | ||||
| 	_correctionG = correctionG; | ||||
| 	initializeMapping(); | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelCorrection::getcorrectionB() const | ||||
| { | ||||
| 	return _correctionB; | ||||
| } | ||||
|  | ||||
| void RgbChannelCorrection::setcorrectionB(uint8_t correctionB) | ||||
| { | ||||
| 	_correctionB = correctionB; | ||||
| 	initializeMapping(); | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelCorrection::correctionR(uint8_t inputR) const | ||||
| { | ||||
| 	return _mappingR[inputR]; | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelCorrection::correctionG(uint8_t inputG) const | ||||
| { | ||||
| 	return _mappingG[inputG]; | ||||
| } | ||||
|  | ||||
| uint8_t RgbChannelCorrection::correctionB(uint8_t inputB) const | ||||
| { | ||||
| 	return _mappingB[inputB]; | ||||
| } | ||||
|  | ||||
| void RgbChannelCorrection::initializeMapping() | ||||
| { | ||||
| 	// initialize the mapping | ||||
| 	for (int i = 0; i < 256; ++i) | ||||
| 	{ | ||||
| 		int outputR = (i * _correctionR) / 255; | ||||
| 		if (outputR < -255) | ||||
| 			{ | ||||
| 				outputR = -255; | ||||
| 			} | ||||
| 		else if (outputR > 255) | ||||
| 			{ | ||||
| 				outputR = 255; | ||||
| 			} | ||||
| 		_mappingR[i] = outputR; | ||||
| 	} | ||||
| 	for (int i = 0; i < 256; ++i) | ||||
| 	{ | ||||
| 		int outputG = (i * _correctionG) / 255; | ||||
| 		if (outputG < -255) | ||||
| 			{ | ||||
| 				outputG = -255; | ||||
| 			} | ||||
| 		else if (outputG > 255) | ||||
| 			{ | ||||
| 				outputG = 255; | ||||
| 			} | ||||
| 		_mappingG[i] = outputG; | ||||
| 	} | ||||
| 	for (int i = 0; i < 256; ++i) | ||||
| 	{ | ||||
| 		int outputB = (i * _correctionB) / 255; | ||||
| 		if (outputB < -255) | ||||
| 			{ | ||||
| 				outputB = -255; | ||||
| 			} | ||||
| 		else if (outputB > 255) | ||||
| 			{ | ||||
| 				outputB = 255; | ||||
| 			} | ||||
| 		_mappingB[i] = outputB; | ||||
| 	} | ||||
| 		 | ||||
|  | ||||
| } | ||||
|  | ||||
| @@ -4,28 +4,29 @@ | ||||
| // Utils includes | ||||
| #include <utils/RgbChannelTransform.h> | ||||
|  | ||||
| RgbChannelTransform::RgbChannelTransform() : | ||||
| 	_threshold(0), | ||||
| 	_gamma(1.0), | ||||
| 	_blacklevel(0.0), | ||||
| 	_whitelevel(1.0) | ||||
| RgbChannelTransform::RgbChannelTransform() | ||||
| { | ||||
| 	initializeMapping(); | ||||
| 	setTransform(0.0, 1.0, 0.0, 1.0); | ||||
| } | ||||
|  | ||||
| RgbChannelTransform::RgbChannelTransform(double threshold, double gamma, double blacklevel, double whitelevel) : | ||||
| 	_threshold(threshold), | ||||
| 	_gamma(gamma), | ||||
| 	_blacklevel(blacklevel), | ||||
| 	_whitelevel(whitelevel) | ||||
| RgbChannelTransform::RgbChannelTransform(double threshold, double gamma, double blacklevel, double whitelevel) | ||||
| { | ||||
| 	initializeMapping(); | ||||
| 	setTransform(threshold, gamma, blacklevel, whitelevel); | ||||
| } | ||||
|  | ||||
| RgbChannelTransform::~RgbChannelTransform() | ||||
| { | ||||
| } | ||||
|  | ||||
| void RgbChannelTransform::setTransform(double threshold, double gamma, double blacklevel, double whitelevel) | ||||
| { | ||||
| 	_threshold  = threshold; | ||||
| 	_gamma      = gamma; | ||||
| 	_blacklevel = blacklevel; | ||||
| 	_whitelevel = whitelevel; | ||||
| 	initializeMapping(); | ||||
| } | ||||
|  | ||||
| double RgbChannelTransform::getThreshold() const | ||||
| { | ||||
| 	return _threshold; | ||||
| @@ -33,8 +34,7 @@ double RgbChannelTransform::getThreshold() const | ||||
|  | ||||
| void RgbChannelTransform::setThreshold(double threshold) | ||||
| { | ||||
| 	_threshold = threshold; | ||||
| 	initializeMapping(); | ||||
| 	setTransform(threshold, _gamma, _blacklevel, _whitelevel); | ||||
| } | ||||
|  | ||||
| double RgbChannelTransform::getGamma() const | ||||
| @@ -44,8 +44,7 @@ double RgbChannelTransform::getGamma() const | ||||
|  | ||||
| void RgbChannelTransform::setGamma(double gamma) | ||||
| { | ||||
| 	_gamma = gamma; | ||||
| 	initializeMapping(); | ||||
| 	setTransform(_threshold, gamma, _blacklevel, _whitelevel); | ||||
| } | ||||
|  | ||||
| double RgbChannelTransform::getBlacklevel() const | ||||
| @@ -55,8 +54,7 @@ double RgbChannelTransform::getBlacklevel() const | ||||
|  | ||||
| void RgbChannelTransform::setBlacklevel(double blacklevel) | ||||
| { | ||||
| 	_blacklevel = blacklevel; | ||||
| 	initializeMapping(); | ||||
| 	setTransform(_threshold, _gamma, blacklevel, _whitelevel); | ||||
| } | ||||
|  | ||||
| double RgbChannelTransform::getWhitelevel() const | ||||
| @@ -66,8 +64,7 @@ double RgbChannelTransform::getWhitelevel() const | ||||
|  | ||||
| void RgbChannelTransform::setWhitelevel(double whitelevel) | ||||
| { | ||||
| 	_whitelevel = whitelevel; | ||||
| 	initializeMapping(); | ||||
| 	setTransform(_threshold, _gamma, _blacklevel, whitelevel); | ||||
| } | ||||
|  | ||||
| void RgbChannelTransform::initializeMapping() | ||||
|   | ||||
							
								
								
									
										3
									
								
								libsrc/utils/RgbToRgbw.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										3
									
								
								libsrc/utils/RgbToRgbw.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -1,5 +1,6 @@ | ||||
| #include <utils/ColorRgb.h> | ||||
| #include <utils/ColorRgbw.h> | ||||
| #include <utils/Logger.h> | ||||
|  | ||||
| void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, std::string _whiteAlgorithm) { | ||||
| 	if (_whiteAlgorithm == "subtract_minimum") { | ||||
| @@ -18,7 +19,7 @@ void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, std::string _whiteAlgorithm | ||||
| 		output->white = 0; | ||||
| 	} | ||||
| 	else { | ||||
| 		std::cout << "ERROR: unknown whiteAlgorithm " << _whiteAlgorithm << std::endl; | ||||
| 		Error(Logger::getInstance("RGBtoRGBW"), "unknown whiteAlgorithm %s", _whiteAlgorithm.c_str()); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -175,7 +175,7 @@ int main(int argc, char * argv[]) | ||||
| 				if (argIdC.isSet())	corrId    = argIdC.getValue(); | ||||
| 				if (argCorrection.isSet())  correction = argCorrection.getValue(); | ||||
|  | ||||
| 				connection.setCorrection( | ||||
| 				connection.setTemperature( | ||||
| 						argIdC.isSet()		? &corrId : nullptr, | ||||
| 						argCorrection.isSet()   ? &correction  : nullptr); | ||||
| 			} | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| #include <unistd.h> | ||||
| #include <cassert> | ||||
|  | ||||
| #include <QCoreApplication> | ||||
| #include <QResource> | ||||
| @@ -42,6 +43,26 @@ HyperionDaemon::HyperionDaemon(std::string configFile, QObject *parent) | ||||
| { | ||||
| 	loadConfig(configFile); | ||||
| 	_hyperion = Hyperion::initInstance(_config, configFile); | ||||
| 	 | ||||
| 	if (Logger::getLogLevel() == Logger::WARNING) | ||||
| 	{ | ||||
| 		if (_config.isMember("logger")) | ||||
| 		{ | ||||
| 			const Json::Value & logConfig = _config["logger"]; | ||||
| 			std::string level = logConfig.get("level", "warn").asString(); // silent warn verbose debug | ||||
| 			if (level == "silent") Logger::setLogLevel(Logger::OFF); | ||||
| 			else if (level == "warn")    Logger::setLogLevel(Logger::WARNING); | ||||
| 			else if (level == "verbose") Logger::setLogLevel(Logger::INFO); | ||||
| 			else if (level == "debug")   Logger::setLogLevel(Logger::DEBUG); | ||||
| 			else Error(Logger::getInstance("LOGGER"), "log level '%s' used in config is unknown. valid: silent warn verbose debug", level.c_str()); | ||||
| 			 | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		WarningIf(_config.isMember("logger"), Logger::getInstance("LOGGER"), "Logger settings overriden by command line argument"); | ||||
| 	} | ||||
| 	 | ||||
| 	Info(_log, "Hyperion started and initialised"); | ||||
| } | ||||
|  | ||||
| @@ -231,13 +252,15 @@ void HyperionDaemon::startNetworkServices() | ||||
| 	if (_config.isMember("boblightServer")) | ||||
| 	{ | ||||
| 		const Json::Value & boblightServerConfig = _config["boblightServer"]; | ||||
| 		_boblightServer = new BoblightServer( | ||||
| 			boblightServerConfig.get("priority",900).asInt(), | ||||
| 			boblightServerConfig["port"].asUInt() | ||||
| 		); | ||||
| 		Debug(_log, "Boblight server created"); | ||||
|  | ||||
| 		if ( boblightServerConfig.get("enable", true).asBool() ) | ||||
| 		{ | ||||
| 			_boblightServer = new BoblightServer( | ||||
| 						boblightServerConfig.get("priority",900).asInt(), | ||||
| 						boblightServerConfig["port"].asUInt() | ||||
| 						); | ||||
| 			Info(_log, "Boblight server created and started on port %d", _boblightServer->getPort()); | ||||
| 			_boblightServer->start(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -252,11 +275,10 @@ void HyperionDaemon::startNetworkServices() | ||||
| 					udpListenerConfig.get("port", 2801).asUInt(), | ||||
| 					udpListenerConfig.get("shared", false).asBool() | ||||
| 				); | ||||
| 		Info(_log, "UDP listener created on port %d", _udpListener->getPort()); | ||||
| 		Debug(_log, "UDP listener created"); | ||||
|  | ||||
| 		if ( udpListenerConfig.get("enable", true).asBool() ) | ||||
| 		{ | ||||
| 			Info(_log, "UDP listener started" ); | ||||
| 			_udpListener->start(); | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -75,5 +75,5 @@ private: | ||||
| 	FramebufferWrapper* _fbGrabber;  | ||||
| 	OsxWrapper*         _osxGrabber; | ||||
| 	WebConfig*          _webConfig; | ||||
|         Hyperion*           _hyperion; | ||||
| 	Hyperion*           _hyperion; | ||||
| }; | ||||
|   | ||||
| @@ -54,7 +54,7 @@ void setColor(char* colorStr) | ||||
| 	unsigned ledCnt = 50; | ||||
| 	std::vector<ColorRgb> buff(ledCnt, color); | ||||
|  | ||||
| 	LedDeviceWs2801 ledDevice("/dev/spidev0.0", 40000); | ||||
| 	LedDeviceWs2801 ledDevice("/dev/spidev0.0", 40000, 500000); | ||||
| 	ledDevice.open(); | ||||
| 	ledDevice.write(buff); | ||||
| } | ||||
| @@ -68,7 +68,7 @@ void doCircle() | ||||
| 	unsigned ledCnt = 50; | ||||
| 	std::vector<ColorRgb> data(ledCnt, ColorRgb::BLACK); | ||||
|  | ||||
| 	LedDeviceWs2801 ledDevice("/dev/spidev0.0", 40000); | ||||
| 	LedDeviceWs2801 ledDevice("/dev/spidev0.0", 40000, 500000); | ||||
| 	ledDevice.open(); | ||||
|  | ||||
| 	timespec loopTime; | ||||
|   | ||||
| @@ -5,7 +5,7 @@ include_directories(${BCM_INCLUDE_DIRS}) | ||||
|  | ||||
| # Configure the use of QT4 | ||||
| #find_package(Qt4 COMPONENTS QtTest REQUIRED QUIET) | ||||
| include(${QT_USE_FILE}) | ||||
| #include(${QT_USE_FILE}) | ||||
| add_definitions(${QT_DEFINITIONS}) | ||||
| link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf) | ||||
|  | ||||
| @@ -16,4 +16,5 @@ add_executable(dispmanx2png | ||||
| target_link_libraries(dispmanx2png | ||||
| 		dispmanx-grabber | ||||
| 		getoptPlusPlus | ||||
| 		Qt5Gui | ||||
| 		${QT_LIBRARIES}) | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| #include <iomanip> | ||||
|  | ||||
| // QT includes | ||||
| #include <QImage> | ||||
| #include <QtGui/QImage> | ||||
|  | ||||
| // getoptPlusPLus includes | ||||
| #include <getoptPlusPlus/getoptpp.h> | ||||
| @@ -35,7 +35,7 @@ int main(int argc, char** argv) | ||||
| 		ParameterSet & parameters = optionParser.getParameters(); | ||||
|  | ||||
| 		QString flagDescr = QString("Set the grab flags of the dispmanx frame grabber [default: 0x%1]").arg(grabFlags, 8, 16, QChar('0')); | ||||
| 		StringParameter   & argFlags = parameters.add<StringParameter>   ('f', "flags", flagDescr.toAscii().constData()); | ||||
| 		StringParameter   & argFlags = parameters.add<StringParameter>   ('f', "flags", flagDescr.toLatin1().constData()); | ||||
| 		IntParameter      & argCount = parameters.add<IntParameter>      ('n', "count", "Number of images to capture (default infinite)"); | ||||
| 		argCount.setDefault(grabCount); | ||||
| 		SwitchParameter<> & argList  = parameters.add<SwitchParameter<> >('l', "list",  "List the possible flags"); | ||||
|   | ||||
| @@ -143,7 +143,7 @@ void setup_io() | ||||
|    ); | ||||
|  | ||||
|    if ((long)gpio_map < 0) { | ||||
|       printf("mmap error %d\n", (int)gpio_map); | ||||
|       printf("mmap error %d\n", (long)gpio_map); | ||||
|       exit (-1); | ||||
|    } | ||||
|    gpio = (volatile unsigned *)gpio_map; | ||||
| @@ -169,7 +169,7 @@ void setup_io() | ||||
|    printf("SPI mapped from 0x%p to 0x%p\n",SPI0_BASE,spi0_map); | ||||
|  | ||||
|    if ((long)spi0_map < 0) { | ||||
|       printf("mmap error %d\n", (int)spi0_map); | ||||
|       printf("mmap error %d\n", (long)spi0_map); | ||||
|       exit (-1); | ||||
|    } | ||||
|    spi0 = (volatile unsigned *)spi0_map; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user