Merge branch 'master' into Nanoleaf

This commit is contained in:
LordGrey 2023-10-02 18:00:45 +02:00 committed by GitHub
commit 8f9d94e390
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 173 additions and 125 deletions

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1.0) cmake_minimum_required(VERSION 3.5.0)
message( STATUS "CMake Version: ${CMAKE_VERSION}" ) message( STATUS "CMake Version: ${CMAKE_VERSION}" )
@ -38,26 +38,24 @@ if ( CCACHE_FOUND )
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND) endif(CCACHE_FOUND)
# enable C++14; MSVC doesn't have c++14 feature switch # enable C++17
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC") if(APPLE)
if(APPLE) include(CheckCXXCompilerFlag)
include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("Werror=unguarded-availability" REQUIRED_UNGUARDED_AVAILABILITY)
CHECK_CXX_COMPILER_FLAG("Werror=unguarded-availability" REQUIRED_UNGUARDED_AVAILABILITY) if(REQUIRED_UNGUARDED_AVAILABILITY)
if(REQUIRED_UNGUARDED_AVAILABILITY) list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "Werror=unguarded-availability")
list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "Werror=unguarded-availability")
endif()
endif() endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-psabi")
endif()
set(CMAKE_CXX_STANDARD 14)
set(CXX_STANDARD_REQUIRED ON)
set(CXX_EXTENSIONS OFF)
endif() endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-psabi")
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Set build variables # Set build variables
# Grabber # Grabber
SET ( DEFAULT_AMLOGIC OFF ) SET ( DEFAULT_AMLOGIC OFF )

View File

