Kjetil Matheussen <k.s.matheussen(a)gmail.com> writes:
Mario Lang:
#include <jack.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
template<typename... Features>
using AudioAccumulatorSet = boost::accumulators::accumulator_set<
float, boost::accumulators::features<Features...>
;
using Count = boost::accumulators::tag::count;
using Max = boost::accumulators::tag::max;
using Min = boost::accumulators::tag::min;
using Mean = boost::accumulators::tag::mean;
using Variance = boost::accumulators::tag::variance;
class Statistics final : public JACK::Client {
JACK::AudioIn In;
AudioAccumulatorSet<Count, Max, Mean, Min, Variance> Accumulator;
public:
Statistics() : JACK::Client("Statistics"), In(createAudioIn("In"))
{}
int process(std::uint32_t FrameCount) override {
for (auto &Value: In.buffer(FrameCount)) Accumulator(Value);
return 0;
}
auto max() const { return boost::accumulators::max(Accumulator); }
auto mean() const { return boost::accumulators::mean(Accumulator); }
auto min() const { return boost::accumulators::min(Accumulator); }
auto sampleCount() const { return boost::accumulators::count(Accumulator); }
auto variance() const { return boost::accumulators::variance(Accumulator); }
};
Nice code. But I wonder about one small thing related to C++.
Couldn't these max/mean/etc. methods in the Statististics class
be written shorter like this?:
auto max() const { return Max(Accumulator); }
auto mean() const { return Mean(Accumulator); }
auto min() const { return Min(Accumulator); }
auto sampleCount() const { return Count(Accumulator); }
auto variance() const { return Variance(Accumulator); }
No, because boost::accumulators::tag::mean is not the same as
boost::accumulators::mean. The first is a "tag" to let the accumulator_set
know (at compile time) which statistics it is supposed to collect,
and the second is a so-called "extractor" which is used to retrieve the result
of a
particular statistics (obviously, at runtime).
Sorry if it's a stupid question, but I haven't
used "using" in C++ yet. :-)
Sorry for sort of overusing 'using' here, I was trying to make a point
(to me, mostly) of abstracting away overly long names without the big
hammer of just including a whole namespace. I tend to prefer knowing
what parts of a namespace are actually actively called/used in my programs.
If you are into long lines, you could of course drop all the using
directives, and eliminate the convenience template AudioAccumulatorSet altogether,
which would give you:
boost::accumulators::accumulator_set<float,
boost::accumulators::features<boost::accumulators::tag::count,
boost::accumulators::tag::mean, boost::accumulators::tag::min,
boost::accumulators::tag::max, boost::accumulators::tag::variance>> Accumulator;
But now it doesn't look like an ad gig for C++ anymore :-)
But the point of that code was really just to make JACK::Client do
something.
--
CYa,
⡍⠁⠗⠊⠕