diff --git a/CMakeLists.txt b/CMakeLists.txt index 12f6bccb..02296780 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,23 +139,23 @@ SET( JSON_FILES config/hyperion.config.json.default ${HYPERION_SCHEMAS} ) -#EXECUTE_PROCESS ( -# COMMAND python test/jsonchecks/checkjson.py ${JSON_FILES} -# WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} -# RESULT_VARIABLE CHECK_JSON_FAILED -#) -#IF ( ${CHECK_JSON_FAILED} ) -# MESSAGE (FATAL_ERROR "check of json files failed" ) -#ENDIF () +EXECUTE_PROCESS ( + COMMAND python test/jsonchecks/checkjson.py ${JSON_FILES} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE CHECK_JSON_FAILED +) +IF ( ${CHECK_JSON_FAILED} ) + MESSAGE (FATAL_ERROR "check of json files failed" ) +ENDIF () -#EXECUTE_PROCESS ( -# COMMAND python test/jsonchecks/checkeffects.py effects effects/schema -# WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} -# RESULT_VARIABLE CHECK_EFFECTS_FAILED -#) -#IF ( ${CHECK_EFFECTS_FAILED} ) -# MESSAGE (FATAL_ERROR "check of json effect files failed" ) -#ENDIF () +EXECUTE_PROCESS ( + COMMAND python test/jsonchecks/checkeffects.py effects effects/schema + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + RESULT_VARIABLE CHECK_EFFECTS_FAILED +) +IF ( ${CHECK_EFFECTS_FAILED} ) + MESSAGE (FATAL_ERROR "check of json effect files failed" ) +ENDIF () EXECUTE_PROCESS ( COMMAND python test/jsonchecks/checkschema.py config/hyperion.config.json.default libsrc/hyperion/hyperion.schema.json diff --git a/assets/webconfig/i18n/de.json b/assets/webconfig/i18n/de.json index a03d0d90..7cd154f5 100644 --- a/assets/webconfig/i18n/de.json +++ b/assets/webconfig/i18n/de.json @@ -603,8 +603,15 @@ "edt_conf_log_heading_title" : "Protokoll", "edt_conf_log_level_title" : "Protokollstufe", "edt_conf_log_level_expl" : "Abhängig der Stufe sind weniger oder mehr Meldungen sichtbar.", + "edt_eff_smooth_custom_title" : "Aktivere Glättung", + "edt_eff_smooth_time_ms_title" : "Glättung: Zeit", + "edt_eff_smooth_updateFrequency_title" : "Glättung: Aktualisierungsfrequenz", + "edt_eff_smooth_updateDelay_title" : "Glättung: Aktualisierungsverzögerung", + "edt_eff_smooth_pause_title" : "Glättung pausieren", "edt_eff_candle_header" : "Kerze", + "edt_eff_candle_header_desc" : "Flackerndes Kerzenlicht", "edt_eff_police_header" : "Polizei", + "edt_eff_police_header_desc" : "Lights like a police car in action", "edt_eff_fade_header" : "Farbübergang", "edt_eff_rainbowmood_header" : "Regenbogen", "edt_eff_rainbowmood_header_desc" : "Alle LEDs Regenbogen Farbübergang", diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json index 998f9c2d..319352d7 100644 --- a/assets/webconfig/i18n/en.json +++ b/assets/webconfig/i18n/en.json @@ -604,9 +604,17 @@ "edt_conf_log_heading_title" : "Logging", "edt_conf_log_level_title" : "Log-Level", "edt_conf_log_level_expl" : "Depending on loglevel you see less or more messages in your log.", + "edt_eff_smooth_custom_title" : "Enable smoothing", + "edt_eff_smooth_time_ms_title" : "Smoothing time", + "edt_eff_smooth_updateFrequency_title" : "Smoothing update frequency", + "edt_eff_smooth_updateDelay_title" : "Smoothing update delay", + "edt_eff_smooth_pause_title" : "Pause smoothing", "edt_eff_candle_header" : "Candle", + "edt_eff_candle_header_desc" : "Shimmering candles", "edt_eff_police_header" : "Police", + "edt_eff_police_header_desc" : "Lights like a police car in action", "edt_eff_fade_header" : "Fade", + "edt_eff_fade_header_desc" : "Fades between colors", "edt_eff_rainbowmood_header" : "Rainbow Mood", "edt_eff_rainbowmood_header_desc" : "All leds rainbow mood", "edt_eff_knightrider_header" : "Knight Rider", diff --git a/effects/candle.json b/effects/candle.json index 6dc6938a..73253371 100644 --- a/effects/candle.json +++ b/effects/candle.json @@ -6,6 +6,11 @@ "sleepTime" : 0.20, "brightness" : 100, "color" : [ 255, 138, 0 ], - "candles" : "all" + "candles" : "all", + "smoothing-custom-settings" : true, + "smoothing-time_ms" : 500, + "smoothing-updateDelay" : 0, + "smoothing-updateFrequency" : 20.0, + "smoothing-pause" : false } } diff --git a/effects/fade.py b/effects/fade.py index 1a02f152..20dd7591 100644 --- a/effects/fade.py +++ b/effects/fade.py @@ -13,12 +13,17 @@ minStepTime = float(hyperion.latchTime)/1000.0 currentR = currentG = currentB = 0 # create color table for fading from start to end color -steps = float(abs(max((colorEnd[0] - colorStart[0]),max((colorEnd[1] - colorStart[1]),(colorEnd[2] - colorStart[2]))))) -color_step = ( - (colorEnd[0] - colorStart[0]) / steps, - (colorEnd[1] - colorStart[1]) / steps, - (colorEnd[2] - colorStart[2]) / steps -) +steps = float(max(abs(colorEnd[0] - colorStart[0]),max(abs(colorEnd[1] - colorStart[1]),abs(colorEnd[2] - colorStart[2])))) +color_step = (0,0,0) + +if steps == 0: + steps = 1 +else: + color_step = ( + (colorEnd[0] - colorStart[0]) / steps, + (colorEnd[1] - colorStart[1]) / steps, + (colorEnd[2] - colorStart[2]) / steps + ) calcChannel = lambda i: min(max(int(round(colorStart[i] + color_step[i]*step)),0), colorEnd[i] if colorStart[i] < colorEnd[i] else colorStart[i]) colors = [] diff --git a/effects/random.json b/effects/random.json index 1c33f980..3b75c3b2 100644 --- a/effects/random.json +++ b/effects/random.json @@ -4,6 +4,11 @@ "args" : { "speed" : 750, - "saturation" : 1.0 + "saturation" : 1.0, + "smoothing-custom-settings" : true, + "smoothing-time_ms" : 200, + "smoothing-updateDelay" : 0, + "smoothing-updateFrequency" : 20.0, + "smoothing-pause" : false } } diff --git a/effects/schema/candle.schema.json b/effects/schema/candle.schema.json index b3ac0764..16436c66 100644 --- a/effects/schema/candle.schema.json +++ b/effects/schema/candle.schema.json @@ -67,6 +67,70 @@ "step": 0.01, "append" : "edt_append_s", "propertyOrder" : 6 + }, + "smoothing-custom-settings" : + { + "type" : "boolean", + "title" : "edt_eff_smooth_custom_title", + "default" : false, + "propertyOrder" : 7 + }, + "smoothing-time_ms" : + { + "type" : "integer", + "title" : "edt_eff_smooth_time_ms_title", + "minimum" : 25, + "maximum": 600, + "default" : 200, + "append" : "edt_append_ms", + "options": { + "dependencies": { + "smoothing-custom-settings": true + } + }, + "propertyOrder" : 8 + }, + "smoothing-updateFrequency" : + { + "type" : "number", + "title" : "edt_eff_smooth_updateFrequency_title", + "minimum" : 1.0, + "maximum" : 100.0, + "default" : 25.0, + "append" : "edt_append_hz", + "options": { + "dependencies": { + "smoothing-custom-settings": true + } + }, + "propertyOrder" : 9 + }, + "smoothing-updateDelay" : + { + "type" : "integer", + "title" : "edt_eff_smooth_updateDelay_title", + "minimum" : 0, + "maximum": 2048, + "default" : 0, + "append" : "edt_append_ms", + "options": { + "dependencies": { + "smoothing-custom-settings": true + } + }, + "propertyOrder" : 10 + }, + "smoothing-pause" : + { + "type" : "boolean", + "title" : "edt_eff_smooth_pause_title", + "default" : false, + "options": { + "dependencies": { + "smoothing-custom-settings": true + } + }, + "propertyOrder" : 12 } }, "additionalProperties": false diff --git a/effects/schema/knight-rider.schema.json b/effects/schema/knight-rider.schema.json index 5b2c2e5d..7a874f5e 100644 --- a/effects/schema/knight-rider.schema.json +++ b/effects/schema/knight-rider.schema.json @@ -1,40 +1,40 @@ -{ - "type":"object", - "script" : "knight-rider.py", - "title":"edt_eff_knightrider_header", - "required":true, - "properties":{ - "color": { - "type": "array", - "title":"edt_eff_color", - "format":"colorpicker", - "default": [255,0,0], - "items" : { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "minItems": 3, - "maxItems": 3, - "propertyOrder" : 1 - }, - "speed": { - "type": "number", - "title":"edt_eff_speed", - "default": 1.0, - "minimum": 0.1, - "step" : 0.1, - "propertyOrder" : 2 - }, - "fadeFactor": { - "type": "number", - "title":"edt_eff_fadefactor", - "default": 0.7, - "minimum" : 0.0, - "maximum" : 0.9, - "step" : 0.1, - "propertyOrder" : 3 - } - }, - "additionalProperties": false -} +{ + "type":"object", + "script" : "knight-rider.py", + "title":"edt_eff_knightrider_header", + "required":true, + "properties":{ + "color": { + "type": "array", + "title":"edt_eff_color", + "format":"colorpicker", + "default": [255,0,0], + "items" : { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "minItems": 3, + "maxItems": 3, + "propertyOrder" : 1 + }, + "speed": { + "type": "number", + "title":"edt_eff_speed", + "default": 1.0, + "minimum": 0.1, + "step" : 0.1, + "propertyOrder" : 2 + }, + "fadeFactor": { + "type": "number", + "title":"edt_eff_fadefactor", + "default": 0.7, + "minimum" : 0.0, + "maximum" : 0.9, + "step" : 0.1, + "propertyOrder" : 3 + } + }, + "additionalProperties": false +} diff --git a/effects/schema/light-clock.schema.json b/effects/schema/light-clock.schema.json index b2171f69..32cf8f09 100644 --- a/effects/schema/light-clock.schema.json +++ b/effects/schema/light-clock.schema.json @@ -76,7 +76,7 @@ "type": "integer", "title": "edt_eff_markerDepth", "default": 5, - "minimum" : 1, + "minimum" : 0, "maximum" : 50, "append" : "edt_append_percent", "options": { diff --git a/effects/schema/mood-blobs.schema.json b/effects/schema/mood-blobs.schema.json index 3112d64d..cf05cd1b 100644 --- a/effects/schema/mood-blobs.schema.json +++ b/effects/schema/mood-blobs.schema.json @@ -1,104 +1,104 @@ -{ - "type":"object", - "script" : "mood-blobs.py", - "title":"edt_eff_moodblobs_header", - "required":true, - "properties":{ - "color": { - "type": "array", - "title":"edt_eff_color", - "format":"colorpicker", - "default": [255,0,0], - "items" : { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "minItems": 3, - "maxItems": 3, - "propertyOrder" : 1 - }, - "blobs": { - "type": "integer", - "title":"edt_eff_blobcount", - "default": 5, - "minimum" : 1, - "propertyOrder" : 2 - }, - "rotationTime": { - "type": "number", - "title":"edt_eff_rotationtime", - "default": 20.0, - "minimum" : 1.0, - "append" : "edt_append_s", - "propertyOrder" : 3 - }, - "hueChange": { - "type": "number", - "title":"edt_eff_huechange", - "default": 60.0, - "minimum" : 1.0, - "propertyOrder" : 4 - }, - "reverse": { - "type": "boolean", - "title":"edt_eff_reversedirection", - "default": false, - "propertyOrder" : 5 - }, - "colorRandom": { - "type": "boolean", - "title":"edt_eff_colorrandom", - "default": false, - "propertyOrder" : 6 - }, - "baseChange": { - "type": "boolean", - "title":"edt_eff_basecolorchange", - "default": false, - "propertyOrder" : 7 - }, - "baseColorRangeLeft": { - "type": "number", - "title":"edt_eff_basecolorrangeleft", - "default": 0.0, - "minimum" : 0.0, - "maximum" : 360.0, - "append" : "edt_append_degree", - "options": { - "dependencies": { - "baseChange": true - } - }, - "propertyOrder" : 9 - }, - "baseColorRangeRight": { - "type": "number", - "title":"edt_eff_basecolorrangeright", - "default": 360.0, - "minimum" : 0.0, - "maximum" : 360.0, - "append" : "edt_append_degree", - "options": { - "dependencies": { - "baseChange": true - } - }, - "propertyOrder" : 10 - }, - "baseColorChangeRate": { - "type": "number", - "title":"edt_eff_basecolorchangerate", - "default": 2.0, - "minimum" : 0.0, - "append" : "edt_append_sdegree", - "options": { - "dependencies": { - "baseChange": true - } - }, - "propertyOrder" : 8 - } - }, - "additionalProperties": false -} +{ + "type":"object", + "script" : "mood-blobs.py", + "title":"edt_eff_moodblobs_header", + "required":true, + "properties":{ + "color": { + "type": "array", + "title":"edt_eff_color", + "format":"colorpicker", + "default": [255,0,0], + "items" : { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "minItems": 3, + "maxItems": 3, + "propertyOrder" : 1 + }, + "blobs": { + "type": "integer", + "title":"edt_eff_blobcount", + "default": 5, + "minimum" : 1, + "propertyOrder" : 2 + }, + "rotationTime": { + "type": "number", + "title":"edt_eff_rotationtime", + "default": 20.0, + "minimum" : 1.0, + "append" : "edt_append_s", + "propertyOrder" : 3 + }, + "hueChange": { + "type": "number", + "title":"edt_eff_huechange", + "default": 60.0, + "minimum" : 1.0, + "propertyOrder" : 4 + }, + "reverse": { + "type": "boolean", + "title":"edt_eff_reversedirection", + "default": false, + "propertyOrder" : 5 + }, + "colorRandom": { + "type": "boolean", + "title":"edt_eff_colorrandom", + "default": false, + "propertyOrder" : 6 + }, + "baseChange": { + "type": "boolean", + "title":"edt_eff_basecolorchange", + "default": false, + "propertyOrder" : 7 + }, + "baseColorRangeLeft": { + "type": "number", + "title":"edt_eff_basecolorrangeleft", + "default": 0.0, + "minimum" : 0.0, + "maximum" : 360.0, + "append" : "edt_append_degree", + "options": { + "dependencies": { + "baseChange": true + } + }, + "propertyOrder" : 9 + }, + "baseColorRangeRight": { + "type": "number", + "title":"edt_eff_basecolorrangeright", + "default": 360.0, + "minimum" : 0.0, + "maximum" : 360.0, + "append" : "edt_append_degree", + "options": { + "dependencies": { + "baseChange": true + } + }, + "propertyOrder" : 10 + }, + "baseColorChangeRate": { + "type": "number", + "title":"edt_eff_basecolorchangerate", + "default": 2.0, + "minimum" : 0.0, + "append" : "edt_append_sdegree", + "options": { + "dependencies": { + "baseChange": true + } + }, + "propertyOrder" : 8 + } + }, + "additionalProperties": false +} diff --git a/effects/schema/police.schema.json b/effects/schema/police.schema.json index 2896062e..3ef200de 100644 --- a/effects/schema/police.schema.json +++ b/effects/schema/police.schema.json @@ -1,58 +1,58 @@ -{ - "type":"object", - "script" : "police.py", - "title":"edt_eff_police_header", - "required":true, - "properties":{ - "color_one": { - "type": "array", - "title":"edt_eff_colorone", - "format":"colorpicker", - "default": [255,0,0], - "items" : { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "minItems": 3, - "maxItems": 3, - "propertyOrder" : 1 - }, - "color_two": { - "type": "array", - "title":"edt_eff_colortwo", - "format":"colorpicker", - "default": [0,0,255], - "items" : { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "minItems": 3, - "maxItems": 3, - "propertyOrder" : 2 - }, - "colors_count": { - "type": "integer", - "title":"edt_eff_colorcount", - "default": 10, - "minimum" : 0, - "propertyOrder" : 3 - }, - "rotation-time": { - "type": "number", - "title":"edt_eff_rotationtime", - "default": 2.0, - "minimum" : 0.1, - "append" : "edt_append_s", - "propertyOrder" : 4 - }, - "reverse": { - "type": "boolean", - "title":"edt_eff_reversedirection", - "default": false, - "propertyOrder" : 5 - } - }, - "additionalProperties": false -} +{ + "type":"object", + "script" : "police.py", + "title":"edt_eff_police_header", + "required":true, + "properties":{ + "color_one": { + "type": "array", + "title":"edt_eff_colorone", + "format":"colorpicker", + "default": [255,0,0], + "items" : { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "minItems": 3, + "maxItems": 3, + "propertyOrder" : 1 + }, + "color_two": { + "type": "array", + "title":"edt_eff_colortwo", + "format":"colorpicker", + "default": [0,0,255], + "items" : { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "minItems": 3, + "maxItems": 3, + "propertyOrder" : 2 + }, + "colors_count": { + "type": "integer", + "title":"edt_eff_colorcount", + "default": 10, + "minimum" : 0, + "propertyOrder" : 3 + }, + "rotation-time": { + "type": "number", + "title":"edt_eff_rotationtime", + "default": 2.0, + "minimum" : 0.1, + "append" : "edt_append_s", + "propertyOrder" : 4 + }, + "reverse": { + "type": "boolean", + "title":"edt_eff_reversedirection", + "default": false, + "propertyOrder" : 5 + } + }, + "additionalProperties": false +} diff --git a/effects/schema/random.schema.json b/effects/schema/random.schema.json index d55810fb..bacacd6a 100644 --- a/effects/schema/random.schema.json +++ b/effects/schema/random.schema.json @@ -1,26 +1,90 @@ -{ - "type":"object", - "script" : "random.py", - "title":"edt_eff_random_header", - "required":true, - "properties":{ - "speed": { - "type": "number", - "title":"edt_eff_speed", - "default": 1000, - "minimum" : 10, - "append" : "edt_append_ms", - "propertyOrder" : 1 - }, - "saturation": { - "type": "number", - "title":"edt_eff_saturation", - "default": 1.0, - "minimum" : 0.1, - "maximum" : 1.0, - "step" : 0.1, - "propertyOrder" : 2 - } - }, - "additionalProperties": false -} +{ + "type":"object", + "script" : "random.py", + "title":"edt_eff_random_header", + "required":true, + "properties":{ + "speed": { + "type": "number", + "title":"edt_eff_speed", + "default": 1000, + "minimum" : 10, + "append" : "edt_append_ms", + "propertyOrder" : 1 + }, + "saturation": { + "type": "number", + "title":"edt_eff_saturation", + "default": 1.0, + "minimum" : 0.1, + "maximum" : 1.0, + "step" : 0.1, + "propertyOrder" : 2 + }, + "smoothing-custom-settings" : + { + "type" : "boolean", + "title" : "edt_eff_smooth_custom_title", + "default" : false, + "propertyOrder" : 3 + }, + "smoothing-time_ms" : + { + "type" : "integer", + "title" : "edt_eff_smooth_time_ms_title", + "minimum" : 25, + "maximum": 600, + "default" : 200, + "append" : "edt_append_ms", + "options": { + "dependencies": { + "smoothing-custom-settings": true + } + }, + "propertyOrder" : 4 + }, + "smoothing-updateFrequency" : + { + "type" : "number", + "title" : "edt_eff_smooth_updateFrequency_title", + "minimum" : 1.0, + "maximum" : 100.0, + "default" : 25.0, + "append" : "edt_append_hz", + "options": { + "dependencies": { + "smoothing-custom-settings": true + } + }, + "propertyOrder" : 5 + }, + "smoothing-updateDelay" : + { + "type" : "integer", + "title" : "edt_eff_smooth_updateDelay_title", + "minimum" : 0, + "maximum": 2048, + "default" : 0, + "append" : "edt_append_ms", + "options": { + "dependencies": { + "smoothing-custom-settings": true + } + }, + "propertyOrder" : 6 + }, + "smoothing-pause" : + { + "type" : "boolean", + "title" : "edt_eff_smooth_pause_title", + "default" : false, + "options": { + "dependencies": { + "smoothing-custom-settings": true + } + }, + "propertyOrder" : 7 + } + }, + "additionalProperties": false +} diff --git a/effects/schema/running_dots.schema.json b/effects/schema/running_dots.schema.json index 1f67efd3..5661bde7 100644 --- a/effects/schema/running_dots.schema.json +++ b/effects/schema/running_dots.schema.json @@ -1,32 +1,32 @@ -{ - "type":"object", - "script" : "running_dots.py", - "title":"edt_eff_runningdots_header", - "required":true, - "properties":{ - "speed": { - "type": "number", - "title":"edt_eff_speed", - "default": 1.5, - "minimum" : 0.1, - "propertyOrder" : 1 - }, - "colorLevel": { - "type": "integer", - "title":"edt_eff_colorevel", - "default": 220, - "minimium" : 0, - "maximum" : 255, - "propertyOrder" : 2 - }, - "whiteLevel": { - "type": "integer", - "title":"edt_eff_whitelevel", - "default": 0, - "minimium" : 0, - "maximum" : 254, - "propertyOrder" : 3 - } - }, - "additionalProperties": false -} +{ + "type":"object", + "script" : "running_dots.py", + "title":"edt_eff_runningdots_header", + "required":true, + "properties":{ + "speed": { + "type": "number", + "title":"edt_eff_speed", + "default": 1.5, + "minimum" : 0.1, + "propertyOrder" : 1 + }, + "colorLevel": { + "type": "integer", + "title":"edt_eff_colorevel", + "default": 220, + "minimium" : 0, + "maximum" : 255, + "propertyOrder" : 2 + }, + "whiteLevel": { + "type": "integer", + "title":"edt_eff_whitelevel", + "default": 0, + "minimium" : 0, + "maximum" : 254, + "propertyOrder" : 3 + } + }, + "additionalProperties": false +} diff --git a/effects/schema/snake.schema.json b/effects/schema/snake.schema.json index dc39fb28..f7135468 100644 --- a/effects/schema/snake.schema.json +++ b/effects/schema/snake.schema.json @@ -1,38 +1,38 @@ -{ - "type":"object", - "script" : "snake.py", - "title":"edt_eff_snake_header", - "required":true, - "properties":{ - "color": { - "type": "array", - "title":"edt_eff_color", - "format":"colorpicker", - "default": [255,0,0], - "items" : { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "minItems": 3, - "maxItems": 3, - "propertyOrder" : 1 - }, - "rotation-time": { - "type": "number", - "title":"edt_eff_rotationtime", - "default": 12.0, - "minimum" : 0.1, - "append" : "edt_append_s", - "propertyOrder" : 2 - }, - "percentage": { - "type": "integer", - "title":"edt_eff_length", - "default": 10, - "append" : "edt_append_percent", - "propertyOrder" : 3 - } - }, - "additionalProperties": false -} +{ + "type":"object", + "script" : "snake.py", + "title":"edt_eff_snake_header", + "required":true, + "properties":{ + "color": { + "type": "array", + "title":"edt_eff_color", + "format":"colorpicker", + "default": [255,0,0], + "items" : { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "minItems": 3, + "maxItems": 3, + "propertyOrder" : 1 + }, + "rotation-time": { + "type": "number", + "title":"edt_eff_rotationtime", + "default": 12.0, + "minimum" : 0.1, + "append" : "edt_append_s", + "propertyOrder" : 2 + }, + "percentage": { + "type": "integer", + "title":"edt_eff_length", + "default": 10, + "append" : "edt_append_percent", + "propertyOrder" : 3 + } + }, + "additionalProperties": false +} diff --git a/effects/schema/sparks.schema.json b/effects/schema/sparks.schema.json index b8182aa6..419543d6 100644 --- a/effects/schema/sparks.schema.json +++ b/effects/schema/sparks.schema.json @@ -1,69 +1,69 @@ -{ - "type":"object", - "script" : "sparks.py", - "title":"edt_eff_sparks_header", - "required":true, - "properties":{ - "color": { - "type": "array", - "title":"edt_eff_color", - "format":"colorpicker", - "default": [255,0,0], - "items" : { - "type": "integer", - "minimum": 0, - "maximum": 255 - }, - "minItems": 3, - "maxItems": 3, - "options": { - "dependencies": { - "random-color": false - } - }, - "propertyOrder" : 1 - }, - "rotation-time": { - "type": "number", - "title":"edt_eff_rotationtime", - "default": 2.0, - "minimum" : 0.1, - "append" : "edt_append_s", - "propertyOrder" : 2 - }, - "sleep-time": { - "type": "number", - "title":"edt_eff_sleeptime", - "default": 0.05, - "minimum" : 0.01, - "propertyOrder" : 3 - }, - "brightness": { - "type": "integer", - "title":"edt_eff_brightness", - "default": 100, - "minimum" : 0, - "maximum" : 100, - "step" : 10, - "append" : "edt_append_percent", - "propertyOrder" : 4 - }, - "saturation": { - "type": "integer", - "title":"edt_eff_saturation", - "default": 100, - "minimum" : 0, - "maximum" : 100, - "step" : 10, - "append" : "edt_append_percent", - "propertyOrder" : 5 - }, - "random-color": { - "type": "boolean", - "title":"edt_eff_colorrandom", - "default": false, - "propertyOrder" : 6 - } - }, - "additionalProperties": false -} +{ + "type":"object", + "script" : "sparks.py", + "title":"edt_eff_sparks_header", + "required":true, + "properties":{ + "color": { + "type": "array", + "title":"edt_eff_color", + "format":"colorpicker", + "default": [255,0,0], + "items" : { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "minItems": 3, + "maxItems": 3, + "options": { + "dependencies": { + "random-color": false + } + }, + "propertyOrder" : 1 + }, + "rotation-time": { + "type": "number", + "title":"edt_eff_rotationtime", + "default": 2.0, + "minimum" : 0.1, + "append" : "edt_append_s", + "propertyOrder" : 2 + }, + "sleep-time": { + "type": "number", + "title":"edt_eff_sleeptime", + "default": 0.05, + "minimum" : 0.01, + "propertyOrder" : 3 + }, + "brightness": { + "type": "integer", + "title":"edt_eff_brightness", + "default": 100, + "minimum" : 0, + "maximum" : 100, + "step" : 10, + "append" : "edt_append_percent", + "propertyOrder" : 4 + }, + "saturation": { + "type": "integer", + "title":"edt_eff_saturation", + "default": 100, + "minimum" : 0, + "maximum" : 100, + "step" : 10, + "append" : "edt_append_percent", + "propertyOrder" : 5 + }, + "random-color": { + "type": "boolean", + "title":"edt_eff_colorrandom", + "default": false, + "propertyOrder" : 6 + } + }, + "additionalProperties": false +} diff --git a/include/effectengine/EffectDefinition.h b/include/effectengine/EffectDefinition.h index 1212e2e3..f5b5f477 100644 --- a/include/effectengine/EffectDefinition.h +++ b/include/effectengine/EffectDefinition.h @@ -8,4 +8,5 @@ struct EffectDefinition { QString name, script, file; QJsonObject args; + unsigned smoothCfg; }; diff --git a/include/effectengine/EffectEngine.h b/include/effectengine/EffectEngine.h index 0a070d9e..67b44647 100644 --- a/include/effectengine/EffectEngine.h +++ b/include/effectengine/EffectEngine.h @@ -48,7 +48,7 @@ public slots: int runEffect(const QString &effectName, int priority, int timeout = -1, const QString &origin="System"); /// Run the specified effect on the given priority channel and optionally specify a timeout - int runEffect(const QString &effectName, const QJsonObject & args, int priority, int timeout = -1, const QString &pythonScript = "", const QString &origin = "System"); + int runEffect(const QString &effectName, const QJsonObject & args, int priority, int timeout = -1, const QString &pythonScript = "", const QString &origin = "System", unsigned smoothCfg=0); /// Clear any effect running on the provided channel void channelCleared(int priority); @@ -65,7 +65,7 @@ private: bool loadEffectSchema(const QString & path, const QString & effectSchemaFile, EffectSchema &effectSchema); /// Run the specified effect on the given priority channel and optionally specify a timeout - int runEffectScript(const QString &script, const QString &name, const QJsonObject & args, int priority, int timeout = -1, const QString & origin="System"); + int runEffectScript(const QString &script, const QString &name, const QJsonObject & args, int priority, int timeout = -1, const QString & origin="System", unsigned smoothCfg=0); private: Hyperion * _hyperion; diff --git a/include/hyperion/Hyperion.h b/include/hyperion/Hyperion.h index 4be6e853..8de93dac 100644 --- a/include/hyperion/Hyperion.h +++ b/include/hyperion/Hyperion.h @@ -47,6 +47,7 @@ class EffectEngine; class RgbChannelAdjustment; class MultiColorAdjustment; class KODIVideoChecker; + /// /// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through /// the priority muxer. @@ -187,6 +188,9 @@ public: QString id; int getLatchTime() const; + + /// forward smoothing config + unsigned addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0); public slots: /// @@ -206,8 +210,9 @@ public slots: /// @param[in] timeout_ms The time the leds are set to the given colors [ms] /// @param[in] component The current component /// @param[in] origin Who set it + /// @param[in] smoothCfg smoothing config id /// - void setColors(int priority, const std::vector &ledColors, const int timeout_ms, bool clearEffects = true, hyperion::Components component=hyperion::COMP_INVALID, const QString origin="System"); + void setColors(int priority, const std::vector &ledColors, const int timeout_ms, bool clearEffects = true, hyperion::Components component=hyperion::COMP_INVALID, const QString origin="System", unsigned smoothCfg=SMOOTHING_MODE_DEFAULT); /// /// Writes the given colors to all leds for the given time and priority diff --git a/include/hyperion/PriorityMuxer.h b/include/hyperion/PriorityMuxer.h index cbdf0673..680b1a97 100644 --- a/include/hyperion/PriorityMuxer.h +++ b/include/hyperion/PriorityMuxer.h @@ -15,6 +15,11 @@ #include #include +// global defines +#define SMOOTHING_MODE_DEFAULT 0 +#define SMOOTHING_MODE_PAUSE 1 + + /// /// The PriorityMuxer handles the priority channels. Led values input is written to the priority map /// and the muxer keeps track of all active priorities. The current priority can be queried and per @@ -40,6 +45,8 @@ public: hyperion::Components componentId; /// Who set it QString origin; + /// id fo smoothing config + unsigned smooth_cfg; }; /// The lowest possible priority, which is used when no priority channels are active @@ -99,7 +106,7 @@ public: /// @param[in] component The component of the channel /// @param[in] origin Who set the channel /// - void setInput(const int priority, const std::vector& ledColors, const int64_t timeoutTime_ms=-1, hyperion::Components component=hyperion::COMP_INVALID, const QString origin="System"); + void setInput(const int priority, const std::vector& ledColors, const int64_t timeoutTime_ms=-1, hyperion::Components component=hyperion::COMP_INVALID, const QString origin="System", unsigned smooth_cfg=SMOOTHING_MODE_DEFAULT); /// /// Clears the specified priority channel diff --git a/libsrc/effectengine/Effect.cpp b/libsrc/effectengine/Effect.cpp index b6c2e0c8..15fbbd00 100644 --- a/libsrc/effectengine/Effect.cpp +++ b/libsrc/effectengine/Effect.cpp @@ -78,13 +78,14 @@ void Effect::registerHyperionExtensionModule() PyImport_AppendInittab("hyperion", &PyInit_hyperion); } -Effect::Effect(PyThreadState * mainThreadState, int priority, int timeout, const QString & script, const QString & name, const QJsonObject & args, const QString & origin) +Effect::Effect(PyThreadState * mainThreadState, int priority, int timeout, const QString & script, const QString & name, const QJsonObject & args, const QString & origin, unsigned smoothCfg) : QThread() , _mainThreadState(mainThreadState) , _priority(priority) , _timeout(timeout) , _script(script) , _name(name) + , _smoothCfg(smoothCfg) , _args(args) , _endTime(-1) , _interpreterThreadState(nullptr) @@ -93,7 +94,7 @@ Effect::Effect(PyThreadState * mainThreadState, int priority, int timeout, const , _colors() , _origin(origin) , _imageSize(Hyperion::getInstance()->getLedGridSize()) - ,_image(_imageSize,QImage::Format_ARGB32_Premultiplied) + , _image(_imageSize,QImage::Format_ARGB32_Premultiplied) { _colors.resize(_imageProcessor->getLedCount()); _colors.fill(ColorRgb::BLACK); @@ -277,7 +278,7 @@ PyObject* Effect::wrapSetColor(PyObject *self, PyObject *args) if (PyArg_ParseTuple(args, "bbb", &color.red, &color.green, &color.blue)) { effect->_colors.fill(color); - effect->setColors(effect->_priority, effect->_colors.toStdVector(), timeout, false, hyperion::COMP_EFFECT, effect->_origin); + effect->setColors(effect->_priority, effect->_colors.toStdVector(), timeout, false, hyperion::COMP_EFFECT, effect->_origin, effect->_smoothCfg); return Py_BuildValue(""); } return nullptr; @@ -295,7 +296,7 @@ PyObject* Effect::wrapSetColor(PyObject *self, PyObject *args) { char * data = PyByteArray_AS_STRING(bytearray); memcpy(effect->_colors.data(), data, length); - effect->setColors(effect->_priority, effect->_colors.toStdVector(), timeout, false, hyperion::COMP_EFFECT, effect->_origin); + effect->setColors(effect->_priority, effect->_colors.toStdVector(), timeout, false, hyperion::COMP_EFFECT, effect->_origin, effect->_smoothCfg); return Py_BuildValue(""); } else @@ -365,7 +366,7 @@ PyObject* Effect::wrapSetImage(PyObject *self, PyObject *args) memcpy(image.memptr(), data, length); std::vector v = effect->_colors.toStdVector(); effect->_imageProcessor->process(image, v); - effect->setColors(effect->_priority, v, timeout, false, hyperion::COMP_EFFECT, effect->_origin); + effect->setColors(effect->_priority, v, timeout, false, hyperion::COMP_EFFECT, effect->_origin, effect->_smoothCfg); return Py_BuildValue(""); } else @@ -456,7 +457,7 @@ PyObject* Effect::wrapImageShow(PyObject *self, PyObject *args) memcpy(image.memptr(), binaryImage.data(), binaryImage.size()); std::vector v = effect->_colors.toStdVector(); effect->_imageProcessor->process(image, v); - effect->setColors(effect->_priority, v, timeout, false, hyperion::COMP_EFFECT, effect->_origin); + effect->setColors(effect->_priority, v, timeout, false, hyperion::COMP_EFFECT, effect->_origin, effect->_smoothCfg); return Py_BuildValue(""); } @@ -552,7 +553,7 @@ PyObject* Effect::wrapImageConicalGradient(PyObject *self, PyObject *args) { argsOK = true; } - angle = std::max(std::min(angle,360),0); + angle = qMax(qMin(angle,360),0); if (argsOK) { @@ -644,7 +645,7 @@ PyObject* Effect::wrapImageRadialGradient(PyObject *self, PyObject *args) { QRect myQRect(startX,startY,width,height); - QRadialGradient gradient(QPoint(centerX,centerY), std::max(radius,0) ); + QRadialGradient gradient(QPoint(centerX,centerY), qMax(radius,0) ); char * data = PyByteArray_AS_STRING(bytearray); for (int idx=0; idx_painter; - startAngle = std::max(std::min(startAngle,360),0); - spanAngle = std::max(std::min(spanAngle,360),-360); + startAngle = qMax(qMin(startAngle,360),0); + spanAngle = qMax(qMin(spanAngle,360),-360); if( argCount == 7 || argCount == 5 ) { @@ -1045,7 +1046,7 @@ PyObject* Effect::wrapImageMinSize(PyObject *self, PyObject *args) { delete effect->_painter; - effect->_image = effect->_image.scaled(std::max(width,w),std::max(height,h), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + effect->_image = effect->_image.scaled(qMax(width,w),qMax(height,h), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); effect->_imageSize = effect->_image.size(); effect->_painter = new QPainter(&(effect->_image)); } @@ -1075,7 +1076,7 @@ PyObject* Effect::wrapImageCRotate(PyObject *self, PyObject *args) if ( argCount == 1 && PyArg_ParseTuple(args, "i", &angle ) ) { - angle = std::max(std::min(angle,360),0); + angle = qMax(qMin(angle,360),0); effect->_painter->rotate(angle); return Py_BuildValue(""); } diff --git a/libsrc/effectengine/Effect.h b/libsrc/effectengine/Effect.h index 2bcb5775..2d23355e 100644 --- a/libsrc/effectengine/Effect.h +++ b/libsrc/effectengine/Effect.h @@ -19,7 +19,7 @@ class Effect : public QThread Q_OBJECT public: - Effect(PyThreadState * mainThreadState, int priority, int timeout, const QString & script, const QString & name, const QJsonObject & args = QJsonObject(), const QString & origin="System"); + Effect(PyThreadState * mainThreadState, int priority, int timeout, const QString & script, const QString & name, const QJsonObject & args = QJsonObject(), const QString & origin="System", unsigned smoothCfg=0); virtual ~Effect(); virtual void run(); @@ -44,7 +44,7 @@ public slots: signals: void effectFinished(Effect * effect); - void setColors(int priority, const std::vector &ledColors, const int timeout_ms, bool clearEffects, hyperion::Components componentconst, QString origin); + void setColors(int priority, const std::vector &ledColors, const int timeout_ms, bool clearEffects, hyperion::Components componentconst, QString origin, unsigned smoothCfg); private slots: void effectFinished(); @@ -96,6 +96,7 @@ private: const QString _script; const QString _name; + unsigned _smoothCfg; const QJsonObject _args; @@ -112,10 +113,10 @@ private: QVector _colors; - QString _origin; - QSize _imageSize; - QImage _image; - QPainter* _painter; + QString _origin; + QSize _imageSize; + QImage _image; + QPainter* _painter; QVector _imageStack; }; diff --git a/libsrc/effectengine/EffectEngine.cpp b/libsrc/effectengine/EffectEngine.cpp index b719074a..ace23bb9 100644 --- a/libsrc/effectengine/EffectEngine.cpp +++ b/libsrc/effectengine/EffectEngine.cpp @@ -2,14 +2,12 @@ #include #undef B0 -// Stl includes -#include - // Qt includes #include #include #include #include +#include // hyperion util includes #include @@ -41,7 +39,7 @@ EffectEngine::EffectEngine(Hyperion * hyperion, const QJsonObject & jsonEffectCo readEffects(); // initialize the python interpreter - Debug(_log,"Initializing Python interpreter"); + Debug(_log, "Initializing Python interpreter"); Effect::registerHyperionExtensionModule(); Py_InitializeEx(0); PyEval_InitThreads(); // Create the GIL @@ -63,11 +61,11 @@ const std::list &EffectEngine::getActiveEffects() for (Effect * effect : _activeEffects) { ActiveEffectDefinition activeEffectDefinition; - activeEffectDefinition.script = effect->getScript(); - activeEffectDefinition.name = effect->getName(); + activeEffectDefinition.script = effect->getScript(); + activeEffectDefinition.name = effect->getName(); activeEffectDefinition.priority = effect->getPriority(); - activeEffectDefinition.timeout = effect->getTimeout(); - activeEffectDefinition.args = effect->getArgs(); + activeEffectDefinition.timeout = effect->getTimeout(); + activeEffectDefinition.args = effect->getArgs(); _availableActiveEffects.push_back(activeEffectDefinition); } @@ -86,7 +84,7 @@ bool EffectEngine::loadEffectDefinition(const QString &path, const QString &effe QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { - Error( log, "Effect file '%s' could not be loaded", fileName.toUtf8().constData()); + Error( log, "Effect file '%s' could not be loaded", QSTRING_CSTR(fileName)); return false; } @@ -108,7 +106,7 @@ bool EffectEngine::loadEffectDefinition(const QString &path, const QString &effe } } - Error( log, "Error while reading effect: '%s' at Line: '%i' , Column: %i", error.errorString().toUtf8().constData(), errorLine, errorColumn); + Error( log, "Error while reading effect: '%s' at Line: '%i' , Column: %i",QSTRING_CSTR( error.errorString()), errorLine, errorColumn); } file.close(); @@ -120,7 +118,7 @@ bool EffectEngine::loadEffectDefinition(const QString &path, const QString &effe if (!schema.open(QIODevice::ReadOnly)) { - Error( log, "Schema not found: %s", schema.errorString().toUtf8().constData()); + Error( log, "Schema not found: %s", QSTRING_CSTR(schema.errorString())); return false; } @@ -142,7 +140,7 @@ bool EffectEngine::loadEffectDefinition(const QString &path, const QString &effe } } - Error( log, "ERROR: Json schema wrong: '%s' at Line: '%i' , Column: %i", error.errorString().toUtf8().constData(), errorLine, errorColumn); + Error( log, "ERROR: Json schema wrong: '%s' at Line: '%i' , Column: %i", QSTRING_CSTR(error.errorString()), errorLine, errorColumn); } schema.close(); @@ -154,7 +152,7 @@ bool EffectEngine::loadEffectDefinition(const QString &path, const QString &effe if (!schemaChecker.validate(configEffect.object()).first) { const QStringList & errors = schemaChecker.getMessages(); - foreach (auto & error, errors) + for (auto & error : errors) { Error( log, "Error while checking '%s':%s", QSTRING_CSTR(fileName), QSTRING_CSTR(error)); } @@ -180,12 +178,27 @@ bool EffectEngine::loadEffectDefinition(const QString &path, const QString &effe } else { (!fileInfo.exists()) - ? effectDefinition.script = path + QDir::separator().toLatin1() + scriptName + ? effectDefinition.script = path + QDir::separator() + scriptName : effectDefinition.script = scriptName; } effectDefinition.args = config["args"].toObject(); - + effectDefinition.smoothCfg = SMOOTHING_MODE_PAUSE; + if (effectDefinition.args["smoothing-custom-settings"].toBool()) + { + bool pause = effectDefinition.args["smoothing-pause"].toBool(); + if (pause) + { + effectDefinition.smoothCfg = _hyperion->addSmoothingConfig(pause); + } + else + { + effectDefinition.smoothCfg = _hyperion->addSmoothingConfig( + effectDefinition.args["smoothing-time_ms"].toInt(), + effectDefinition.args["smoothing-updateFrequency"].toDouble(), + effectDefinition.args["smoothing-updateDelay"].toInt() ); + } + } return true; } @@ -201,7 +214,7 @@ bool EffectEngine::loadEffectSchema(const QString &path, const QString &effectSc QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { - Error( log, "Effect schema '%s' could not be loaded", fileName.toUtf8().constData()); + Error( log, "Effect schema '%s' could not be loaded", QSTRING_CSTR(fileName)); return false; } @@ -223,7 +236,7 @@ bool EffectEngine::loadEffectSchema(const QString &path, const QString &effectSc } } - Error( log, "Error while reading effect schema: '%s' at Line: '%i' , Column: %i", error.errorString().toUtf8().constData(), errorLine, errorColumn); + Error( log, "Error while reading effect schema: '%s' at Line: '%i' , Column: %i", QSTRING_CSTR(error.errorString()), errorLine, errorColumn); return false; } @@ -240,17 +253,13 @@ bool EffectEngine::loadEffectSchema(const QString &path, const QString &effectSc if (scriptName.isEmpty() || !pyFile.open(QIODevice::ReadOnly)) { fileName = path + "schema/" + QDir::separator() + effectSchemaFile; - Error( log, "Python script '%s' in effect schema '%s' could not be loaded", scriptName.toUtf8().constData(), fileName.toUtf8().constData()); + Error( log, "Python script '%s' in effect schema '%s' could not be loaded", QSTRING_CSTR(scriptName), QSTRING_CSTR(fileName)); return false; } pyFile.close(); - if (scriptName.mid(0, 1) == ":" ) - effectSchema.pyFile = ":/effects/"+scriptName.mid(1); - else - effectSchema.pyFile = path + QDir::separator().toLatin1() + scriptName; - + effectSchema.pyFile = (scriptName.mid(0, 1) == ":" ) ? ":/effects/"+scriptName.mid(1) : path + QDir::separator() + scriptName; effectSchema.pySchema = tempSchemaEffect; return true; @@ -279,38 +288,36 @@ void EffectEngine::readEffects() disableList << efx.toString(); } - std::map availableEffects; - foreach (const QString & path, efxPathList ) + QMap availableEffects; + for (const QString & path : efxPathList ) { QDir directory(path); if (!directory.exists()) { if(directory.mkpath(path)) { - Warning(_log, "New Effect path \"%s\" created successfull",path.toUtf8().constData() ); + Warning(_log, "New Effect path \"%s\" created successfull", QSTRING_CSTR(path) ); } else { - Warning(_log, "Failed to create Effect path \"%s\", please check permissions",path.toUtf8().constData() ); + Warning(_log, "Failed to create Effect path \"%s\", please check permissions", QSTRING_CSTR(path) ); } } else { int efxCount = 0; QStringList filenames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase); - foreach (const QString & filename, filenames) + for (const QString & filename : filenames) { EffectDefinition def; if (loadEffectDefinition(path, filename, def)) { - if (availableEffects.find(def.name) != availableEffects.end()) - { - Info(_log, "effect overload effect '%s' is now taken from %s'", def.name.toUtf8().constData(), path.toUtf8().constData() ); - } + InfoIf(availableEffects.find(def.name) != availableEffects.end(), _log, + "effect overload effect '%s' is now taken from %s'", QSTRING_CSTR(def.name), QSTRING_CSTR(path) ); if ( disableList.contains(def.name) ) { - Info(_log, "effect '%s' not loaded, because it is disabled in hyperion config", def.name.toUtf8().constData()); + Info(_log, "effect '%s' not loaded, because it is disabled in hyperion config", QSTRING_CSTR(def.name)); } else { @@ -319,13 +326,13 @@ void EffectEngine::readEffects() } } } - Info(_log, "%d effects loaded from directory %s", efxCount, path.toUtf8().constData()); + Info(_log, "%d effects loaded from directory %s", efxCount, QSTRING_CSTR(path)); // collect effect schemas efxCount = 0; directory = path + "schema/"; QStringList pynames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase); - foreach (const QString & pyname, pynames) + for (const QString & pyname : pynames) { EffectSchema pyEffect; if (loadEffectSchema(path, pyname, pyEffect)) @@ -334,20 +341,16 @@ void EffectEngine::readEffects() efxCount++; } } - if (efxCount > 0) - Info(_log, "%d effect schemas loaded from directory %s", efxCount, (path + "schema/").toUtf8().constData()); + InfoIf(efxCount > 0, _log, "%d effect schemas loaded from directory %s", efxCount, QSTRING_CSTR((path + "schema/"))); } } - foreach(auto item, availableEffects) + for(auto item : availableEffects) { - _availableEffects.push_back(item.second); + _availableEffects.push_back(item); } - if (_availableEffects.size() == 0) - { - Error(_log, "no effects found, check your effect directories"); - } + ErrorIf(_availableEffects.size()==0, _log, "no effects found, check your effect directories"); } int EffectEngine::runEffect(const QString &effectName, int priority, int timeout, const QString &origin) @@ -355,9 +358,9 @@ int EffectEngine::runEffect(const QString &effectName, int priority, int timeout return runEffect(effectName, QJsonObject(), priority, timeout, "", origin); } -int EffectEngine::runEffect(const QString &effectName, const QJsonObject &args, int priority, int timeout, const QString &pythonScript, const QString &origin) +int EffectEngine::runEffect(const QString &effectName, const QJsonObject &args, int priority, int timeout, const QString &pythonScript, const QString &origin, unsigned smoothCfg) { - Info( _log, "run effect %s on channel %d", effectName.toUtf8().constData(), priority); + Info( _log, "run effect %s on channel %d", QSTRING_CSTR(effectName), priority); if (pythonScript.isEmpty()) { @@ -373,23 +376,23 @@ int EffectEngine::runEffect(const QString &effectName, const QJsonObject &args, if (effectDefinition == nullptr) { // no such effect - Error(_log, "effect %s not found", effectName.toUtf8().constData()); + Error(_log, "effect %s not found", QSTRING_CSTR(effectName)); return -1; } - return runEffectScript(effectDefinition->script, effectName, (args.isEmpty() ? effectDefinition->args : args), priority, timeout, origin); + return runEffectScript(effectDefinition->script, effectName, (args.isEmpty() ? effectDefinition->args : args), priority, timeout, origin, effectDefinition->smoothCfg); } - return runEffectScript(pythonScript, effectName, args, priority, timeout, origin); + return runEffectScript(pythonScript, effectName, args, priority, timeout, origin, smoothCfg); } -int EffectEngine::runEffectScript(const QString &script, const QString &name, const QJsonObject &args, int priority, int timeout, const QString & origin) +int EffectEngine::runEffectScript(const QString &script, const QString &name, const QJsonObject &args, int priority, int timeout, const QString & origin, unsigned smoothCfg) { // clear current effect on the channel channelCleared(priority); // create the effect - Effect * effect = new Effect(_mainThreadState, priority, timeout, script, name, args, origin); - connect(effect, SIGNAL(setColors(int,std::vector,int,bool,hyperion::Components,const QString)), _hyperion, SLOT(setColors(int,std::vector,int,bool,hyperion::Components,const QString)), Qt::QueuedConnection); + Effect * effect = new Effect(_mainThreadState, priority, timeout, script, name, args, origin, smoothCfg); + connect(effect, SIGNAL(setColors(int,std::vector,int,bool,hyperion::Components,const QString,unsigned)), _hyperion, SLOT(setColors(int,std::vector,int,bool,hyperion::Components,const QString,unsigned)), Qt::QueuedConnection); connect(effect, SIGNAL(effectFinished(Effect*)), this, SLOT(effectFinished(Effect*))); _activeEffects.push_back(effect); diff --git a/libsrc/grabber/amlogic/AmlogicGrabber.cpp b/libsrc/grabber/amlogic/AmlogicGrabber.cpp index a609b3b8..76db83a8 100755 --- a/libsrc/grabber/amlogic/AmlogicGrabber.cpp +++ b/libsrc/grabber/amlogic/AmlogicGrabber.cpp @@ -31,8 +31,8 @@ #endif AmlogicGrabber::AmlogicGrabber(const unsigned width, const unsigned height) - : _width(std::max(160u, width)) // Minimum required width or height is 160 - , _height(std::max(160u, height)) + : _width(qMax(160u, width)) // Minimum required width or height is 160 + , _height(qMax(160u, height)) , _amlogicCaptureDev(-1) , _log(Logger::getInstance("AMLOGICGRABBER")) { diff --git a/libsrc/grabber/v4l2/V4L2Grabber.cpp b/libsrc/grabber/v4l2/V4L2Grabber.cpp index 4bd98509..11739dd3 100644 --- a/libsrc/grabber/v4l2/V4L2Grabber.cpp +++ b/libsrc/grabber/v4l2/V4L2Grabber.cpp @@ -44,7 +44,7 @@ V4L2Grabber::V4L2Grabber(const QString & device , _height(height) , _lineLength(-1) , _frameByteSize(-1) - , _frameDecimation(std::max(1, frameDecimation)) + , _frameDecimation(qMax(1, frameDecimation)) , _noSignalCounterThreshold(50) , _noSignalThresholdColor(ColorRgb{0,0,0}) , _signalDetectionEnabled(true) @@ -62,8 +62,8 @@ V4L2Grabber::V4L2Grabber(const QString & device , _deviceAutoDiscoverEnabled(false) { - _imageResampler.setHorizontalPixelDecimation(std::max(1, horizontalPixelDecimation)); - _imageResampler.setVerticalPixelDecimation(std::max(1, verticalPixelDecimation)); + _imageResampler.setHorizontalPixelDecimation(qMax(1, horizontalPixelDecimation)); + _imageResampler.setVerticalPixelDecimation(qMax(1, verticalPixelDecimation)); getV4Ldevices(); } @@ -198,7 +198,7 @@ void V4L2Grabber::setSignalThreshold(double redSignalThreshold, double greenSign _noSignalThresholdColor.red = uint8_t(255*redSignalThreshold); _noSignalThresholdColor.green = uint8_t(255*greenSignalThreshold); _noSignalThresholdColor.blue = uint8_t(255*blueSignalThreshold); - _noSignalCounterThreshold = std::max(1, noSignalCounterThreshold); + _noSignalCounterThreshold = qMax(1, noSignalCounterThreshold); Info(_log, "Signal threshold set to: {%d, %d, %d}", _noSignalThresholdColor.red, _noSignalThresholdColor.green, _noSignalThresholdColor.blue ); } diff --git a/libsrc/grabber/x11/X11Grabber.cpp b/libsrc/grabber/x11/X11Grabber.cpp index feae804b..2b75abcf 100755 --- a/libsrc/grabber/x11/X11Grabber.cpp +++ b/libsrc/grabber/x11/X11Grabber.cpp @@ -1,9 +1,4 @@ -// STL includes -#include -#include #include - -// X11Grabber includes #include X11Grabber::X11Grabber(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation) @@ -137,7 +132,7 @@ Image & X11Grabber::grab() { double scale_x = static_cast(_windowAttr.width / _horizontalDecimation) / static_cast(_windowAttr.width); double scale_y = static_cast(_windowAttr.height / _verticalDecimation) / static_cast(_windowAttr.height); - double scale = std::min(scale_y, scale_x); + double scale = qMin(scale_y, scale_x); _transform = { @@ -215,7 +210,7 @@ int X11Grabber::grabFrame(Image & image) { double scale_x = static_cast(_windowAttr.width / _horizontalDecimation) / static_cast(_windowAttr.width); double scale_y = static_cast(_windowAttr.height / _verticalDecimation) / static_cast(_windowAttr.height); - double scale = std::min(scale_y, scale_x); + double scale = qMin(scale_y, scale_x); _transform = { diff --git a/libsrc/hyperion/Hyperion.cpp b/libsrc/hyperion/Hyperion.cpp index 5a3143a7..d9517ec6 100644 --- a/libsrc/hyperion/Hyperion.cpp +++ b/libsrc/hyperion/Hyperion.cpp @@ -1,10 +1,8 @@ // STL includes -#include #include #include #include -#include // QT includes #include @@ -208,10 +206,10 @@ LedString Hyperion::createLedString(const QJsonValue& ledsConfig, const ColorOrd { const QJsonObject& hscanConfig = ledConfigArray[i].toObject()["hscan"].toObject(); const QJsonObject& vscanConfig = ledConfigArray[i].toObject()["vscan"].toObject(); - led.minX_frac = std::max(0.0, std::min(1.0, hscanConfig["minimum"].toDouble())); - led.maxX_frac = std::max(0.0, std::min(1.0, hscanConfig["maximum"].toDouble())); - led.minY_frac = std::max(0.0, std::min(1.0, vscanConfig["minimum"].toDouble())); - led.maxY_frac = std::max(0.0, std::min(1.0, vscanConfig["maximum"].toDouble())); + led.minX_frac = qMax(0.0, qMin(1.0, hscanConfig["minimum"].toDouble())); + led.maxX_frac = qMax(0.0, qMin(1.0, hscanConfig["maximum"].toDouble())); + led.minY_frac = qMax(0.0, qMin(1.0, vscanConfig["minimum"].toDouble())); + led.maxY_frac = qMax(0.0, qMin(1.0, vscanConfig["maximum"].toDouble())); // Fix if the user swapped min and max if (led.minX_frac > led.maxX_frac) { @@ -287,10 +285,10 @@ QSize Hyperion::getLedLayoutGridSize(const QJsonValue& ledsConfig) { const QJsonObject& hscanConfig = ledConfigArray[i].toObject()["hscan"].toObject(); const QJsonObject& vscanConfig = ledConfigArray[i].toObject()["vscan"].toObject(); - double minX_frac = std::max(0.0, std::min(1.0, hscanConfig["minimum"].toDouble())); - double maxX_frac = std::max(0.0, std::min(1.0, hscanConfig["maximum"].toDouble())); - double minY_frac = std::max(0.0, std::min(1.0, vscanConfig["minimum"].toDouble())); - double maxY_frac = std::max(0.0, std::min(1.0, vscanConfig["maximum"].toDouble())); + double minX_frac = qMax(0.0, qMin(1.0, hscanConfig["minimum"].toDouble())); + double maxX_frac = qMax(0.0, qMin(1.0, hscanConfig["maximum"].toDouble())); + double minY_frac = qMax(0.0, qMin(1.0, vscanConfig["minimum"].toDouble())); + double maxY_frac = qMax(0.0, qMin(1.0, vscanConfig["maximum"].toDouble())); // Fix if the user swapped min and max if (minX_frac > maxX_frac) { @@ -345,7 +343,7 @@ LinearColorSmoothing * Hyperion::createColorSmoothing(const QJsonObject & smooth device->setEnable(smoothingConfig["enable"].toBool(true)); InfoIf(!device->enabled(), CORE_LOGGER,"Smoothing disabled"); - assert(device != nullptr); + Q_ASSERT(device != nullptr); return device; } @@ -427,6 +425,8 @@ Hyperion::Hyperion(const QJsonObject &qjsonConfig, const QString configFile) getComponentRegister().componentStateChanged(hyperion::COMP_SMOOTHING, _deviceSmooth->componentState()); getComponentRegister().componentStateChanged(hyperion::COMP_LEDDEVICE, _device->componentState()); + _deviceSmooth->addConfig(true); // add pause to config 1 + // setup the timer _timer.setSingleShot(true); QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(update())); @@ -436,12 +436,12 @@ Hyperion::Hyperion(const QJsonObject &qjsonConfig, const QString configFile) QObject::connect(&_timerBonjourResolver, SIGNAL(timeout()), this, SLOT(bonjourResolve())); _timerBonjourResolver.start(); - // create the effect engine + // create the effect engine, must be initialized after smoothing! _effectEngine = new EffectEngine(this,qjsonConfig["effects"].toObject() ); const QJsonObject& device = qjsonConfig["device"].toObject(); unsigned int hwLedCount = device["ledCount"].toInt(getLedCount()); - _hwLedCount = std::max(hwLedCount, getLedCount()); + _hwLedCount = qMax(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"); @@ -478,6 +478,11 @@ int Hyperion::getLatchTime() const return _device->getLatchTime(); } +unsigned Hyperion::addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay) +{ + return _deviceSmooth->addConfig(settlingTime_ms, ledUpdateFrequency_hz, updateDelay); +} + void Hyperion::freeObjects(bool emitCloseSignal) { if (emitCloseSignal) @@ -664,7 +669,7 @@ void Hyperion::setColor(int priority, const ColorRgb &color, const int timeout_m setColors(priority, ledColors, timeout_ms, clearEffects, hyperion::COMP_COLOR); } -void Hyperion::setColors(int priority, const std::vector& ledColors, const int timeout_ms, bool clearEffects, hyperion::Components component, const QString origin) +void Hyperion::setColors(int priority, const std::vector& ledColors, const int timeout_ms, bool clearEffects, hyperion::Components component, const QString origin, unsigned smoothCfg) { // clear effects if this call does not come from an effect if (clearEffects) @@ -675,11 +680,11 @@ void Hyperion::setColors(int priority, const std::vector& ledColors, c if (timeout_ms > 0) { const uint64_t timeoutTime = QDateTime::currentMSecsSinceEpoch() + timeout_ms; - _muxer.setInput(priority, ledColors, timeoutTime, component, origin); + _muxer.setInput(priority, ledColors, timeoutTime, component, origin, smoothCfg); } else { - _muxer.setInput(priority, ledColors, -1, component, origin); + _muxer.setInput(priority, ledColors, -1, component, origin, smoothCfg); } if (! _sourceAutoSelectEnabled || priority == _muxer.getCurrentPriority()) @@ -891,7 +896,8 @@ void Hyperion::update() // Write the data to the device if (_device->enabled()) { - _deviceSmooth->setPause(priorityInfo.componentId == hyperion::COMP_EFFECT); + _deviceSmooth->selectConfig(priorityInfo.smooth_cfg); + // feed smoothing in pause mode to maintain a smooth transistion back to smoth mode if (_deviceSmooth->enabled() || _deviceSmooth->pause()) _deviceSmooth->setLedValues(_ledBuffer); @@ -907,9 +913,9 @@ void Hyperion::update() } else { - int timeout_ms = std::max(0, int(priorityInfo.timeoutTime_ms - QDateTime::currentMSecsSinceEpoch())); - // std::min() 200ms forced refresh if color is active to update priorityMuxer properly for forced serverinfo push - _timer.start(std::min(timeout_ms, 200)); + int timeout_ms = qMax(0, int(priorityInfo.timeoutTime_ms - QDateTime::currentMSecsSinceEpoch())); + // qMin() 200ms forced refresh if color is active to update priorityMuxer properly for forced serverinfo push + _timer.start(qMin(timeout_ms, 200)); } } diff --git a/libsrc/hyperion/ImageToLedsMap.cpp b/libsrc/hyperion/ImageToLedsMap.cpp index 38cacc69..679b46b8 100644 --- a/libsrc/hyperion/ImageToLedsMap.cpp +++ b/libsrc/hyperion/ImageToLedsMap.cpp @@ -1,9 +1,3 @@ -// STL includes -#include -#include -#include - -// hyperion includes #include using namespace hyperion; @@ -21,8 +15,8 @@ ImageToLedsMap::ImageToLedsMap( , _colorsMap() { // Sanity check of the size of the borders (and width and height) - assert(_width > 2*_verticalBorder); - assert(_height > 2*_horizontalBorder); + Q_ASSERT(_width > 2*_verticalBorder); + Q_ASSERT(_height > 2*_horizontalBorder); // Reserve enough space in the map for the leds _colorsMap.reserve(leds.size()); @@ -42,18 +36,18 @@ ImageToLedsMap::ImageToLedsMap( } // Compute the index boundaries for this led - unsigned minX_idx = xOffset + unsigned(std::round(actualWidth * led.minX_frac)); - unsigned maxX_idx = xOffset + unsigned(std::round(actualWidth * led.maxX_frac)); - unsigned minY_idx = yOffset + unsigned(std::round(actualHeight * led.minY_frac)); - unsigned maxY_idx = yOffset + unsigned(std::round(actualHeight * led.maxY_frac)); + unsigned minX_idx = xOffset + unsigned(qRound(actualWidth * led.minX_frac)); + unsigned maxX_idx = xOffset + unsigned(qRound(actualWidth * led.maxX_frac)); + unsigned minY_idx = yOffset + unsigned(qRound(actualHeight * led.minY_frac)); + unsigned maxY_idx = yOffset + unsigned(qRound(actualHeight * led.maxY_frac)); // make sure that the area is at least a single led large - minX_idx = std::min(minX_idx, xOffset + actualWidth - 1); + minX_idx = qMin(minX_idx, xOffset + actualWidth - 1); if (minX_idx == maxX_idx) { maxX_idx = minX_idx + 1; } - minY_idx = std::min(minY_idx, yOffset + actualHeight - 1); + minY_idx = qMin(minY_idx, yOffset + actualHeight - 1); if (minY_idx == maxY_idx) { maxY_idx = minY_idx + 1; diff --git a/libsrc/hyperion/LinearColorSmoothing.cpp b/libsrc/hyperion/LinearColorSmoothing.cpp index 0fea4d5c..b4404be9 100644 --- a/libsrc/hyperion/LinearColorSmoothing.cpp +++ b/libsrc/hyperion/LinearColorSmoothing.cpp @@ -8,6 +8,7 @@ using namespace hyperion; +// ledUpdateFrequency_hz = 0 > cause divide by zero! LinearColorSmoothing::LinearColorSmoothing( LedDevice * ledDevice, double ledUpdateFrequency_hz, int settlingTime_ms, unsigned updateDelay, bool continuousOutput) : LedDevice() , _ledDevice(ledDevice) @@ -18,14 +19,20 @@ LinearColorSmoothing::LinearColorSmoothing( LedDevice * ledDevice, double ledUpd , _writeToLedsEnable(true) , _continuousOutput(continuousOutput) , _pause(false) + , _currentConfigId(0) { _log = Logger::getInstance("Smoothing"); _timer.setSingleShot(false); _timer.setInterval(_updateInterval); + selectConfig( addConfig(_settlingTime, ledUpdateFrequency_hz, updateDelay) ); + + // add pause on cfg 1 + SMOOTHING_CFG cfg = {true, 100, 50, 0}; + _cfgList.append(cfg); + Info( _log, "smoothing cfg %d: pause", _cfgList.count()-1); + connect(&_timer, SIGNAL(timeout()), this, SLOT(updateLeds())); - Info( _log, "Created linear-smoothing with interval: %d ms, settlingTime: %d ms, updateDelay: %d frames", - _updateInterval, settlingTime_ms, _outputDelay ); } LinearColorSmoothing::~LinearColorSmoothing() @@ -160,3 +167,44 @@ void LinearColorSmoothing::setPause(bool pause) _pause = pause; } +unsigned LinearColorSmoothing::addConfig(int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay) +{ + SMOOTHING_CFG cfg = {false, settlingTime_ms, int64_t(1000.0/ledUpdateFrequency_hz), updateDelay}; + _cfgList.append(cfg); + + Info( _log, "smoothing cfg %d: interval: %d ms, settlingTime: %d ms, updateDelay: %d frames", _cfgList.count()-1, cfg.updateInterval, cfg.settlingTime, cfg.outputDelay ); + return _cfgList.count() - 1; +} + +bool LinearColorSmoothing::selectConfig(unsigned cfg) +{ + if (_currentConfigId == cfg) + { + return true; + } + + if ( cfg < (unsigned)_cfgList.count()) + { + _settlingTime = _cfgList[cfg].settlingTime; + _outputDelay = _cfgList[cfg].outputDelay; + _pause = _cfgList[cfg].pause; + + if (_cfgList[cfg].updateInterval != _updateInterval) + { + _timer.stop(); + _updateInterval = _cfgList[cfg].updateInterval; + _timer.setInterval(_updateInterval); + _timer.start(); + } + _currentConfigId = cfg; + InfoIf( enabled() && !_pause, _log, "set smoothing cfg: %d, interval: %d ms, settlingTime: %d ms, updateDelay: %d frames", _currentConfigId, _updateInterval, _settlingTime, _outputDelay ); + InfoIf( _pause, _log, "set smoothing cfg: %d, pause", _currentConfigId ); + + return true; + } + + // reset to default + _currentConfigId = 0; + return false; +} + diff --git a/libsrc/hyperion/LinearColorSmoothing.h b/libsrc/hyperion/LinearColorSmoothing.h index bcb00a26..34aff620 100644 --- a/libsrc/hyperion/LinearColorSmoothing.h +++ b/libsrc/hyperion/LinearColorSmoothing.h @@ -6,6 +6,7 @@ // Qt includes #include +#include // hyperion incluse #include @@ -33,7 +34,7 @@ public: /// write updated values as input for the smoothing filter /// /// @param ledValues The color-value per led - /// @return Zero on succes else negative + /// @return Zero on success else negative /// virtual int write(const std::vector &ledValues); @@ -45,6 +46,9 @@ public: bool pause() { return _pause; } ; bool enabled() { return LedDevice::enabled() && !_pause; }; + unsigned addConfig(int settlingTime_ms, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0); + bool selectConfig(unsigned cfg); + private slots: /// Timer callback which writes updated led values to the led device void updateLeds(); @@ -61,10 +65,10 @@ private: LedDevice * _ledDevice; /// The interval at which to update the leds (msec) - const int64_t _updateInterval; + int64_t _updateInterval; /// The time after which the updated led values have been fully applied (msec) - const int64_t _settlingTime; + int64_t _settlingTime; /// The Qt timer object QTimer _timer; @@ -82,7 +86,7 @@ private: std::vector _previousValues; /// The number of updates to keep in the output queue (delayed) before being output - const unsigned _outputDelay; + unsigned _outputDelay; /// The output queue std::list > _outputQueue; @@ -94,4 +98,17 @@ private: /// Flag for pausing bool _pause; + + struct SMOOTHING_CFG + { + bool pause; + int64_t settlingTime; + int64_t updateInterval; + unsigned outputDelay; + }; + + /// config list + QVector _cfgList; + + unsigned _currentConfigId; }; diff --git a/libsrc/hyperion/MultiColorAdjustment.cpp b/libsrc/hyperion/MultiColorAdjustment.cpp index cbf38fe3..32985dba 100644 --- a/libsrc/hyperion/MultiColorAdjustment.cpp +++ b/libsrc/hyperion/MultiColorAdjustment.cpp @@ -1,7 +1,3 @@ - -// STL includes -#include - // Hyperion includes #include #include "MultiColorAdjustment.h" @@ -29,8 +25,8 @@ void MultiColorAdjustment::addAdjustment(ColorAdjustment * adjustment) void MultiColorAdjustment::setAdjustmentForLed(const QString& id, const unsigned startLed, const unsigned endLed) { - assert(startLed <= endLed); - assert(endLed < _ledAdjustments.size()); + Q_ASSERT(startLed <= endLed); + Q_ASSERT(endLed < _ledAdjustments.size()); // Get the identified adjustment (don't care if is nullptr) ColorAdjustment * adjustment = getAdjustment(id); @@ -83,10 +79,9 @@ void MultiColorAdjustment::setBacklightEnabled(bool enable) } } - void MultiColorAdjustment::applyAdjustment(std::vector& ledColors) { - const size_t itCnt = std::min(_ledAdjustments.size(), ledColors.size()); + const size_t itCnt = qMin(_ledAdjustments.size(), ledColors.size()); for (size_t i=0; i // STL includes #include #include @@ -27,7 +26,6 @@ PriorityMuxer::PriorityMuxer(int ledCount) PriorityMuxer::~PriorityMuxer() { - // empty } int PriorityMuxer::getCurrentPriority() const @@ -55,7 +53,7 @@ const PriorityMuxer::InputInfo& PriorityMuxer::getInputInfo(const int priority) return elemIt.value(); } -void PriorityMuxer::setInput(const int priority, const std::vector& ledColors, const int64_t timeoutTime_ms, hyperion::Components component, const QString origin) +void PriorityMuxer::setInput(const int priority, const std::vector& ledColors, const int64_t timeoutTime_ms, hyperion::Components component, const QString origin, unsigned smooth_cfg) { InputInfo& input = _activeInputs[priority]; input.priority = priority; @@ -63,7 +61,8 @@ void PriorityMuxer::setInput(const int priority, const std::vector& le input.ledColors = ledColors; input.componentId = component; input.origin = origin; - _currentPriority = std::min(_currentPriority, priority); + input.smooth_cfg = smooth_cfg; + _currentPriority = qMin(_currentPriority, priority); } void PriorityMuxer::clearInput(const int priority) @@ -101,8 +100,8 @@ void PriorityMuxer::setCurrentTime(const int64_t& now) infoIt = _activeInputs.erase(infoIt); } else - { - _currentPriority = std::min(_currentPriority, infoIt->priority); + { + _currentPriority = qMin(_currentPriority, infoIt->priority); // call emitReq when effect or color is running with timeout > -1, blacklist prio 255 if(infoIt->priority < 254 && infoIt->timeoutTime_ms > -1 && (infoIt->componentId == hyperion::COMP_EFFECT || infoIt->componentId == hyperion::COMP_COLOR)) diff --git a/libsrc/leddevice/LedDeviceAPA102.cpp b/libsrc/leddevice/LedDeviceAPA102.cpp index 5fc34a03..3a114024 100644 --- a/libsrc/leddevice/LedDeviceAPA102.cpp +++ b/libsrc/leddevice/LedDeviceAPA102.cpp @@ -16,7 +16,7 @@ bool LedDeviceAPA102::init(const QJsonObject &deviceConfig) ProviderSpi::init(deviceConfig); const unsigned int startFrameSize = 4; - const unsigned int endFrameSize = std::max(((_ledCount + 15) / 16), 4); + const unsigned int endFrameSize = qMax(((_ledCount + 15) / 16), 4); const unsigned int APAbufferSize = (_ledCount * 4) + startFrameSize + endFrameSize; _ledBuffer.resize(APAbufferSize, 0xFF); diff --git a/libsrc/leddevice/LedDeviceAdalight.cpp b/libsrc/leddevice/LedDeviceAdalight.cpp index ac59652a..ecc5d8c3 100644 --- a/libsrc/leddevice/LedDeviceAdalight.cpp +++ b/libsrc/leddevice/LedDeviceAdalight.cpp @@ -26,7 +26,7 @@ bool LedDeviceAdalight::init(const QJsonObject &deviceConfig) { const unsigned int startFrameSize = 4; const unsigned int bytesPerRGBLed = 4; - const unsigned int endFrameSize = std::max(((_ledCount + 15) / 16), bytesPerRGBLed); + const unsigned int endFrameSize = qMax(((_ledCount + 15) / 16), bytesPerRGBLed); _ledBuffer.resize(_headerSize + (_ledCount * bytesPerRGBLed) + startFrameSize + endFrameSize, 0x00); // init constant data values diff --git a/libsrc/leddevice/LedDeviceDMX.cpp b/libsrc/leddevice/LedDeviceDMX.cpp index fe1c06aa..7b8ba3d4 100644 --- a/libsrc/leddevice/LedDeviceDMX.cpp +++ b/libsrc/leddevice/LedDeviceDMX.cpp @@ -38,7 +38,7 @@ bool LedDeviceDMX::init(const QJsonObject &deviceConfig) Debug(_log, "_dmxString \"%s\", _dmxDeviceType %d", QSTRING_CSTR(dmxString), _dmxDeviceType ); _rs232Port.setStopBits(QSerialPort::TwoStop); - _dmxLedCount = std::min(_ledCount, 512/_dmxSlotsPerLed); + _dmxLedCount = qMin(_ledCount, 512/_dmxSlotsPerLed); _dmxChannelCount = 1 + _dmxSlotsPerLed * _dmxLedCount; Debug(_log, "_dmxStart %d, _dmxSlotsPerLed %d", _dmxStart, _dmxSlotsPerLed); diff --git a/libsrc/leddevice/LedDeviceLightpack-hidapi.cpp b/libsrc/leddevice/LedDeviceLightpack-hidapi.cpp index afe89083..075426b8 100644 --- a/libsrc/leddevice/LedDeviceLightpack-hidapi.cpp +++ b/libsrc/leddevice/LedDeviceLightpack-hidapi.cpp @@ -209,7 +209,7 @@ int LedDeviceLightpack::write(const std::vector &ledValues) int LedDeviceLightpack::write(const ColorRgb * ledValues, int size) { - int count = std::min(_hwLedCount,size); + int count = qMin(_hwLedCount,size); for (int i=0; i &ledValues) int LedDeviceLightpack::write(const ColorRgb * ledValues, int size) { - int count = std::min(_hwLedCount, _ledCount); + int count = qMin(_hwLedCount, _ledCount); for (int i = 0; i < count ; ++i) { diff --git a/libsrc/leddevice/LedDeviceMultiLightpack.cpp b/libsrc/leddevice/LedDeviceMultiLightpack.cpp index 9f1082a1..3c951a9c 100644 --- a/libsrc/leddevice/LedDeviceMultiLightpack.cpp +++ b/libsrc/leddevice/LedDeviceMultiLightpack.cpp @@ -81,7 +81,7 @@ int LedDeviceMultiLightpack::write(const std::vector &ledValues) for (LedDeviceLightpack * device : _lightpacks) { - int count = std::min(device->getLedCount(), size); + int count = qMin(device->getLedCount(), size); if (count > 0) { diff --git a/libsrc/leddevice/LedDeviceUdpArtNet.cpp b/libsrc/leddevice/LedDeviceUdpArtNet.cpp index 8738e972..50f2b168 100644 --- a/libsrc/leddevice/LedDeviceUdpArtNet.cpp +++ b/libsrc/leddevice/LedDeviceUdpArtNet.cpp @@ -79,7 +79,7 @@ The Sequence field is set to 0x00 to disable this feature. if ( (ledIdx == _ledRGBCount-1) || (dmxIdx >= DMX_MAX) ) { prepare(thisUniverse, _artnet_seq, dmxIdx); - retVal &= writeBytes(18 + std::min(dmxIdx, DMX_MAX), artnet_packet.raw); + retVal &= writeBytes(18 + qMin(dmxIdx, DMX_MAX), artnet_packet.raw); memset(artnet_packet.raw, 0, sizeof(artnet_packet.raw)); thisUniverse ++; diff --git a/libsrc/leddevice/schemas/schema-fadecandy.json b/libsrc/leddevice/schemas/schema-fadecandy.json index 880e1b0a..78ef8241 100644 --- a/libsrc/leddevice/schemas/schema-fadecandy.json +++ b/libsrc/leddevice/schemas/schema-fadecandy.json @@ -34,24 +34,44 @@ "type": "boolean", "title":"edt_dev_spec_FCmanualControl_title", "default": false, + "options": { + "dependencies": { + "setFcConfig": true + } + }, "propertyOrder" : 5 }, "ledOn": { "type": "boolean", "title":"edt_dev_spec_FCledToOn_title", "default": false, + "options": { + "dependencies": { + "setFcConfig": true + } + }, "propertyOrder" : 6 }, "interpolation": { "type": "boolean", "title":"edt_dev_spec_interpolation_title", "default": false, + "options": { + "dependencies": { + "setFcConfig": true + } + }, "propertyOrder" : 7 }, "dither": { "type": "boolean", "title":"edt_dev_spec_dithering_title", "default": false, + "options": { + "dependencies": { + "setFcConfig": true + } + }, "propertyOrder" : 8 }, "gamma" : { @@ -59,11 +79,21 @@ "title" : "edt_dev_spec_gamma_title", "minimum" : 0.1, "maximum": 5.0, + "options": { + "dependencies": { + "setFcConfig": true + } + }, "propertyOrder" : 9 }, "whitepoint" : { "type" : "array", "title" : "edt_dev_spec_whitepoint_title", + "options": { + "dependencies": { + "setFcConfig": true + } + }, "propertyOrder" : 10, "default" : [255,255,255], "maxItems" : 3, diff --git a/libsrc/udplistener/UDPListener.cpp b/libsrc/udplistener/UDPListener.cpp index 9ebc146f..cb53958c 100644 --- a/libsrc/udplistener/UDPListener.cpp +++ b/libsrc/udplistener/UDPListener.cpp @@ -1,6 +1,3 @@ -// system includes -#include - // project includes #include @@ -123,7 +120,7 @@ void UDPListener::processTheDatagram(const QByteArray * datagram, const QHostAdd std::vector _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb::BLACK); - for (int ledIndex=0; ledIndex < std::min(packetLedCount, hyperionLedCount); ledIndex++) { + for (int ledIndex=0; ledIndex < qMin(packetLedCount, hyperionLedCount); ledIndex++) { ColorRgb & rgb = _ledColors[ledIndex]; rgb.red = datagram->at(ledIndex*3+0); rgb.green = datagram->at(ledIndex*3+1); diff --git a/libsrc/utils/RgbChannelAdjustment.cpp b/libsrc/utils/RgbChannelAdjustment.cpp index 2a317a8b..dc763ff8 100644 --- a/libsrc/utils/RgbChannelAdjustment.cpp +++ b/libsrc/utils/RgbChannelAdjustment.cpp @@ -1,9 +1,3 @@ -// STL includes -#include -#include -#include - -// Utils includes #include RgbChannelAdjustment::RgbChannelAdjustment(QString channelName) @@ -64,9 +58,9 @@ void RgbChannelAdjustment::apply(uint8_t input, uint8_t brightness, uint8_t & re if (!_initialized[input]) { - _mapping[RED ][input] = std::min( ((_brightness * input * _adjust[RED ]) / 65025), UINT8_MAX); - _mapping[GREEN][input] = std::min( ((_brightness * input * _adjust[GREEN]) / 65025), UINT8_MAX); - _mapping[BLUE ][input] = std::min( ((_brightness * input * _adjust[BLUE ]) / 65025), UINT8_MAX); + _mapping[RED ][input] = qMin( ((_brightness * input * _adjust[RED ]) / 65025), UINT8_MAX); + _mapping[GREEN][input] = qMin( ((_brightness * input * _adjust[GREEN]) / 65025), UINT8_MAX); + _mapping[BLUE ][input] = qMin( ((_brightness * input * _adjust[BLUE ]) / 65025), UINT8_MAX); _initialized[input] = true; } red = _mapping[RED ][input]; diff --git a/libsrc/utils/RgbToRgbw.cpp b/libsrc/utils/RgbToRgbw.cpp index 11aaa585..7e5005c1 100755 --- a/libsrc/utils/RgbToRgbw.cpp +++ b/libsrc/utils/RgbToRgbw.cpp @@ -19,7 +19,7 @@ void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, const WhiteAlgorithm algori { case SUBTRACT_MINIMUM: { - output->white = std::min(std::min(input.red, input.green), input.blue); + output->white = qMin(qMin(input.red, input.green), input.blue); output->red = input.red - output->white; output->green = input.green - output->white; output->blue = input.blue - output->white; diff --git a/libsrc/utils/RgbTransform.cpp b/libsrc/utils/RgbTransform.cpp index d99cc687..2b3fd730 100644 --- a/libsrc/utils/RgbTransform.cpp +++ b/libsrc/utils/RgbTransform.cpp @@ -1,6 +1,4 @@ -#include -#include - +#include #include RgbTransform::RgbTransform() @@ -55,9 +53,9 @@ void RgbTransform::initializeMapping() { for (int i = 0; i < 256; ++i) { - _mappingR[i] = std::min(std::max((int)(std::pow(i / 255.0, _gammaR) * 255), 0), 255); - _mappingG[i] = std::min(std::max((int)(std::pow(i / 255.0, _gammaG) * 255), 0), 255); - _mappingB[i] = std::min(std::max((int)(std::pow(i / 255.0, _gammaB) * 255), 0), 255); + _mappingR[i] = qMin(qMax((int)(qPow(i / 255.0, _gammaR) * 255), 0), 255); + _mappingG[i] = qMin(qMax((int)(qPow(i / 255.0, _gammaG) * 255), 0), 255); + _mappingB[i] = qMin(qMax((int)(qPow(i / 255.0, _gammaB) * 255), 0), 255); } } @@ -70,7 +68,7 @@ int RgbTransform::getBacklightThreshold() const void RgbTransform::setBacklightThreshold(int backlightThreshold) { _backlightThreshold = backlightThreshold; - _sumBrightnessLow = 765.0 * ((std::pow(2.0,(_backlightThreshold/100)*2)-1) / 3.0); + _sumBrightnessLow = 765.0 * ((qPow(2.0,(_backlightThreshold/100)*2)-1) / 3.0); } bool RgbTransform::getBacklightColored() const @@ -129,9 +127,9 @@ void RgbTransform::updateBrightnessComponents() { B_in = (_brightness<50)? -0.09*_brightness+7.5 : -0.04*_brightness+5.0; - _brightness_rgb = std::ceil(std::min(255.0,255.0/B_in)); - _brightness_cmy = std::ceil(std::min(255.0,255.0/(B_in*Fcmy))); - _brightness_w = std::ceil(std::min(255.0,255.0/(B_in*Fw))); + _brightness_rgb = std::ceil(qMin(255.0,255.0/B_in)); + _brightness_cmy = std::ceil(qMin(255.0,255.0/(B_in*Fcmy))); + _brightness_w = std::ceil(qMin(255.0,255.0/(B_in*Fw))); } } @@ -149,7 +147,6 @@ void RgbTransform::transform(uint8_t & red, uint8_t & green, uint8_t & blue) green = _mappingR[green]; blue = _mappingR[blue]; - //std::cout << (int)red << " " << (int)green << " " << (int)blue << " => "; // apply brightnesss int rgbSum = red+green+blue; @@ -164,7 +161,7 @@ void RgbTransform::transform(uint8_t & red, uint8_t & green, uint8_t & blue) if (blue ==0) blue = 1; rgbSum = red+green+blue; } - double cL =std::min((int)(_sumBrightnessLow /rgbSum), 255); + double cL =qMin((int)(_sumBrightnessLow /rgbSum), 255); red *= cL; green *= cL; @@ -172,11 +169,10 @@ void RgbTransform::transform(uint8_t & red, uint8_t & green, uint8_t & blue) } else { - red = std::min((int)(_sumBrightnessLow/3.0), 255); + red = qMin((int)(_sumBrightnessLow/3.0), 255); green = red; blue = red; } } - //std::cout << _sumBrightnessLow << " " << (int)red << " " << (int)green << " " << (int)blue << std::endl; } diff --git a/src/hyperiond/systray.cpp b/src/hyperiond/systray.cpp index c307cc7c..afde8277 100644 --- a/src/hyperiond/systray.cpp +++ b/src/hyperiond/systray.cpp @@ -32,7 +32,6 @@ SysTray::SysTray(HyperionDaemon *hyperiond, quint16 webPort) _trayIcon->setIcon(icon); _trayIcon->show(); setWindowIcon(icon); - _colorDlg.setModal(true); _colorDlg.setOptions(QColorDialog::NoButtons); } @@ -58,21 +57,31 @@ void SysTray::iconActivated(QSystemTrayIcon::ActivationReason reason) void SysTray::createTrayIcon() { quitAction = new QAction(tr("&Quit"), this); + QIcon quitIcon = QIcon::fromTheme("application-exit"); + quitAction->setIcon(quitIcon); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); colorAction = new QAction(tr("&Color"), this); + QIcon colorIcon = QIcon::fromTheme("applications-graphics"); + colorAction->setIcon(colorIcon); connect(colorAction, SIGNAL(triggered()), this, SLOT(showColorDialog())); settingsAction = new QAction(tr("&Settings"), this); + QIcon settingsIcon = QIcon::fromTheme("preferences-system"); + settingsAction->setIcon(settingsIcon); connect(settingsAction, SIGNAL(triggered()), this, SLOT(settings())); clearAction = new QAction(tr("&Clear"), this); + QIcon clearIcon = QIcon::fromTheme("edit-delete"); + clearAction->setIcon(clearIcon); connect(clearAction, SIGNAL(triggered()), this, SLOT(clearEfxColor())); const std::list efxs = _hyperion->getEffects(); _trayIconMenu = new QMenu(this); _trayIconEfxMenu = new QMenu(_trayIconMenu); _trayIconEfxMenu->setTitle(tr("Effects")); + QIcon efxIcon = QIcon::fromTheme("media-playback-start"); + _trayIconEfxMenu->setIcon(efxIcon); for (auto efx : efxs) { QAction *efxAction = new QAction(efx.name, this);