From 7516da6aa8d11097ef728cd90431a58b87bf6675 Mon Sep 17 00:00:00 2001 From: Hayodea Hekol Date: Fri, 3 Apr 2026 23:54:22 -0400 Subject: [PATCH] Api improvements: ambience-count-[l|g]t-val and Comparator --- include/user/deviceAttachmentSpec.h | 24 +++++- .../openClCollatingAndMeshingEngine.cpp | 13 ++- .../livoxGen1/pcloudAmbienceQualeIfaceApi.h | 79 +++++++++++++++++++ .../livoxGen1/pcloudAmbienceStimulusBuffer.h | 14 +--- 4 files changed, 111 insertions(+), 19 deletions(-) create mode 100644 stimBuffApis/livoxGen1/pcloudAmbienceQualeIfaceApi.h diff --git a/include/user/deviceAttachmentSpec.h b/include/user/deviceAttachmentSpec.h index af1b6eb..a72201c 100644 --- a/include/user/deviceAttachmentSpec.h +++ b/include/user/deviceAttachmentSpec.h @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace smo { @@ -115,6 +116,25 @@ public: } } + /** + * @brief Parse an optional integer parameter from a parameter list + * @param params The parameter vector to search in + * @param paramName The name of the parameter to parse + * @param defaultValue The default value to return if no parameter is found + * @return The parsed integer value, or defaultValue if none found + * @note The lattermost supplied matching param wins if multiple are present + */ + static int parseOptionalParamAsInt( + const std::vector>& params, + const std::string& paramName, + int defaultValue + ) + { + const std::string paramNames[] = {paramName}; + return parseOptionalParamAsIntWithSynonyms( + params, paramNames, defaultValue); + } + /** * @brief Parse an optional integer parameter from a parameter list using synonyms * @param params The parameter vector to search in @@ -135,9 +155,9 @@ public: { const auto& [paramName, paramValue] = *paramIt; auto synonymIt = std::find( - synonymNames.begin(), synonymNames.end(), paramName); + std::begin(synonymNames), std::end(synonymNames), paramName); - if (synonymIt == synonymNames.end()) + if (synonymIt == std::end(synonymNames)) { continue; } try { diff --git a/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.cpp b/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.cpp index acb350c..9a1e606 100644 --- a/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.cpp +++ b/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.cpp @@ -988,19 +988,18 @@ void OpenClCollatingAndMeshingEngine::produceAmbienceStimulusFrame( parent.ambienceStimulusBuffer.load(std::memory_order_acquire); if (!ambienceBuff) { return; } - uint32_t lowVal = ambienceBuff->ambienceIntensityLowVal; + const auto& ambienceCountComparator = ambienceBuff->ambienceCountComparator; // Read average intensity values from averageIntensityBuffer float* averageIntensityAverages = reinterpret_cast( averageIntensityBufferPtr); - // Count frames whose average intensity is <= lowVal (postrin only) + // Count frames whose average intensity matches the configured comparator. uint32_t ambienceCount = 0; for (uint32_t i = 0; i < nSucceeded; ++i) { float avg = averageIntensityAverages[i]; - if (avg <= static_cast(lowVal)) - { + if (ambienceCountComparator(avg)) { ++ambienceCount; } } @@ -1223,7 +1222,8 @@ public: { std::shared_ptr ambienceBuff = engine.parent.ambienceStimulusBuffer.load(std::memory_order_acquire); - uint32_t lowVal = ambienceBuff->ambienceIntensityLowVal; + const auto& ambienceCountComparator = + ambienceBuff->ambienceCountComparator; uint32_t postrinThreshold = ambienceBuff->postrinInterestThreshold; float* averageIntensityAverages = reinterpret_cast( @@ -1233,8 +1233,7 @@ public: for (uint32_t i = 0; i < nSucceeded; ++i) { float avg = averageIntensityAverages[i]; - if (avg <= static_cast(lowVal)) - { + if (ambienceCountComparator(avg)) { ++framesMetThreshold; } } diff --git a/stimBuffApis/livoxGen1/pcloudAmbienceQualeIfaceApi.h b/stimBuffApis/livoxGen1/pcloudAmbienceQualeIfaceApi.h new file mode 100644 index 0000000..d804193 --- /dev/null +++ b/stimBuffApis/livoxGen1/pcloudAmbienceQualeIfaceApi.h @@ -0,0 +1,79 @@ +#ifndef _LIVOX_GEN1_PCLOUD_AMBIENCE_QUALE_IFACE_API_H +#define _LIVOX_GEN1_PCLOUD_AMBIENCE_QUALE_IFACE_API_H + +#include +#include +#include +#include + +namespace smo { +namespace stim_buff { + +enum ParamComparatorOp +{ + OP_CMP_GT, + OP_CMP_LT, +}; + +struct ParamComparator +{ + ParamComparatorOp op; + uint32_t value; + + bool operator()(float ambienceVal) const + { + switch (op) + { + case OP_CMP_GT: + return ambienceVal > static_cast(value); + case OP_CMP_LT: + return ambienceVal < static_cast(value); + } + + throw std::runtime_error("Unsupported ParamComparatorOp"); + } +}; + +inline ParamComparator parsePcloudAmbienceParamComparator( + const std::shared_ptr& deviceAttachmentSpec) +{ + const auto& params = deviceAttachmentSpec->qualeIfaceApiParams; + constexpr int kParamNotSpecified = -1; + const int gtVal = device::DeviceAttachmentSpec::parseOptionalParamAsInt( + params, "ambience-count-gt-val", kParamNotSpecified); + const int ltVal = device::DeviceAttachmentSpec::parseOptionalParamAsInt( + params, "ambience-count-lt-val", kParamNotSpecified); + + if (gtVal != kParamNotSpecified && ltVal != kParamNotSpecified) + { + throw std::runtime_error( + "Only one of 'ambience-count-gt-val' or 'ambience-count-lt-val' " + "may be specified for a pcloudAmbience stim buff instance"); + } + + if (gtVal != kParamNotSpecified) + { + return ParamComparator{ + .op = OP_CMP_GT, + .value = static_cast(gtVal), + }; + } + + if (ltVal != kParamNotSpecified) + { + return ParamComparator{ + .op = OP_CMP_LT, + .value = static_cast(ltVal), + }; + } + + return ParamComparator{ + .op = OP_CMP_LT, + .value = 8U, + }; +} + +} // namespace stim_buff +} // namespace smo + +#endif // _LIVOX_GEN1_PCLOUD_AMBIENCE_QUALE_IFACE_API_H diff --git a/stimBuffApis/livoxGen1/pcloudAmbienceStimulusBuffer.h b/stimBuffApis/livoxGen1/pcloudAmbienceStimulusBuffer.h index 27fdd1d..9f27845 100644 --- a/stimBuffApis/livoxGen1/pcloudAmbienceStimulusBuffer.h +++ b/stimBuffApis/livoxGen1/pcloudAmbienceStimulusBuffer.h @@ -11,6 +11,7 @@ #include #include #include +#include "pcloudAmbienceQualeIfaceApi.h" #include "lg1PcloudAmbienceStencil.h" namespace smo { @@ -63,15 +64,8 @@ public: : 0U; postrinInterestThreshold = intrin::resolveThresholdValue( postrinInterestParam, nDgramsPerFrame_); - - // Parse ambienceIntensityLowVal from qualeIfaceApiParams - const std::vector ambienceIntensityLowValParamNames = { - "ambience-intensity-low-val" - }; - ambienceIntensityLowVal = static_cast( - device::DeviceAttachmentSpec::parseOptionalParamAsIntWithSynonyms( - deviceAttachmentSpec->qualeIfaceApiParams, - ambienceIntensityLowValParamNames, 8)); + ambienceCountComparator = parsePcloudAmbienceParamComparator( + deviceAttachmentSpec); // Construct stencils and add to list (FIFO behavior) for (size_t i = 0; i < nStencils; ++i) { @@ -90,7 +84,7 @@ public: public: uint32_t postrinInterestPercentage; uint32_t postrinInterestThreshold; - uint32_t ambienceIntensityLowVal; + ParamComparator ambienceCountComparator; size_t nStencils; std::list stencils; };