4#include <initializer_list>
10#include "metrics/hart_metrics_common.hpp"
41template <
typename ValueType>
50 using SingleChannelMetricEvaluator = std::function<ValueType (size_t channel,
Slice slice,
Unit requestedUnit)>;
58 using ChannelPairMetricEvaluator = std::function<ValueType (size_t channelA, size_t channelB,
Slice slice,
Unit requestedUnit)>;
69 SingleChannelMetricEvaluator evaluator,
70 size_t totalNumChannels,
71 std::vector<size_t>&& defaultChannelsToProcess
74 m_query =
hart::make_unique<Query>();
75 m_query->singleChannelMetricEvaluator = std::move (evaluator);
76 m_query->totalNumChannelsA = totalNumChannels;
77 m_query->totalNumChannelsB = 0;
80 m_query->channels = std::move (defaultChannelsToProcess);
95 ChannelPairMetricEvaluator evaluator,
96 size_t totalNumChannelsA,
97 size_t totalNumChannelsB,
98 std::vector<std::pair<size_t, size_t>>&& defaultChannelPairsToProcess
101 m_query =
hart::make_unique<Query>();
102 m_query->channelPairMetricEvaluator = std::move (evaluator);
103 m_query->totalNumChannelsA = totalNumChannelsA;
104 m_query->totalNumChannelsB = totalNumChannelsB;
107 m_query->channelPairs = std::move (defaultChannelPairsToProcess);
118 copy.m_query =
hart::make_unique<Query> (*m_query);
119 copy.m_query->requestedUnit = requestedUnit;
132 copy.m_query =
hart::make_unique<Query> (*m_query);
134 if (getEvaluatorType() == EvaluatorType::singleChannels)
136 copy.m_query->channels.clear();
137 copy.m_query->channels.push_back (channel);
141 copy.m_query->channelPairs.clear();
142 copy.m_query->channelPairs.push_back (std::make_pair (channel, channel));
158 copy.m_query =
hart::make_unique<Query> (*m_query);
160 if (getEvaluatorType() == EvaluatorType::singleChannels)
162 copy.m_query->channels.clear();
163 copy.m_query->channels.reserve (channels.size());
164 copy.m_query->channels.assign (channels.begin(), channels.end());
168 copy.m_query->channelPairs.clear();
169 copy.m_query->channelPairs.reserve (channels.size());
171 for (
const size_t channel : channels)
172 copy.m_query->channelPairs.emplace_back (channel, channel);
185 MetricQuery ch (std::initializer_list<std::pair<size_t, size_t>> channels)
const
188 copy.m_query =
hart::make_unique<Query> (*m_query);
190 if (getEvaluatorType() == EvaluatorType::singleChannels)
193 copy.m_query->channelPairs.clear();
194 copy.m_query->channels.reserve (channels.size());
195 copy.m_query->channelPairs.assign (channels.begin(), channels.end());
207 copy.m_query =
hart::make_unique<Query> (*m_query);
209 if (getEvaluatorType() == EvaluatorType::singleChannels)
211 copy.m_query->channels.clear();
212 copy.m_query->channels.reserve (channelFlags
.numTrue());
214 for (size_t channel = 0; channel < channelFlags
.size(); ++ channel)
215 if (channelFlags
[channel
] ==
true)
216 copy.m_query->channels.push_back (channel);
220 copy.m_query->channelPairs.clear();
221 copy.m_query->channelPairs.reserve (channelFlags
.numTrue());
223 for (size_t channel = 0; channel < channelFlags
.size(); ++ channel)
224 if (channelFlags
[channel
] ==
true)
225 copy.m_query->channelPairs.emplace_back (channel, channel);
237 copy.m_query =
hart::make_unique<Query> (*m_query);
242 copy.m_query->slice = slice;
257 template <
typename ReducerType>
258 auto get (ReducerType reducer)
const
259 -> ReducerResultType<ReducerType,
typename std::vector<ValueType>::
const_iterator>
262 return reducer (m_query->cachedValues.begin(), m_query->cachedValues.end());
272 return get (
first());
282 return get (
first());
288 SingleChannelMetricEvaluator singleChannelMetricEvaluator =
nullptr;
289 ChannelPairMetricEvaluator channelPairMetricEvaluator =
nullptr;
290 std::vector<size_t> channels;
291 std::vector<std::pair<size_t, size_t>> channelPairs;
292 size_t totalNumChannelsA = 0;
293 size_t totalNumChannelsB = 0;
296 mutable bool cacheValid =
false;
297 mutable std::vector<ValueType> cachedValues;
300 enum class EvaluatorType
307 EvaluatorType getEvaluatorType()
const
311 if (m_query->singleChannelMetricEvaluator !=
nullptr)
313 hassert (m_query->channelPairMetricEvaluator ==
nullptr);
314 return EvaluatorType::singleChannels;
317 if (m_query->channelPairMetricEvaluator !=
nullptr)
319 hassert (m_query->singleChannelMetricEvaluator ==
nullptr);
320 return EvaluatorType::channelPairs;
324 return EvaluatorType::none;
327 void ensureCache()
const
329 if (m_query->cacheValid)
332 m_query->cachedValues.clear();
334 if (getEvaluatorType() == EvaluatorType::singleChannels)
335 buildCacheForSingleChannelsEvaluator();
337 buildCacheForChannelPairsEvaluator();
339 m_query->cacheValid =
true;
342 void buildCacheForSingleChannelsEvaluator()
const
344 for (size_t channel : m_query->channels)
346 if (channel >= m_query->totalNumChannelsA)
349 m_query->cachedValues.push_back (
350 m_query->singleChannelMetricEvaluator (
353 m_query->requestedUnit
359 void buildCacheForChannelPairsEvaluator()
const
361 for (
const std::pair<size_t, size_t>& channelPair : m_query->channelPairs)
363 if (channelPair.first >= m_query->totalNumChannelsA || channelPair.second >= m_query->totalNumChannelsB)
366 m_query->cachedValues.push_back (
367 m_query->channelPairMetricEvaluator (
371 m_query->requestedUnit
377 std::shared_ptr<Query> m_query;
A set of boolean flags mapped to each audio channel.
bool operator[](size_t channel) const
Access the flag value for a specific channel.
size_t size() const noexcept
Returns the size (not capacity) of the container.
size_t numTrue() const noexcept
Checks how many channels are marked with true
Thrown when a container index is out of range.
Manages the metrics calculations.
MetricQuery(ChannelPairMetricEvaluator evaluator, size_t totalNumChannelsA, size_t totalNumChannelsB, std::vector< std::pair< size_t, size_t > > &&defaultChannelPairsToProcess)
Create a metric query object for a metric that operates on pair of channels at a time.
MetricQuery(SingleChannelMetricEvaluator evaluator, size_t totalNumChannels, std::vector< size_t > &&defaultChannelsToProcess)
Create a metric query object for a metric that operates on one channel at a time.
MetricQuery ch(std::initializer_list< std::pair< size_t, size_t > > channels) const
Requests the metric to be applied to certain channel pairs.
MetricQuery ch(std::initializer_list< size_t > channels) const
Requests the metric to be applied to certain channels.
MetricQuery ch(size_t channel) const
Requests the metric to be applied to certain channel.
operator ValueType() const
Query a value of a calculated metric.
MetricQuery ch(const ChannelFlags &channelFlags) const
Requests the metric to be applied to certain channels.
MetricQuery at(Slice slice) const
Requests to perform a metric on a specific range inside of data.
ValueType get() const
Query a value of a calculated metric.
auto get(ReducerType reducer) const -> ReducerResultType< ReducerType, typename std::vector< ValueType >::const_iterator >
Query a value of a calculated metric using a reducer.
MetricQuery as(Unit requestedUnit) const
Requests the metric to return its value(s) in a certain unit.
Thrown when an unexpected container size is encountered.
Thrown when some parameter has an unsupported value.
#define HART_THROW_OR_RETURN_VOID(ExceptionType, message)
Throws an exception if HART_DO_NOT_THROW_EXCEPTIONS is set, prints a message and returns otherwise.
#define hassert(condition)
Triggers a HartAssertException if the condition is false
#define HART_THROW_OR_RETURN(ExceptionType, message, returnValue)
Throws an exception if HART_DO_NOT_THROW_EXCEPTIONS is set, prints a message and returns a specified ...
#define hassertfalse
Triggers a HartAssertException
Unit
Represents a physical unit.
@ native
Default (native) unit of whatever returns some value.
Represents a slice of analysis data.
Returns the first element in the range.