@ -327,7 +327,7 @@ $(document).ready(function () {
var saveOptions = conf_editor_screen.getValue(); var saveOptions = conf_editor_screen.getValue();
var instCaptOptions = window.serverConfig.instCapture; var instCaptOptions = window.serverConfig.instCapture;
instCaptOptions.systemEnable = true; instCaptOptions.systemEnable = saveOptions.framegrabber.enable;
saveOptions.instCapture = instCaptOptions; saveOptions.instCapture = instCaptOptions;
requestWriteConfig(saveOptions); requestWriteConfig(saveOptions);
@ -679,7 +679,7 @@ $(document).ready(function () {
var saveOptions = conf_editor_video.getValue(); var saveOptions = conf_editor_video.getValue();
var instCaptOptions = window.serverConfig.instCapture; var instCaptOptions = window.serverConfig.instCapture;
instCaptOptions.v4lEnable = true; instCaptOptions.v4lEnable = saveOptions.grabberV4L2.enable;
saveOptions.instCapture = instCaptOptions; saveOptions.instCapture = instCaptOptions;
requestWriteConfig(saveOptions); requestWriteConfig(saveOptions);
@ -805,7 +805,7 @@ $(document).ready(function () {
const saveOptions = conf_editor_audio.getValue(); const saveOptions = conf_editor_audio.getValue();
const instCaptOptions = window.serverConfig.instCapture; const instCaptOptions = window.serverConfig.instCapture;
instCaptOptions.audioEnable = true; instCaptOptions.audioEnable = saveOptions.grabberAudio.enable;
saveOptions.instCapture = instCaptOptions; saveOptions.instCapture = instCaptOptions;
requestWriteConfig(saveOptions); requestWriteConfig(saveOptions);

View File

@ -93,7 +93,7 @@ else
fi fi
# Determine if PR number exists # Determine if PR number exists
pulls=$(request_call "$api_url/pulls") pulls=$(request_call "$api_url/pulls?state=open")
pr_exists=$(echo "$pulls" | tr '\r\n' ' ' | ${pythonCmd} -c """ pr_exists=$(echo "$pulls" | tr '\r\n' ' ' | ${pythonCmd} -c """
import json,sys import json,sys
@ -106,7 +106,7 @@ for i in data:
""" 2>/dev/null) """ 2>/dev/null)
if [ "$pr_exists" != "exists" ]; then if [ "$pr_exists" != "exists" ]; then
echo "---> Pull Request $pr_number not found -> abort" echo "---> Pull Request $pr_number not found as open PR -> abort"
exit 1 exit 1
fi fi
@ -122,7 +122,7 @@ for i in data:
""" 2>/dev/null) """ 2>/dev/null)
if [ -z "$head_sha" ]; then if [ -z "$head_sha" ]; then
echo "---> The specified PR #$pr_number has no longer any artifacts." echo "---> The specified PR #$pr_number has no longer any artifacts or has been closed."
echo "---> It may be older than 14 days. Ask the PR creator to recreate the artifacts at the following URL:" echo "---> It may be older than 14 days. Ask the PR creator to recreate the artifacts at the following URL:"
echo "---> https://github.com/hyperion-project/hyperion.ng/pull/$pr_number" echo "---> https://github.com/hyperion-project/hyperion.ng/pull/$pr_number"
exit 1 exit 1
@ -130,13 +130,13 @@ fi
if [ -z "$run_id" ]; then if [ -z "$run_id" ]; then
# Determine run_id from head_sha # Determine run_id from head_sha
runs=$(request_call "$api_url/actions/runs") runs=$(request_call "$api_url/actions/runs?head_sha=$head_sha")
run_id=$(echo "$runs" | tr '\r\n' ' ' | ${pythonCmd} -c """ run_id=$(echo "$runs" | tr '\r\n' ' ' | ${pythonCmd} -c """
import json,sys import json,sys
data = json.load(sys.stdin) data = json.load(sys.stdin)
for i in data['workflow_runs']: for i in data['workflow_runs']:
if i['head_sha'] == '"$head_sha"': if i['name'] == 'Hyperion PR Build':
print(i['id']) print(i['id'])
break break
""" 2>/dev/null) """ 2>/dev/null)

View File

@ -48,7 +48,7 @@ macro(DeployMacOS TARGET)
foreach(PLUGIN "platforms" "sqldrivers" "imageformats") foreach(PLUGIN "platforms" "sqldrivers" "imageformats")
if(EXISTS ${PLUGIN_DIR}/${PLUGIN}) if(EXISTS ${PLUGIN_DIR}/${PLUGIN})
file(GLOB files "${PLUGIN_DIR}/${PLUGIN}/*") file(GLOB files "${PLUGIN_DIR}/${PLUGIN}/*")
list(FILTER files EXCLUDE REGEX ".*libqwebp\\.dylib$") list(FILTER files EXCLUDE REGEX ".*libqwebp\\.dylib$")
foreach(file ${files}) foreach(file ${files})
file(GET_RUNTIME_DEPENDENCIES file(GET_RUNTIME_DEPENDENCIES
EXECUTABLES ${file} EXECUTABLES ${file}

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.2) cmake_minimum_required(VERSION 3.5)
project(qmdnsengine) project(qmdnsengine)

View File

@ -133,6 +133,9 @@ endif()
if(ENABLE_PROTOBUF_SERVER) if(ENABLE_PROTOBUF_SERVER)
set(USE_SYSTEM_PROTO_LIBS ${DEFAULT_USE_SYSTEM_PROTO_LIBS} CACHE BOOL "use protobuf library from system") set(USE_SYSTEM_PROTO_LIBS ${DEFAULT_USE_SYSTEM_PROTO_LIBS} CACHE BOOL "use protobuf library from system")
# defines for 3rd party sub-modules
set(ABSL_PROPAGATE_CXX_STD ON CACHE BOOL "Build abseil-cpp with C++ version requirements propagated")
if (USE_SYSTEM_PROTO_LIBS) if (USE_SYSTEM_PROTO_LIBS)
find_package(Protobuf REQUIRED) find_package(Protobuf REQUIRED)
@ -161,9 +164,6 @@ if(ENABLE_PROTOBUF_SERVER)
# define the protobuf library # define the protobuf library
set(PROTOBUF_LIBRARIES protobuf::libprotobuf) set(PROTOBUF_LIBRARIES protobuf::libprotobuf)
# defines for 3rd party sub-modules
set(ABSL_PROPAGATE_CXX_STD ON CACHE BOOL "Build abseil-cpp with C++ version requirements propagated")
endif() endif()
# redefine at parent scope # redefine at parent scope
@ -270,7 +270,7 @@ if(ENABLE_DEV_NETWORK)
set(USE_SYSTEM_MBEDTLS_LIBS OFF) set(USE_SYSTEM_MBEDTLS_LIBS OFF)
endif (NOT MBEDTLS_FOUND) endif (NOT MBEDTLS_FOUND)
else() else()
cmake_minimum_required(VERSION 3.2) cmake_minimum_required(VERSION 3.5.1)
set(CMAKE_POLICY_DEFAULT_CMP0071 NEW) set(CMAKE_POLICY_DEFAULT_CMP0071 NEW)

View File

@ -88,6 +88,11 @@ private slots:
/// ///
void handleInstanceStateChange(InstanceState state, quint8 instance, const QString &name = QString()); void handleInstanceStateChange(InstanceState state, quint8 instance, const QString &name = QString());
///
/// @brief Stream a new LED Colors update
///
void streamLedColorsUpdate();
signals: signals:
/// ///
/// Signal emits with the reply message provided with handleMessage() /// Signal emits with the reply message provided with handleMessage()

View File

@ -39,8 +39,8 @@ class AudioGrabberWindows : public AudioGrabber
HANDLE notificationEvent; HANDLE notificationEvent;
std::atomic<bool> isRunning{ false }; std::atomic<bool> isRunning{ false };
static BOOL CALLBACK DirectSoundEnumProcessor(LPGUID deviceIdGuid, LPCTSTR deviceDescStr, static BOOL CALLBACK DirectSoundEnumProcessor(LPGUID deviceIdGuid, LPCWSTR deviceDescStr,
LPCTSTR deviceModelStr, LPVOID context) LPCWSTR deviceModelStr, LPVOID context)
{ {
// Skip undefined audio devices // Skip undefined audio devices
if (deviceIdGuid == NULL) if (deviceIdGuid == NULL)
@ -50,12 +50,15 @@ static BOOL CALLBACK DirectSoundEnumProcessor(LPGUID deviceIdGuid, LPCTSTR devic
AudioGrabber::DeviceProperties device; AudioGrabber::DeviceProperties device;
// Process Device Information
QString deviceName = QString::fromWCharArray(deviceDescStr);
// Process Device ID // Process Device ID
LPOLESTR deviceIdStr; LPOLESTR deviceIdStr;
HRESULT res = StringFromCLSID(*deviceIdGuid, &deviceIdStr); HRESULT res = StringFromCLSID(*deviceIdGuid, &deviceIdStr);
if (FAILED(res)) if (FAILED(res))
{ {
Error(Logger::getInstance("AUDIOGRABBER"), "Failed to get CLSID-string for %s with error: 0x%08x: %s", deviceDescStr, res, std::system_category().message(res).c_str()); Error(Logger::getInstance("AUDIOGRABBER"), "Failed to get CLSID-string for %s with error: 0x%08x: %s", QSTRING_CSTR(deviceName), res, std::system_category().message(res).c_str());
return FALSE; return FALSE;
} }
@ -63,10 +66,7 @@ static BOOL CALLBACK DirectSoundEnumProcessor(LPGUID deviceIdGuid, LPCTSTR devic
CoTaskMemFree(deviceIdStr); CoTaskMemFree(deviceIdStr);
// Process Device Information Debug(Logger::getInstance("AUDIOGRABBER"), "Found Audio Device: %s", QSTRING_CSTR(deviceName));
QString deviceName = QString::fromLocal8Bit(deviceDescStr);
Debug(Logger::getInstance("AUDIOGRABBER"), "Found Audio Device: %s", deviceDescStr);
device.id = deviceId; device.id = deviceId;
device.name = deviceName; device.name = deviceName;

View File

@ -413,9 +413,13 @@ namespace hyperion
} }
// Compute the average of each color channel // Compute the average of each color channel
const uint8_t avgRed = uint8_t(std::min(std::lround(sqrt(static_cast<double>(cummRed/pixelNum))), 255L));
const uint8_t avgGreen = uint8_t(std::min(std::lround(sqrt(static_cast<double>(cummGreen/pixelNum))), 255L)); #ifdef WIN32
const uint8_t avgBlue = uint8_t(std::min(std::lround(sqrt(static_cast<double>(cummBlue/pixelNum))), 255L)); #undef min
#endif
const uint8_t avgRed = static_cast<uint8_t>(std::min(std::lround(std::sqrt(static_cast<double>(cummRed / pixelNum))), 255L));
const uint8_t avgGreen = static_cast<uint8_t>(std::min(std::lround(sqrt(static_cast<double>(cummGreen / pixelNum))), 255L));
const uint8_t avgBlue = static_cast<uint8_t>(std::min(std::lround(sqrt(static_cast<double>(cummBlue / pixelNum))), 255L));
// Return the computed color // Return the computed color
return {avgRed, avgGreen, avgBlue}; return {avgRed, avgGreen, avgBlue};

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#define QSTRING_CSTR(str) str.toLocal8Bit().constData() #define QSTRING_CSTR(str) str.toUtf8().constData()
typedef QList< int > QIntList; typedef QList< int > QIntList;

View File

@ -140,6 +140,8 @@ void JsonAPI::initialize()
connect(this, &JsonAPI::toggleSuspendAll, _instanceManager, &HyperionIManager::triggerToggleSuspend); connect(this, &JsonAPI::toggleSuspendAll, _instanceManager, &HyperionIManager::triggerToggleSuspend);
connect(this, &JsonAPI::idleAll, _instanceManager, &HyperionIManager::triggerIdle); connect(this, &JsonAPI::idleAll, _instanceManager, &HyperionIManager::triggerIdle);
connect(this, &JsonAPI::toggleIdleAll, _instanceManager, &HyperionIManager::triggerToggleIdle); connect(this, &JsonAPI::toggleIdleAll, _instanceManager, &HyperionIManager::triggerToggleIdle);
connect(_ledStreamTimer, &QTimer::timeout, this, &JsonAPI::streamLedColorsUpdate, Qt::UniqueConnection);
} }
bool JsonAPI::handleInstanceSwitch(quint8 inst, bool forced) bool JsonAPI::handleInstanceSwitch(quint8 inst, bool forced)
@ -404,7 +406,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString
activePriorities.removeAll(PriorityMuxer::LOWEST_PRIORITY); activePriorities.removeAll(PriorityMuxer::LOWEST_PRIORITY);
int currentPriority = _hyperion->getCurrentPriority(); int currentPriority = _hyperion->getCurrentPriority();
for(int priority : qAsConst(activePriorities)) for(int priority : std::as_const(activePriorities))
{ {
const Hyperion::InputInfo &priorityInfo = _hyperion->getPriorityInfo(priority); const Hyperion::InputInfo &priorityInfo = _hyperion->getPriorityInfo(priority);
@ -1139,6 +1141,11 @@ void JsonAPI::handleComponentStateCommand(const QJsonObject &message, const QStr
sendSuccessReply(command, tan); sendSuccessReply(command, tan);
} }
void JsonAPI::streamLedColorsUpdate()
{
emit streamLedcolorsUpdate(_currentLedValues);
}
void JsonAPI::handleLedColorsCommand(const QJsonObject &message, const QString &command, int tan) void JsonAPI::handleLedColorsCommand(const QJsonObject &message, const QString &command, int tan)
{ {
// create result // create result
@ -1154,21 +1161,21 @@ void JsonAPI::handleLedColorsCommand(const QJsonObject &message, const QString &
_streaming_leds_reply["tan"] = tan; _streaming_leds_reply["tan"] = tan;
connect(_hyperion, &Hyperion::rawLedColors, this, [=](const std::vector<ColorRgb> &ledValues) { connect(_hyperion, &Hyperion::rawLedColors, this, [=](const std::vector<ColorRgb> &ledValues) {
_currentLedValues = ledValues;
// necessary because Qt::UniqueConnection for lambdas does not work until 5.9 if (ledValues != _currentLedValues)
// see: https://bugreports.qt.io/browse/QTBUG-52438 {
if (!_ledStreamConnection) _currentLedValues = ledValues;
_ledStreamConnection = connect(_ledStreamTimer, &QTimer::timeout, this, [=]() { if (!_ledStreamTimer->isActive() || _ledStreamTimer->interval() != streaming_interval)
emit streamLedcolorsUpdate(_currentLedValues); {
}, _ledStreamTimer->start(streaming_interval);
Qt::UniqueConnection); }
}
else
{
_ledStreamTimer->stop();
}
});
// start the timer
if (!_ledStreamTimer->isActive() || _ledStreamTimer->interval() != streaming_interval)
_ledStreamTimer->start(streaming_interval);
},
Qt::UniqueConnection);
// push once // push once
_hyperion->update(); _hyperion->update();
} }
@ -1387,7 +1394,7 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject &message, const QString &
if (API::getPendingTokenRequests(vec)) if (API::getPendingTokenRequests(vec))
{ {
QJsonArray arr; QJsonArray arr;
for (const auto &entry : qAsConst(vec)) for (const auto &entry : std::as_const(vec))
{ {
QJsonObject obj; QJsonObject obj;
obj["comment"] = entry.comment; obj["comment"] = entry.comment;

View File

@ -199,7 +199,7 @@ void JsonCB::handlePriorityUpdate(int currentPriority, const PriorityMuxer::Inpu
activePriorities.removeAll(PriorityMuxer::LOWEST_PRIORITY); activePriorities.removeAll(PriorityMuxer::LOWEST_PRIORITY);
for (int priority : qAsConst(activePriorities)) { for (int priority : std::as_const(activePriorities)) {
const Hyperion::InputInfo& priorityInfo = activeInputs[priority]; const Hyperion::InputInfo& priorityInfo = activeInputs[priority];

View File

@ -7,6 +7,7 @@
#include <QThreadStorage> #include <QThreadStorage>
#include <QUuid> #include <QUuid>
#include <QDir> #include <QDir>
#include <QMetaType>
#ifdef _WIN32 #ifdef _WIN32
#include <stdexcept> #include <stdexcept>
@ -425,15 +426,15 @@ void DBManager::doAddBindValue(QSqlQuery& query, const QVariantList& variants) c
auto t = variant.userType(); auto t = variant.userType();
switch(t) switch(t)
{ {
case QVariant::UInt: case QMetaType::UInt:
case QVariant::Int: case QMetaType::Int:
case QVariant::Bool: case QMetaType::Bool:
query.addBindValue(variant.toInt()); query.addBindValue(variant.toInt());
break; break;
case QVariant::Double: case QMetaType::Double:
query.addBindValue(variant.toFloat()); query.addBindValue(variant.toFloat());
break; break;
case QVariant::ByteArray: case QMetaType::QByteArray:
query.addBindValue(variant.toByteArray()); query.addBindValue(variant.toByteArray());
break; break;
default: default:

View File

@ -224,7 +224,7 @@ void EffectFileHandler::updateEffects()
} }
QMap<QString, EffectDefinition> availableEffects; QMap<QString, EffectDefinition> availableEffects;
for (const QString& path : qAsConst(efxPathList)) for (const QString& path : std::as_const(efxPathList))
{ {
QDir directory(path); QDir directory(path);
if (!directory.exists()) if (!directory.exists())
@ -241,8 +241,8 @@ void EffectFileHandler::updateEffects()
else else
{ {
int efxCount = 0; int efxCount = 0;
QStringList filenames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase); const QStringList filenames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase);
for (const QString& filename : qAsConst(filenames)) for (const QString& filename : filenames)
{ {
EffectDefinition def; EffectDefinition def;
if (loadEffectDefinition(path, filename, def)) if (loadEffectDefinition(path, filename, def))
@ -268,8 +268,8 @@ void EffectFileHandler::updateEffects()
QString schemaPath = path + "schema" + '/'; QString schemaPath = path + "schema" + '/';
directory.setPath(schemaPath); directory.setPath(schemaPath);
QStringList schemaFileNames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase); const QStringList schemaFileNames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase);
for (const QString& schemaFileName : qAsConst(schemaFileNames)) for (const QString& schemaFileName : schemaFileNames)
{ {
EffectSchema pyEffect; EffectSchema pyEffect;
if (loadEffectSchema(path, directory.filePath(schemaFileName), pyEffect)) if (loadEffectSchema(path, directory.filePath(schemaFileName), pyEffect))
@ -282,7 +282,7 @@ void EffectFileHandler::updateEffects()
} }
} }
for (const auto& item : qAsConst(availableEffects)) for (const auto& item : std::as_const(availableEffects))
{ {
_availableEffects.push_back(item); _availableEffects.push_back(item);
} }

View File

@ -269,7 +269,7 @@ int MessageForwarder::startJsonTargets(const QJsonObject& config)
if (!_jsonTargets.isEmpty()) if (!_jsonTargets.isEmpty())
{ {
for (const auto& targetHost : qAsConst(_jsonTargets)) for (const auto& targetHost : std::as_const(_jsonTargets))
{ {
Info(_log, "Forwarding now to JSON-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port); Info(_log, "Forwarding now to JSON-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port);
} }
@ -286,7 +286,7 @@ void MessageForwarder::stopJsonTargets()
if (!_jsonTargets.isEmpty()) if (!_jsonTargets.isEmpty())
{ {
disconnect(_hyperion, &Hyperion::forwardJsonMessage, nullptr, nullptr); disconnect(_hyperion, &Hyperion::forwardJsonMessage, nullptr, nullptr);
for (const auto& targetHost : qAsConst(_jsonTargets)) for (const auto& targetHost : std::as_const(_jsonTargets))
{ {
Info(_log, "Stopped forwarding to JSON-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port); Info(_log, "Stopped forwarding to JSON-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port);
} }
@ -373,7 +373,7 @@ int MessageForwarder::startFlatbufferTargets(const QJsonObject& config)
if (!_flatbufferTargets.isEmpty()) if (!_flatbufferTargets.isEmpty())
{ {
for (const auto& targetHost : qAsConst(_flatbufferTargets)) for (const auto& targetHost : std::as_const(_flatbufferTargets))
{ {
Info(_log, "Forwarding now to Flatbuffer-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port); Info(_log, "Forwarding now to Flatbuffer-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port);
} }
@ -399,7 +399,7 @@ void MessageForwarder::stopFlatbufferTargets()
_messageForwarderFlatBufHelper = nullptr; _messageForwarderFlatBufHelper = nullptr;
} }
for (const auto& targetHost : qAsConst(_flatbufferTargets)) for (const auto& targetHost : std::as_const(_flatbufferTargets))
{ {
Info(_log, "Stopped forwarding to Flatbuffer-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port); Info(_log, "Stopped forwarding to Flatbuffer-target host: %s port: %u", QSTRING_CSTR(targetHost.host.toString()), targetHost.port);
} }
@ -412,7 +412,7 @@ void MessageForwarder::forwardJsonMessage(const QJsonObject& message)
if (_forwarder_enabled) if (_forwarder_enabled)
{ {
QTcpSocket client; QTcpSocket client;
for (const auto& targetHost : qAsConst(_jsonTargets)) for (const auto& targetHost : std::as_const(_jsonTargets))
{ {
client.connectToHost(targetHost.host, targetHost.port); client.connectToHost(targetHost.host, targetHost.port);
if (client.waitForConnected(CONNECT_TIMEOUT.count())) if (client.waitForConnected(CONNECT_TIMEOUT.count()))

View File

@ -9,6 +9,15 @@
// Constants // Constants
namespace { namespace {
const uint16_t RESOLUTION = 255; const uint16_t RESOLUTION = 255;
//Constants vuMeter
const QJsonArray DEFAULT_HOTCOLOR { 255,0,0 };
const QJsonArray DEFAULT_WARNCOLOR { 255,255,0 };
const QJsonArray DEFAULT_SAFECOLOR { 0,255,0 };
const int DEFAULT_WARNVALUE { 80 };
const int DEFAULT_SAFEVALUE { 45 };
const int DEFAULT_MULTIPLIER { 0 };
const int DEFAULT_TOLERANCE { 20 };
} }
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
@ -28,12 +37,12 @@ AudioGrabber::AudioGrabber()
, _deviceProperties() , _deviceProperties()
, _device("none") , _device("none")
, _hotColor(QColorConstants::Red) , _hotColor(QColorConstants::Red)
, _warnValue(80) , _warnValue(DEFAULT_WARNVALUE)
, _warnColor(QColorConstants::Yellow) , _warnColor(QColorConstants::Yellow)
, _safeValue(45) , _safeValue(DEFAULT_SAFEVALUE)
, _safeColor(QColorConstants::Green) , _safeColor(QColorConstants::Green)
, _multiplier(0) , _multiplier(DEFAULT_MULTIPLIER)
, _tolerance(20) , _tolerance(DEFAULT_TOLERANCE)
, _dynamicMultiplier(INT16_MAX) , _dynamicMultiplier(INT16_MAX)
, _started(false) , _started(false)
{ {
@ -61,18 +70,27 @@ void AudioGrabber::setDevice(const QString& device)
void AudioGrabber::setConfiguration(const QJsonObject& config) void AudioGrabber::setConfiguration(const QJsonObject& config)
{ {
QJsonArray hotColorArray = config["hotColor"].toArray(QJsonArray::fromVariantList(QList<QVariant>({ QVariant(255), QVariant(0), QVariant(0) }))); QString audioEffect = config["audioEffect"].toString();
QJsonArray warnColorArray = config["warnColor"].toArray(QJsonArray::fromVariantList(QList<QVariant>({ QVariant(255), QVariant(255), QVariant(0) }))); QJsonObject audioEffectConfig = config[audioEffect].toObject();
QJsonArray safeColorArray = config["safeColor"].toArray(QJsonArray::fromVariantList(QList<QVariant>({ QVariant(0), QVariant(255), QVariant(0) })));
_hotColor = QColor(hotColorArray.at(0).toInt(), hotColorArray.at(1).toInt(), hotColorArray.at(2).toInt()); if (audioEffect == "vuMeter")
_warnColor = QColor(warnColorArray.at(0).toInt(), warnColorArray.at(1).toInt(), warnColorArray.at(2).toInt()); {
_safeColor = QColor(safeColorArray.at(0).toInt(), safeColorArray.at(1).toInt(), safeColorArray.at(2).toInt()); QJsonArray hotColorArray = audioEffectConfig.value("hotColor").toArray(DEFAULT_HOTCOLOR);
QJsonArray warnColorArray = audioEffectConfig.value("warnColor").toArray(DEFAULT_WARNCOLOR);
QJsonArray safeColorArray = audioEffectConfig.value("safeColor").toArray(DEFAULT_SAFECOLOR);
_warnValue = config["warnValue"].toInt(80); _hotColor = QColor(hotColorArray.at(0).toInt(), hotColorArray.at(1).toInt(), hotColorArray.at(2).toInt());
_safeValue = config["safeValue"].toInt(45); _warnColor = QColor(warnColorArray.at(0).toInt(), warnColorArray.at(1).toInt(), warnColorArray.at(2).toInt());
_multiplier = config["multiplier"].toDouble(0); _safeColor = QColor(safeColorArray.at(0).toInt(), safeColorArray.at(1).toInt(), safeColorArray.at(2).toInt());
_tolerance = config["tolerance"].toInt(20); _warnValue = audioEffectConfig["warnValue"].toInt(DEFAULT_WARNVALUE);
_safeValue = audioEffectConfig["safeValue"].toInt(DEFAULT_SAFEVALUE);
_multiplier = audioEffectConfig["multiplier"].toDouble(DEFAULT_MULTIPLIER);
_tolerance = audioEffectConfig["tolerance"].toInt(DEFAULT_MULTIPLIER);
}
else
{
Error(_log, "Unknow Audio-Effect: \"%s\" configured", QSTRING_CSTR(audioEffect));
}
} }
void AudioGrabber::resetMultiplier() void AudioGrabber::resetMultiplier()

View File

@ -1,4 +1,7 @@
#include <grabber/AudioGrabberWindows.h> #include <grabber/AudioGrabberWindows.h>
#include <climits>
#include <QImage> #include <QImage>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray> #include <QJsonArray>
@ -61,7 +64,10 @@ bool AudioGrabberWindows::configureCaptureInterface()
// wFormatTag, nChannels, nSamplesPerSec, mAvgBytesPerSec, // wFormatTag, nChannels, nSamplesPerSec, mAvgBytesPerSec,
// nBlockAlign, wBitsPerSample, cbSize // nBlockAlign, wBitsPerSample, cbSize
notificationSize = max(1024, audioFormat.nAvgBytesPerSec / 8); #ifdef WIN32
#undef max
#endif
notificationSize = std::max(static_cast<DWORD>(1024), static_cast<DWORD>(audioFormat.nAvgBytesPerSec / 8));
notificationSize -= notificationSize % audioFormat.nBlockAlign; notificationSize -= notificationSize % audioFormat.nBlockAlign;
bufferCaptureSize = notificationSize * AUDIO_NOTIFICATION_COUNT; bufferCaptureSize = notificationSize * AUDIO_NOTIFICATION_COUNT;

View File

@ -2,8 +2,8 @@
SET( CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber ) SET( CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber )
SET( CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/audio ) SET( CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/audio )
if (WIN32) if (WIN32)
add_definitions(-DUNICODE -D_UNICODE)
FILE ( GLOB AUDIO_GRABBER_SOURCES "${CURRENT_HEADER_DIR}/Audio*Windows.h" "${CURRENT_HEADER_DIR}/AudioGrabber.h" "${CURRENT_HEADER_DIR}/AudioWrapper.h" "${CURRENT_SOURCE_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*Windows.cpp" "${CURRENT_SOURCE_DIR}/AudioGrabber.cpp" "${CURRENT_SOURCE_DIR}/AudioWrapper.cpp") FILE ( GLOB AUDIO_GRABBER_SOURCES "${CURRENT_HEADER_DIR}/Audio*Windows.h" "${CURRENT_HEADER_DIR}/AudioGrabber.h" "${CURRENT_HEADER_DIR}/AudioWrapper.h" "${CURRENT_SOURCE_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*Windows.cpp" "${CURRENT_SOURCE_DIR}/AudioGrabber.cpp" "${CURRENT_SOURCE_DIR}/AudioWrapper.cpp")
elseif(${CMAKE_SYSTEM} MATCHES "Linux") elseif(${CMAKE_SYSTEM} MATCHES "Linux")
FILE ( GLOB AUDIO_GRABBER_SOURCES "${CURRENT_HEADER_DIR}/Audio*Linux.h" "${CURRENT_HEADER_DIR}/AudioGrabber.h" "${CURRENT_HEADER_DIR}/AudioWrapper.h" "${CURRENT_SOURCE_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*Linux.cpp" "${CURRENT_SOURCE_DIR}/AudioGrabber.cpp" "${CURRENT_SOURCE_DIR}/AudioWrapper.cpp") FILE ( GLOB AUDIO_GRABBER_SOURCES "${CURRENT_HEADER_DIR}/Audio*Linux.h" "${CURRENT_HEADER_DIR}/AudioGrabber.h" "${CURRENT_HEADER_DIR}/AudioWrapper.h" "${CURRENT_SOURCE_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*Linux.cpp" "${CURRENT_SOURCE_DIR}/AudioGrabber.cpp" "${CURRENT_SOURCE_DIR}/AudioWrapper.cpp")

View File

@ -103,7 +103,7 @@ bool QtGrabber::setupDisplay()
Info(_log, "Available Displays:"); Info(_log, "Available Displays:");
int index = 0; int index = 0;
for (auto* screen : qAsConst(screens)) for (auto* screen : std::as_const(screens))
{ {
const QRect geo = screen->geometry(); const QRect geo = screen->geometry();
Info(_log, "Display %d: Name: %s Resolution: [%dx%d], Geometry: (L,T,R,B) %d,%d,%d,%d Depth:%dbit", index, QSTRING_CSTR(screen->name()), geo.width(), geo.height(), geo.x(), geo.y(), geo.x() + geo.width(), geo.y() + geo.height(), screen->depth()); Info(_log, "Display %d: Name: %s Resolution: [%dx%d], Geometry: (L,T,R,B) %d,%d,%d,%d Depth:%dbit", index, QSTRING_CSTR(screen->name()), geo.width(), geo.height(), geo.x(), geo.y(), geo.x() + geo.width(), geo.y() + geo.height(), screen->depth());

View File

@ -61,7 +61,7 @@ ComponentRegister::ComponentRegister(Hyperion* hyperion)
vect << COMP_FORWARDER; vect << COMP_FORWARDER;
#endif #endif
for(auto e : qAsConst(vect)) for(auto e : std::as_const(vect))
{ {
_componentStates.emplace(e, (e == COMP_ALL)); _componentStates.emplace(e, (e == COMP_ALL));
} }

View File

@ -58,9 +58,9 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
} }
// transform json to string lists // transform json to string lists
QStringList keyList = defaultConfig.keys(); const QStringList keyList = defaultConfig.keys();
QStringList defValueList; QStringList defValueList;
for (const auto& key : qAsConst(keyList)) for (const auto& key : keyList)
{ {
if (defaultConfig[key].isObject()) if (defaultConfig[key].isObject())
{ {
@ -73,7 +73,7 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
} }
// fill database with default data if required // fill database with default data if required
for (const auto& key : qAsConst(keyList)) for (const auto& key : keyList)
{ {
QString val = defValueList.takeFirst(); QString val = defValueList.takeFirst();
// prevent overwrite // prevent overwrite
@ -86,7 +86,7 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
// need to validate all data in database construct the entire data object // need to validate all data in database construct the entire data object
// TODO refactor schemaChecker to accept QJsonArray in validate(); QJsonDocument container? To validate them per entry... // TODO refactor schemaChecker to accept QJsonArray in validate(); QJsonDocument container? To validate them per entry...
QJsonObject dbConfig; QJsonObject dbConfig;
for (const auto& key : qAsConst(keyList)) for (const auto& key : keyList)
{ {
QJsonDocument doc = _sTable->getSettingsRecord(key); QJsonDocument doc = _sTable->getSettingsRecord(key);
if (doc.isArray()) if (doc.isArray())
@ -242,9 +242,9 @@ bool SettingsManager::saveSettings(QJsonObject config, bool correct)
_qconfig = config; _qconfig = config;
// extract keys and data // extract keys and data
QStringList keyList = config.keys(); const QStringList keyList = config.keys();
QStringList newValueList; QStringList newValueList;
for (const auto& key : qAsConst(keyList)) for (const auto& key : keyList)
{ {
if (config[key].isObject()) if (config[key].isObject())
{ {
@ -258,7 +258,7 @@ bool SettingsManager::saveSettings(QJsonObject config, bool correct)
bool rc = true; bool rc = true;
// compare database data with new data to emit/save changes accordingly // compare database data with new data to emit/save changes accordingly
for (const auto& key : qAsConst(keyList)) for (const auto& key : keyList)
{ {
QString data = newValueList.takeFirst(); QString data = newValueList.takeFirst();
if (_sTable->getSettingsRecordString(key) != data) if (_sTable->getSettingsRecordString(key) != data)
@ -269,7 +269,15 @@ bool SettingsManager::saveSettings(QJsonObject config, bool correct)
} }
else else
{ {
emit settingsChanged(settings::stringToType(key), QJsonDocument::fromJson(data.toLocal8Bit())); QJsonParseError error;
QJsonDocument jsonDocument = QJsonDocument::fromJson(data.toUtf8(), &error);
if (error.error != QJsonParseError::NoError) {
Error(_log, "Error parsing JSON: %s", QSTRING_CSTR(error.errorString()));
rc = false;
}
else {
emit settingsChanged(settings::stringToType(key), jsonDocument);
}
} }
} }
} }
@ -618,10 +626,10 @@ bool SettingsManager::handleConfigUpgrade(QJsonObject& config)
QJsonArray json; QJsonArray json;
if (newForwarderConfig.contains("json")) if (newForwarderConfig.contains("json"))
{ {
QJsonArray oldJson = newForwarderConfig["json"].toArray(); const QJsonArray oldJson = newForwarderConfig["json"].toArray();
QJsonObject newJsonConfig; QJsonObject newJsonConfig;
for (const QJsonValue& value : qAsConst(oldJson)) for (const QJsonValue& value : oldJson)
{ {
if (value.isString()) if (value.isString())
{ {
@ -661,10 +669,10 @@ bool SettingsManager::handleConfigUpgrade(QJsonObject& config)
QJsonArray flatbuffer; QJsonArray flatbuffer;
if (newForwarderConfig.contains("flat")) if (newForwarderConfig.contains("flat"))
{ {
QJsonArray oldFlatbuffer = newForwarderConfig["flat"].toArray(); const QJsonArray oldFlatbuffer = newForwarderConfig["flat"].toArray();
QJsonObject newFlattbufferConfig; QJsonObject newFlattbufferConfig;
for (const QJsonValue& value : qAsConst(oldFlatbuffer)) for (const QJsonValue& value : oldFlatbuffer)
{ {
if (value.isString()) if (value.isString())
{ {

View File

@ -352,12 +352,12 @@ bool LedDeviceWled::powerOn()
} }
else else
{ {
QJsonArray propertiesSegments = _originalStateProperties[STATE_SEG].toArray(); const QJsonArray propertiesSegments = _originalStateProperties[STATE_SEG].toArray();
bool isStreamSegmentIdFound { false }; bool isStreamSegmentIdFound { false };
QJsonArray segments; QJsonArray segments;
for (const auto& segmentItem : qAsConst(propertiesSegments)) for (const auto& segmentItem : propertiesSegments)
{ {
QJsonObject segmentObj = segmentItem.toObject(); QJsonObject segmentObj = segmentItem.toObject();
@ -505,9 +505,9 @@ bool LedDeviceWled::restoreState()
if (_isStreamToSegment) if (_isStreamToSegment)
{ {
QJsonArray propertiesSegments = _originalStateProperties[STATE_SEG].toArray(); const QJsonArray propertiesSegments = _originalStateProperties[STATE_SEG].toArray();
QJsonArray segments; QJsonArray segments;
for (const auto& segmentItem : qAsConst(propertiesSegments)) for (const auto& segmentItem : propertiesSegments)
{ {
QJsonObject segmentObj = segmentItem.toObject(); QJsonObject segmentObj = segmentItem.toObject();

View File

@ -65,7 +65,7 @@ void Logger::deleteInstance(const QString & name, const QString & subName)
if (name.isEmpty()) if (name.isEmpty())
{ {
for (auto *logger : qAsConst(LoggerMap)) { for (auto *logger : std::as_const(LoggerMap)) {
delete logger; delete logger;
} }

View File

@ -59,13 +59,13 @@ QPair<bool, bool> QJsonSchemaChecker::validate(const QJsonObject& value, bool ig
QJsonObject QJsonSchemaChecker::getAutoCorrectedConfig(const QJsonObject& value, bool ignoreRequired) QJsonObject QJsonSchemaChecker::getAutoCorrectedConfig(const QJsonObject& value, bool ignoreRequired)
{ {
_ignoreRequired = ignoreRequired; _ignoreRequired = ignoreRequired;
QStringList sequence = QStringList() << "remove" << "modify" << "create"; const QStringList sequence = QStringList() << "remove" << "modify" << "create";
_error = false; _error = false;
_schemaError = false; _schemaError = false;
_messages.clear(); _messages.clear();
_autoCorrected = value; _autoCorrected = value;
for (const QString& correct : qAsConst(sequence)) for (const QString& correct : sequence)
{ {
_correct = correct; _correct = correct;
_currentPath.clear(); _currentPath.clear();

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1.0) cmake_minimum_required(VERSION 3.5.0)
project(hyperion-aml) project(hyperion-aml)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1.0) cmake_minimum_required(VERSION 3.5.0)
project(hyperion-dispmanx) project(hyperion-dispmanx)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1.0) cmake_minimum_required(VERSION 3.5.0)
project(hyperion-framebuffer) project(hyperion-framebuffer)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1.0) cmake_minimum_required(VERSION 3.5.0)
project(hyperion-osx) project(hyperion-osx)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Widgets REQUIRED)

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1.0) cmake_minimum_required(VERSION 3.5.0)
project(hyperion-qt) project(hyperion-qt)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Network Widgets REQUIRED)

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1.0) cmake_minimum_required(VERSION 3.5.0)
project(hyperion-remote) project(hyperion-remote)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)

View File

@ -57,9 +57,9 @@ void showHelp(Option & option){
int getInstaneIdbyName(const QJsonObject & reply, const QString & name){ int getInstaneIdbyName(const QJsonObject & reply, const QString & name){
if(reply.contains("instance")){ if(reply.contains("instance")){
QJsonArray list = reply.value("instance").toArray(); const QJsonArray list = reply.value("instance").toArray();
for ( const auto &entry : qAsConst(list) ) { for ( const auto &entry : list ) {
const QJsonObject obj = entry.toObject(); const QJsonObject obj = entry.toObject();
if(obj["friendly_name"] == name && obj["running"].toBool()) if(obj["friendly_name"] == name && obj["running"].toBool())
{ {

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1.0) cmake_minimum_required(VERSION 3.5.0)
project(hyperion-v4l2) project(hyperion-v4l2)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1.0) cmake_minimum_required(VERSION 3.5.0)
project(hyperion-x11) project(hyperion-x11)
find_package(X11 REQUIRED) find_package(X11 REQUIRED)

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1.0) cmake_minimum_required(VERSION 3.5.0)
project(hyperion-xcb) project(hyperion-xcb)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network Widgets REQUIRED)

View File

@ -15,4 +15,5 @@ void CreateConsole()
freopen_s(&fDummy, "CONOUT$", "w", stderr); freopen_s(&fDummy, "CONOUT$", "w", stderr);
freopen_s(&fDummy, "CONIN$", "r", stdin); freopen_s(&fDummy, "CONIN$", "r", stdin);
SetConsoleTitle(TEXT("Hyperion")); SetConsoleTitle(TEXT("Hyperion"));
SetConsoleOutputCP(CP_UTF8);
} }

View File

@ -268,9 +268,9 @@ int main(int argc, char** argv)
if (directory.exists() && destDir.exists()) if (directory.exists() && destDir.exists())
{ {
std::cout << "Extract to folder: " << destDir.absolutePath().toStdString() << std::endl; std::cout << "Extract to folder: " << destDir.absolutePath().toStdString() << std::endl;
QStringList filenames = directory.entryList(QStringList() << "*", QDir::Files, QDir::Name | QDir::IgnoreCase); const QStringList filenames = directory.entryList(QStringList() << "*", QDir::Files, QDir::Name | QDir::IgnoreCase);
QString destFileName; QString destFileName;
for (const QString & filename : qAsConst(filenames)) for (const QString & filename : filenames)
{ {
destFileName = destDir.dirName()+"/"+filename; destFileName = destDir.dirName()+"/"+filename;
if (QFile::exists(destFileName)) if (QFile::exists(destFileName))