xref: /aosp_15_r20/external/armnn/samples/common/include/Audio/SlidingWindow.hpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #pragma once
7 
8 template<class T>
9 class SlidingWindow
10 {
11 protected:
12     T* m_start = nullptr;
13     size_t m_dataSize = 0;
14     size_t m_size = 0;
15     size_t m_stride = 0;
16     size_t m_count = 0;
17 public:
18 
19     /**
20      * Creates the window slider through the given data.
21      *
22      * @param data          pointer to the data to slide through.
23      * @param dataSize      size in T type elements wise.
24      * @param windowSize    sliding window size in T type wise elements.
25      * @param stride        stride size in T type wise elements.
26      */
SlidingWindow(T * data,size_t dataSize,size_t windowSize,size_t stride)27     SlidingWindow(T* data, size_t dataSize,
28                   size_t windowSize, size_t stride)
29     {
30         m_start = data;
31         m_dataSize = dataSize;
32         m_size = windowSize;
33         m_stride = stride;
34     }
35 
36     SlidingWindow() = default;
37 
38     ~SlidingWindow() = default;
39 
40     /**
41      * Get the next data window.
42      * @return pointer to the next window, if next window is not available nullptr is returned.
43      */
Next()44     virtual T* Next()
45     {
46         if (HasNext())
47         {
48             m_count++;
49             return m_start + Index() * m_stride;
50         }
51         else
52         {
53             return nullptr;
54         }
55     }
56 
57     /**
58      * Checks if the next data portion is available.
59      * @return true if next data portion is available
60      */
HasNext()61     bool HasNext()
62     {
63         return this->m_count < 1 + this->FractionalTotalStrides() && (this->NextWindowStartIndex() < this->m_dataSize);
64     }
65 
66     /**
67      * Resest the slider to the initial position.
68      */
Reset()69     virtual void Reset()
70     {
71         m_count = 0;
72     }
73 
74     /**
75      * Resest the slider to the initial position.
76      */
GetWindowSize()77     virtual size_t GetWindowSize()
78     {
79         return m_size;
80     }
81 
82     /**
83      * Resets the slider to the start of the new data.
84      * New data size MUST be the same as the old one.
85      * @param newStart pointer to the new data to slide through.
86      */
Reset(T * newStart)87     virtual void Reset(T* newStart)
88     {
89         m_start = newStart;
90         Reset();
91     }
92 
93     /**
94      * Gets current index of the sliding window.
95      * @return current position of the sliding window in number of strides
96      */
Index()97     size_t Index()
98     {
99         return m_count == 0? 0: m_count - 1;
100     }
101 
102     /**
103      * Gets the index from the start of the data where the next window will begin.
104      * While Index() returns the index of sliding window itself this function returns the index of the data
105      * element itself.
106      * @return Index from the start of the data where the next sliding window will begin.
107      */
NextWindowStartIndex()108     virtual size_t NextWindowStartIndex()
109     {
110         return m_count == 0? 0: ((m_count) * m_stride);
111     }
112 
113     /**
114      * Go to given sliding window index.
115      * @param index new position of the sliding window. if index is invalid (greater than possible range of strides)
116      *              then next call to Next() will return nullptr.
117      */
FastForward(size_t index)118     void FastForward(size_t index)
119     {
120         m_count = index;
121     }
122 
123     /**
124      * Calculates whole number of times the window can stride through the given data.
125      * @return maximum number of strides.
126      */
TotalStrides()127     size_t TotalStrides()
128     {
129         if (m_size > m_dataSize)
130         {
131             return 0;
132         }
133         return ((m_dataSize - m_size)/m_stride);
134     }
135 
136     /**
137      * Calculates number of times the window can stride through the given data. May not be a whole number.
138      * @return Number of strides to cover all data.
139      */
FractionalTotalStrides()140     float FractionalTotalStrides()
141     {
142         if(this->m_size > this->m_dataSize)
143         {
144             return this->m_dataSize / this->m_size;
145         }
146         else
147         {
148             return ((this->m_dataSize - this->m_size)/ static_cast<float>(this->m_stride));
149         }
150 
151     }
152 
153     /**
154      * Calculates the remaining data left to be processed
155      * @return The remaining unprocessed data
156      */
RemainingData()157     int RemainingData()
158     {
159         return this->m_dataSize - this->NextWindowStartIndex();
160     }
161 };