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