diff --git a/utility/MinMaxHelpers.hpp b/utility/MinMaxHelpers.hpp new file mode 100644 index 00000000..670940dc --- /dev/null +++ b/utility/MinMaxHelpers.hpp @@ -0,0 +1,29 @@ +// Copyright (c) 2024 Sean Nowlan +// Copyright (c) 2014-2019 Josh Blum +// SPDX-License-Identifier: BSL-1.0 + +#pragma once + +#include +#include //abs +#include + +template +T getMin(const T& a, const T& b) { + return std::min(a, b); +} + +template +T getMax(const T& a, const T& b) { + return std::max(a, b); +} + +template +std::complex getMin(const std::complex& a, const std::complex& b) { + return std::min(std::abs(a), std::abs(b)); +} + +template +std::complex getMax(const std::complex& a, const std::complex& b) { + return std::max(std::abs(a), std::abs(b)); +} diff --git a/utility/SignalProbe.cpp b/utility/SignalProbe.cpp index 6b7f5bcf..454a9795 100644 --- a/utility/SignalProbe.cpp +++ b/utility/SignalProbe.cpp @@ -8,6 +8,8 @@ #include #include //min/max #include +#include +#include "MinMaxHelpers.hpp" /*********************************************************************** * |PothosDoc Signal Probe @@ -20,11 +22,15 @@ * * The calculation for value can be, the last seen value, * the RMS (root mean square) over the last buffer, - * or the mean (average value) over the last buffer. + * the mean (average value) over the last buffer, + * the minimum value (real) or absolute value (complex) over the last buffer, + * the maximum value (real) or absolute value (complex) over the last buffer, + * the minimum absolute value (magnitude) over the last buffer, + * or the maximum absolute value (magnitude) over the last buffer. * * |category /Utility * |category /Event - * |keywords rms average mean + * |keywords rms average mean min minimum max maximum * |alias /blocks/stream_probe * * |param dtype[Data Type] The data type consumed by the stream probe. @@ -40,6 +46,10 @@ * |option [Value] "VALUE" * |option [RMS] "RMS" * |option [Mean] "MEAN" + * |option [Min] "MIN" + * |option [Max] "MAX" + * |option [Min Abs] "MINABS" + * |option [Max Abs] "MAXABS" * * |param rate How many calculations per second? * The probe will perform a calculation at most this many times per second. @@ -158,6 +168,53 @@ class SignalProbe : public Pothos::Block mean /= N; _value = mean; } + else if (_mode == "MIN") + { + ProbeType minimum = std::numeric_limits::max(); + ProbeType x_n; + for (size_t n = 0; n < N; n++) + { + x_n = Pothos::Util::fromQ(x[n], 0); + minimum = getMin(minimum, x_n); + } + _value = minimum; + } + else if (_mode == "MAX") + { + ProbeType maximum = std::numeric_limits::lowest(); + ProbeType x_n; + for (size_t n = 0; n < N; n++) + { + x_n = Pothos::Util::fromQ(x[n], 0); + maximum = getMax(maximum, x_n); + } + _value = maximum; + } + + else if (_mode == "MINABS") + { + double minimum = std::numeric_limits::max(); + ProbeType x_n; + for (size_t n = 0; n < N; n++) + { + x_n = Pothos::Util::fromQ(x[n], 0); + const double mag = std::abs(x_n); + minimum = std::min(minimum, mag); + } + _value = minimum; + } + else if (_mode == "MAXABS") + { + double maximum = std::numeric_limits::lowest(); + ProbeType x_n; + for (size_t n = 0; n < N; n++) + { + x_n = Pothos::Util::fromQ(x[n], 0); + const double mag = std::abs(x_n); + maximum = std::max(maximum, mag); + } + _value = maximum; + } this->emitSignal("valueChanged", _value); }