DAP: Add intrin DAPSpecs

We now specify intrins as separate DAPS lines. This syntax is much
nicer and well-grouped than the previous negtrin-*/postrin-* param
names.

Alas, we're about to replace it in the next few commits already though.
This commit is contained in:
2026-04-12 04:06:47 -04:00
parent c696316a1e
commit fc1fcae0b0
14 changed files with 595 additions and 284 deletions
+16 -1
View File
@@ -10,6 +10,7 @@
#include <opts.h>
#include <user/senseApiDesc.h>
#include <user/deviceAttachmentSpec.h>
#include <user/intrinThresholdParams.h>
#include <spinscale/callback.h>
#include <livoxProto1/livoxProto1.h>
#include <livoxProto1/device.h>
@@ -513,6 +514,8 @@ static const StimBuffApiDesc livoxGen1ApiDesc = {
{.name = "mesh"},
{.name = "pcloudIntensity"},
{.name = "pcloudAmbience"},
{.name = "negtrin"},
{.name = "postrin"},
{.name = "gyro"},
{.name = "accel"}
},
@@ -645,12 +648,24 @@ extern "C" void livoxGen1_attachDeviceReq(
return;
}
try {
smo::intrin::validateIntrinsQualeApiPolicy(
desc->qualeIfaceApi, desc->qualeIfaceApiParams);
}
catch (const std::runtime_error& e)
{
std::cerr << __func__ << ": " << e.what() << std::endl;
cb.callbackFn(false, desc);
return;
}
if (!PcloudStimulusProducer::supportsQualeIfaceApi(qualeIfaceApi))
{
// Unknown qualeIfaceApi
std::cerr << __func__ << ": Unsupported qualeIfaceApi '"
<< qualeIfaceApi << "' for LivoxGen1. "
"Supported values: mesh, pcloudIntensity, pcloudAmbience"
"Supported values: mesh, pcloudIntensity, pcloudAmbience, "
"negtrin, postrin"
<< std::endl;
cb.callbackFn(false, desc);
return;
+8 -1
View File
@@ -4,6 +4,7 @@
#include <memory>
#include <user/stimulusBuffer.h>
#include <user/stagingBuffer.h>
#include <user/intrinThresholdParams.h>
namespace smo {
namespace stim_buff {
@@ -13,6 +14,8 @@ class StimulusProducer;
/**
* MeshStimulusBuffer is a specialized StimulusBuffer for mesh data.
* Intrinsic threshold params are not allowed on mesh qualeIfaceApi lines;
* use dedicated negtrin/postrin specs (docs/design/intrin-thresholds.md).
*/
class MeshStimulusBuffer
: public StimulusBuffer
@@ -30,7 +33,11 @@ public:
parent, deviceAttachmentSpec, histbuffMs,
inputEngineConstraints, outputEngineConstraints,
callbacks, flags)
{}
{
intrin::validateIntrinsQualeApiPolicy(
deviceAttachmentSpec->qualeIfaceApi,
deviceAttachmentSpec->qualeIfaceApiParams);
}
~MeshStimulusBuffer() = default;
@@ -0,0 +1,251 @@
#ifndef _LIVOX_GEN1_PCLOUD_AMBIENCE_INTRIN_STIMULUS_BUFFER_H
#define _LIVOX_GEN1_PCLOUD_AMBIENCE_INTRIN_STIMULUS_BUFFER_H
#include <memory>
#include <cstdint>
#include <cstddef>
#include <optional>
#include <string>
#include <user/stimulusBuffer.h>
#include <user/stagingBuffer.h>
#include <user/deviceAttachmentSpec.h>
#include <user/intrinThresholdParams.h>
#include "pcloudAmbienceQualeIfaceApi.h"
namespace smo {
namespace stim_buff {
enum class IntrinStatus
{
DISABLED,
NEGTRIN,
POSTRIN,
};
struct ParsedAmbienceIntrinConfig
{
IntrinStatus status;
uint32_t interestPercentage;
uint32_t interestThreshold;
};
inline bool isAmbienceIntrinEnabled(IntrinStatus intrinStatus)
{
return intrinStatus != IntrinStatus::DISABLED;
}
inline intrin::ParsedThresholdParam parseAmbienceThresholdParam(
const std::string& paramName,
const std::string& paramValue,
intrin::ThresholdUnit unit)
{
try
{
return intrin::ParsedThresholdParam{
.value = std::stoi(paramValue),
.unit = unit,
.matchedName = paramName,
.wasSpecified = true,
};
}
catch (const std::exception& e)
{
throw std::runtime_error(
"Failed to parse '" + paramName + "' param value '" + paramValue
+ "' as integer: " + e.what());
}
}
inline ParsedAmbienceIntrinConfig buildAmbienceIntrinConfig(
IntrinStatus status,
const intrin::ParsedThresholdParam& thresholdParam,
size_t nDgramsPerFrame)
{
return ParsedAmbienceIntrinConfig{
.status = status,
.interestPercentage =
thresholdParam.unit == intrin::ThresholdUnit::Percentage
? static_cast<uint32_t>(thresholdParam.value)
: 0U,
.interestThreshold = intrin::resolveThresholdValue(
thresholdParam, nDgramsPerFrame),
};
}
inline std::optional<ParsedAmbienceIntrinConfig> tryParseAmbienceIntrinConfig(
const std::string& paramName,
const std::string& paramValue,
size_t nDgramsPerFrame,
const std::string& qualeIfaceApi)
{
using intrin::ThresholdUnit;
const bool apiIsPostrin = (qualeIfaceApi == "postrin");
const bool apiIsNegtrin = (qualeIfaceApi == "negtrin");
if (intrin::namesContain(intrin::kPosIntPcParamNames, paramName)
|| (apiIsPostrin
&& intrin::namesContain(
intrin::kIntrinInterestPcUnprefixed, paramName)))
{
return buildAmbienceIntrinConfig(
IntrinStatus::POSTRIN,
parseAmbienceThresholdParam(
paramName, paramValue, ThresholdUnit::Percentage),
nDgramsPerFrame);
}
if (intrin::namesContain(intrin::kPosIntThrParamNames, paramName)
|| (apiIsPostrin
&& intrin::namesContain(
intrin::kIntrinInterestThrUnprefixed, paramName)))
{
return buildAmbienceIntrinConfig(
IntrinStatus::POSTRIN,
parseAmbienceThresholdParam(
paramName, paramValue, ThresholdUnit::Absolute),
nDgramsPerFrame);
}
if (intrin::namesContain(intrin::kNegIntPcParamNames, paramName)
|| (apiIsNegtrin
&& intrin::namesContain(
intrin::kIntrinInterestPcUnprefixed, paramName)))
{
return buildAmbienceIntrinConfig(
IntrinStatus::NEGTRIN,
parseAmbienceThresholdParam(
paramName, paramValue, ThresholdUnit::Percentage),
nDgramsPerFrame);
}
if (intrin::namesContain(intrin::kNegIntThrParamNames, paramName)
|| (apiIsNegtrin
&& intrin::namesContain(
intrin::kIntrinInterestThrUnprefixed, paramName)))
{
return buildAmbienceIntrinConfig(
IntrinStatus::NEGTRIN,
parseAmbienceThresholdParam(
paramName, paramValue, ThresholdUnit::Absolute),
nDgramsPerFrame);
}
return std::nullopt;
}
inline ParsedAmbienceIntrinConfig parseAmbienceIntrinConfig(
const std::shared_ptr<device::DeviceAttachmentSpec>& deviceAttachmentSpec,
size_t nDgramsPerFrame)
{
const auto& params = deviceAttachmentSpec->qualeIfaceApiParams;
for (auto paramIt = params.rbegin(); paramIt != params.rend(); ++paramIt)
{
const auto& [paramName, paramValue] = *paramIt;
const auto parsedConfig = tryParseAmbienceIntrinConfig(
paramName,
paramValue,
nDgramsPerFrame,
deviceAttachmentSpec->qualeIfaceApi);
if (parsedConfig.has_value())
{ return parsedConfig.value(); }
}
return ParsedAmbienceIntrinConfig{
.status = IntrinStatus::DISABLED,
.interestPercentage = 0U,
.interestThreshold = 0U,
};
}
inline void validateAmbienceIntrinComparatorConfig(
IntrinStatus intrinStatus,
const std::optional<ParamComparator>& passbandCountComparator)
{
if (isAmbienceIntrinEnabled(intrinStatus)
&& !passbandCountComparator.has_value())
{
throw std::runtime_error(
"A PcloudAmbience intrinsic pipeline with an intrin threshold "
"must also specify either 'passband-count-gt-val' or "
"'passband-count-lt-val'");
}
}
class StimulusProducer;
/**
* Intrinsic pipeline for LivoxGen1 ambience: attaches as qualeIfaceApi
* negtrin(...) or postrin(...) with from-stimbuff=pcloudAmbience. Parses
* interest thresholds and passband comparators; sensory data still flows
* through PcloudAmbienceStimulusBuffer.
*/
class PcloudAmbienceIntrinStimulusBuffer
: public StimulusBuffer
{
public:
explicit PcloudAmbienceIntrinStimulusBuffer(
StimulusProducer& parent,
const std::shared_ptr<device::DeviceAttachmentSpec>& deviceAttachmentSpec,
int histbuffMs,
const StagingBuffer::IOEngineConstraints& inputEngineConstraints,
const StagingBuffer::IOEngineConstraints& outputEngineConstraints,
const SmoCallbacks& callbacks,
cl_mem_flags flags,
size_t nDgramsPerFrame_)
: StimulusBuffer(
parent, deviceAttachmentSpec, histbuffMs,
inputEngineConstraints, outputEngineConstraints,
callbacks, flags),
nDgramsPerFrame(nDgramsPerFrame_)
{
intrin::validateIntrinsQualeApiPolicy(
deviceAttachmentSpec->qualeIfaceApi,
deviceAttachmentSpec->qualeIfaceApiParams);
intrin::validateNoForbiddenUnitlessIntrinParams(
deviceAttachmentSpec->qualeIfaceApiParams);
const auto intrinConfig = parseAmbienceIntrinConfig(
deviceAttachmentSpec, nDgramsPerFrame_);
intrinStatus = intrinConfig.status;
intrinInterestPercentage = intrinConfig.interestPercentage;
intrinInterestThreshold = intrinConfig.interestThreshold;
passbandCountComparator = parseOptionalPcloudAmbienceParamComparator(
deviceAttachmentSpec);
validateAmbienceIntrinComparatorConfig(
intrinStatus, passbandCountComparator);
}
~PcloudAmbienceIntrinStimulusBuffer() = default;
bool shouldTriggerIntrinEvent(uint32_t ambiencePassbandCount) const
{
if (!isAmbienceIntrinEnabled(intrinStatus))
{ return false; }
return ambiencePassbandCount >= intrinInterestThreshold;
}
PcloudAmbienceIntrinStimulusBuffer(
const PcloudAmbienceIntrinStimulusBuffer&) = delete;
PcloudAmbienceIntrinStimulusBuffer& operator=(
const PcloudAmbienceIntrinStimulusBuffer&) = delete;
PcloudAmbienceIntrinStimulusBuffer(PcloudAmbienceIntrinStimulusBuffer&&) =
delete;
PcloudAmbienceIntrinStimulusBuffer& operator=(
PcloudAmbienceIntrinStimulusBuffer&&) = delete;
public:
IntrinStatus intrinStatus;
uint32_t intrinInterestPercentage;
uint32_t intrinInterestThreshold;
std::optional<ParamComparator> passbandCountComparator;
size_t nDgramsPerFrame;
};
} // namespace stim_buff
} // namespace smo
#endif // _LIVOX_GEN1_PCLOUD_AMBIENCE_INTRIN_STIMULUS_BUFFER_H
@@ -5,11 +5,34 @@
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <user/deviceAttachmentSpec.h>
#include <vector>
namespace smo {
namespace stim_buff {
inline std::string parseRequiredFromStimbuffQualeIfaceName(
const std::vector<std::pair<std::string, std::string>>& params)
{
for (auto it = params.rbegin(); it != params.rend(); ++it)
{
if (it->first != "from-stimbuff")
{ continue; }
if (it->second.empty())
{
throw std::runtime_error(
"'from-stimbuff' must name a non-empty sensory qualeIfaceApi");
}
return it->second;
}
throw std::runtime_error(
"internal: 'from-stimbuff' missing after intrin policy validation");
}
enum ParamComparatorOp
{
OP_CMP_GT,
@@ -21,14 +44,14 @@ struct ParamComparator
ParamComparatorOp op;
uint32_t value;
bool operator()(float ambienceVal) const
bool operator()(float passbandMetricVal) const
{
switch (op)
{
case OP_CMP_GT:
return ambienceVal > static_cast<float>(value);
return passbandMetricVal > static_cast<float>(value);
case OP_CMP_LT:
return ambienceVal < static_cast<float>(value);
return passbandMetricVal < static_cast<float>(value);
}
throw std::runtime_error("Unsupported ParamComparatorOp");
@@ -41,15 +64,15 @@ inline std::optional<ParamComparator> parseOptionalPcloudAmbienceParamComparator
const auto& params = deviceAttachmentSpec->qualeIfaceApiParams;
constexpr int kParamNotSpecified = -1;
const int gtVal = device::DeviceAttachmentSpec::parseOptionalParamAsInt(
params, "ambience-count-gt-val", kParamNotSpecified);
params, "passband-count-gt-val", kParamNotSpecified);
const int ltVal = device::DeviceAttachmentSpec::parseOptionalParamAsInt(
params, "ambience-count-lt-val", kParamNotSpecified);
params, "passband-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");
"Only one of 'passband-count-gt-val' or 'passband-count-lt-val' "
"may be specified for a PcloudAmbience intrinsic pipeline");
}
if (gtVal != kParamNotSpecified)
@@ -2,164 +2,22 @@
#define _LIVOX_GEN1_PCLOUD_AMBIENCE_STIMULUS_BUFFER_H
#include <memory>
#include <cstdint>
#include <cstddef>
#include <optional>
#include <vector>
#include <string>
#include <user/stimulusBuffer.h>
#include <user/stagingBuffer.h>
#include <user/deviceAttachmentSpec.h>
#include <user/intrinThresholdParams.h>
#include "pcloudAmbienceQualeIfaceApi.h"
namespace smo {
namespace stim_buff {
enum class IntrinStatus
{
DISABLED,
NEGTRIN,
POSTRIN,
};
struct ParsedAmbienceIntrinConfig
{
IntrinStatus status;
uint32_t interestPercentage;
uint32_t interestThreshold;
};
inline bool isAmbienceIntrinEnabled(IntrinStatus intrinStatus)
{
return intrinStatus != IntrinStatus::DISABLED;
}
inline intrin::ParsedThresholdParam parseAmbienceThresholdParam(
const std::string& paramName,
const std::string& paramValue,
intrin::ThresholdUnit unit)
{
try
{
return intrin::ParsedThresholdParam{
.value = std::stoi(paramValue),
.unit = unit,
.matchedName = paramName,
.wasSpecified = true,
};
}
catch (const std::exception& e)
{
throw std::runtime_error(
"Failed to parse '" + paramName + "' param value '" + paramValue
+ "' as integer: " + e.what());
}
}
inline ParsedAmbienceIntrinConfig buildAmbienceIntrinConfig(
IntrinStatus status,
const intrin::ParsedThresholdParam& thresholdParam,
size_t nDgramsPerFrame)
{
return ParsedAmbienceIntrinConfig{
.status = status,
.interestPercentage =
thresholdParam.unit == intrin::ThresholdUnit::Percentage
? static_cast<uint32_t>(thresholdParam.value)
: 0U,
.interestThreshold = intrin::resolveThresholdValue(
thresholdParam, nDgramsPerFrame),
};
}
inline std::optional<ParsedAmbienceIntrinConfig> tryParseAmbienceIntrinConfig(
const std::string& paramName,
const std::string& paramValue,
size_t nDgramsPerFrame)
{
using intrin::ThresholdUnit;
if (intrin::namesContain(intrin::kPosIntPcParamNames, paramName))
{
return buildAmbienceIntrinConfig(
IntrinStatus::POSTRIN,
parseAmbienceThresholdParam(
paramName, paramValue, ThresholdUnit::Percentage),
nDgramsPerFrame);
}
if (intrin::namesContain(intrin::kPosIntThrParamNames, paramName))
{
return buildAmbienceIntrinConfig(
IntrinStatus::POSTRIN,
parseAmbienceThresholdParam(
paramName, paramValue, ThresholdUnit::Absolute),
nDgramsPerFrame);
}
if (intrin::namesContain(intrin::kNegIntPcParamNames, paramName))
{
return buildAmbienceIntrinConfig(
IntrinStatus::NEGTRIN,
parseAmbienceThresholdParam(
paramName, paramValue, ThresholdUnit::Percentage),
nDgramsPerFrame);
}
if (intrin::namesContain(intrin::kNegIntThrParamNames, paramName))
{
return buildAmbienceIntrinConfig(
IntrinStatus::NEGTRIN,
parseAmbienceThresholdParam(
paramName, paramValue, ThresholdUnit::Absolute),
nDgramsPerFrame);
}
return std::nullopt;
}
inline ParsedAmbienceIntrinConfig parseAmbienceIntrinConfig(
const std::shared_ptr<device::DeviceAttachmentSpec>& deviceAttachmentSpec,
size_t nDgramsPerFrame)
{
const auto& params = deviceAttachmentSpec->qualeIfaceApiParams;
for (auto paramIt = params.rbegin(); paramIt != params.rend(); ++paramIt)
{
const auto& [paramName, paramValue] = *paramIt;
const auto parsedConfig = tryParseAmbienceIntrinConfig(
paramName, paramValue, nDgramsPerFrame);
if (parsedConfig.has_value())
{ return parsedConfig.value(); }
}
return ParsedAmbienceIntrinConfig{
.status = IntrinStatus::DISABLED,
.interestPercentage = 0U,
.interestThreshold = 0U,
};
}
inline void validateAmbienceIntrinComparatorConfig(
IntrinStatus intrinStatus,
const std::optional<ParamComparator>& ambienceCountComparator)
{
if (isAmbienceIntrinEnabled(intrinStatus)
&& !ambienceCountComparator.has_value())
{
throw std::runtime_error(
"A pcloudAmbience stim buff instance with an intrin threshold "
"must also specify either 'ambience-count-gt-val' or "
"'ambience-count-lt-val'");
}
}
// Forward declaration
class StimulusProducer;
/**
* PcloudAmbienceStimulusBuffer is a specialized StimulusBuffer for ambience point cloud data.
* Sensory PcloudAmbience buffer: per-dgram ambience floats only.
* Intrinsic thresholds and passband comparators are only valid on dedicated
* negtrin/postrin qualeIfaceApi specs (PcloudAmbienceIntrinStimulusBuffer);
* see docs/design/intrin-thresholds.md.
*/
class PcloudAmbienceStimulusBuffer
: public StimulusBuffer
@@ -180,42 +38,21 @@ public:
callbacks, flags),
nDgramsPerFrame(nDgramsPerFrame_)
{
intrin::validateNoForbiddenUnitlessIntrinParams(
intrin::validateIntrinsQualeApiPolicy(
deviceAttachmentSpec->qualeIfaceApi,
deviceAttachmentSpec->qualeIfaceApiParams);
const auto intrinConfig = parseAmbienceIntrinConfig(
deviceAttachmentSpec, nDgramsPerFrame_);
intrinStatus = intrinConfig.status;
intrinInterestPercentage = intrinConfig.interestPercentage;
intrinInterestThreshold = intrinConfig.interestThreshold;
ambienceCountComparator = parseOptionalPcloudAmbienceParamComparator(
deviceAttachmentSpec);
validateAmbienceIntrinComparatorConfig(
intrinStatus, ambienceCountComparator);
}
~PcloudAmbienceStimulusBuffer() = default;
bool shouldTriggerIntrinEvent(uint32_t ambiencePassbandCount) const
{
if (!isAmbienceIntrinEnabled(intrinStatus))
{ return false; }
return ambiencePassbandCount >= intrinInterestThreshold;
}
// Non-copyable, non-movable: inherited pinner lifetime is instance-bound
PcloudAmbienceStimulusBuffer(const PcloudAmbienceStimulusBuffer&) = delete;
PcloudAmbienceStimulusBuffer& operator=(const PcloudAmbienceStimulusBuffer&) = delete;
PcloudAmbienceStimulusBuffer& operator=(
const PcloudAmbienceStimulusBuffer&) = delete;
PcloudAmbienceStimulusBuffer(PcloudAmbienceStimulusBuffer&&) = delete;
PcloudAmbienceStimulusBuffer& operator=(PcloudAmbienceStimulusBuffer&&) = delete;
PcloudAmbienceStimulusBuffer& operator=(
PcloudAmbienceStimulusBuffer&&) = delete;
public:
IntrinStatus intrinStatus;
uint32_t intrinInterestPercentage;
uint32_t intrinInterestThreshold;
std::optional<ParamComparator> ambienceCountComparator;
size_t nDgramsPerFrame;
};
@@ -4,6 +4,7 @@
#include <memory>
#include <user/stimulusBuffer.h>
#include <user/stagingBuffer.h>
#include <user/intrinThresholdParams.h>
namespace smo {
namespace stim_buff {
@@ -31,7 +32,11 @@ public:
parent, deviceAttachmentSpec, histbuffMs,
inputEngineConstraints, outputEngineConstraints,
callbacks, flags)
{}
{
intrin::validateIntrinsQualeApiPolicy(
deviceAttachmentSpec->qualeIfaceApi,
deviceAttachmentSpec->qualeIfaceApiParams);
}
~PcloudIntensityStimulusBuffer() = default;
@@ -4,6 +4,7 @@
#include <unistd.h>
#include <iomanip>
#include <cstddef>
#include <string>
#include <user/spMcRingBuffer.h>
#include <componentThread.h>
#include <spinscale/asynchronousLoop.h>
@@ -13,6 +14,24 @@
#include "livoxGen1.h"
#include "pcloudStimulusProducer.h"
namespace {
void requirePcloudAmbienceFromStimbuff(
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& spec)
{
const std::string fromName =
smo::stim_buff::parseRequiredFromStimbuffQualeIfaceName(
spec->qualeIfaceApiParams);
if (fromName != "pcloudAmbience")
{
throw std::runtime_error(
"LivoxGen1 PcloudAmbience intrinsic pipelines require "
"from-stimbuff=pcloudAmbience (got '" + fromName + "').");
}
}
} // namespace
namespace smo {
namespace stim_buff {
@@ -132,7 +151,8 @@ bool PcloudStimulusProducer::supportsQualeIfaceApi(
const std::string& qualeIfaceApi)
{
return qualeIfaceApi == "mesh" || qualeIfaceApi == "pcloudIntensity" ||
qualeIfaceApi == "pcloudAmbience";
qualeIfaceApi == "pcloudAmbience" || qualeIfaceApi == "negtrin" ||
qualeIfaceApi == "postrin";
}
bool PcloudStimulusProducer::exportsQualeIfaceApi(
@@ -228,6 +248,11 @@ PcloudStimulusProducer::getAttachedStimulusBuffer(
if (std::dynamic_pointer_cast<PcloudAmbienceStimulusBuffer>(buffer))
{ return buffer; }
}
else if (qualeIfaceApi == "negtrin" || qualeIfaceApi == "postrin")
{
if (std::dynamic_pointer_cast<PcloudAmbienceIntrinStimulusBuffer>(buffer))
{ return buffer; }
}
// Type mismatch - return nullptr
return nullptr;
@@ -259,6 +284,22 @@ void PcloudStimulusProducer::destroyAttachedStimulusBuffer(
ambienceBuff.reset();
ambienceStimulusBuffer.store(nullptr, std::memory_order_release);
}
auto negIntrinBuff = negtrinAmbienceIntrinStimulusBuffer.load(
std::memory_order_acquire);
if (negIntrinBuff == buffer)
{
negIntrinBuff.reset();
negtrinAmbienceIntrinStimulusBuffer.store(
nullptr, std::memory_order_release);
}
auto posIntrinBuff = postrinAmbienceIntrinStimulusBuffer.load(
std::memory_order_acquire);
if (posIntrinBuff == buffer)
{
posIntrinBuff.reset();
postrinAmbienceIntrinStimulusBuffer.store(
nullptr, std::memory_order_release);
}
// Call base class implementation to remove from attachedStimulusBuffers
StimulusProducer::destroyAttachedStimulusBuffer(buffer);
@@ -343,12 +384,38 @@ PcloudStimulusProducer::getOrCreateAttachedStimulusBuffer(
this->start();
return ambienceStimBuff;
}
else if (qualeIfaceApi == "negtrin" || qualeIfaceApi == "postrin")
{
requirePcloudAmbienceFromStimbuff(deviceAttachmentSpec);
auto intrinBuff = std::make_shared<PcloudAmbienceIntrinStimulusBuffer>(
*this, deviceAttachmentSpec, histbuffMs,
openClAmbienceInputConstraints, openClAmbienceInputConstraints,
*smoHooksPtr, CL_MEM_READ_WRITE,
this->nDgramsPerStagingBufferFrame);
this->stop();
addAttachedStimulusBufferIfNotExists(intrinBuff);
if (qualeIfaceApi == "negtrin")
{
negtrinAmbienceIntrinStimulusBuffer.store(
intrinBuff, std::memory_order_release);
}
else
{
postrinAmbienceIntrinStimulusBuffer.store(
intrinBuff, std::memory_order_release);
}
this->start();
return intrinBuff;
}
else
{
throw std::runtime_error(
"Unsupported qualeIfaceApi: '" + qualeIfaceApi + "' for "
"PcloudStimulusProducer. "
"Supported values: mesh, pcloudIntensity, pcloudAmbience");
"Supported values: mesh, pcloudIntensity, pcloudAmbience, "
"negtrin, postrin");
}
}
@@ -15,6 +15,7 @@
#include "meshStimulusBuffer.h"
#include "pcloudIntensityStimulusBuffer.h"
#include "pcloudAmbienceStimulusBuffer.h"
#include "pcloudAmbienceIntrinStimulusBuffer.h"
namespace smo {
namespace stim_buff {
@@ -104,6 +105,10 @@ public:
intensityStimulusBuffer;
std::atomic<std::shared_ptr<PcloudAmbienceStimulusBuffer>>
ambienceStimulusBuffer;
std::atomic<std::shared_ptr<PcloudAmbienceIntrinStimulusBuffer>>
negtrinAmbienceIntrinStimulusBuffer;
std::atomic<std::shared_ptr<PcloudAmbienceIntrinStimulusBuffer>>
postrinAmbienceIntrinStimulusBuffer;
private:
class ProduceFrameReq;