// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #pragma once #include #include #include struct IndexValueTuple { int Index = -1; float Value = 0.f; }; namespace DSP { std::vector MovingAverage(const std::vector& signal, size_t numOfPoints); std::vector FirstDerivate(const std::vector& signal); std::vector DivideTwoArrays(std::vector& dividend, std::vector& divisor); IndexValueTuple FindMaximum(const std::vector& signal, size_t minIdx, size_t maxIdx); IndexValueTuple FindMinimum(const std::vector& signal, size_t minIdx, size_t maxIdx); float Angle(k4a_float3_t A, k4a_float3_t B, k4a_float3_t C); class RollingWindow { public: RollingWindow(int windowSize) { m_window.resize(windowSize, 0); m_circularIndex = windowSize - 1; } void Update(const std::chrono::microseconds& timestamp, float v) { // Remove nans if (v != v) return; m_circularIndex = (m_circularIndex + 1) % m_window.size(); m_movingAverageDelta = (v - m_window[m_circularIndex]) / m_window.size(); m_movingAverage += m_movingAverageDelta; m_window[m_circularIndex] = v; if (m_circularIndex == m_window.size() - 1) { m_filled = true; } m_timestampDelta = timestamp - m_timestamp; m_timestamp = timestamp; } bool IsValid() const { return m_filled; } float GetMovingAverage() const { return m_movingAverage; } float GetMovingAverageVelocity() const { return m_movingAverageDelta / m_timestampDelta.count(); } private: std::vector m_window; float m_movingAverage = 0; float m_movingAverageDelta = 0; size_t m_circularIndex = 0; bool m_filled = false; std::chrono::microseconds m_timestamp; std::chrono::microseconds m_timestampDelta; }; };