aboutsummaryrefslogtreecommitdiff
path: root/samples/SpeechRecognition/include/SlidingWindow.hpp
blob: 791a0b7fc013617ee15316ba3628be08f434624a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//
// Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

template<class T>
class SlidingWindow
{
protected:
    T* m_start = nullptr;
    size_t m_dataSize = 0;
    size_t m_size = 0;
    size_t m_stride = 0;
    size_t m_count = 0;
public:

    /**
     * Creates the window slider through the given data.
     *
     * @param data          pointer to the data to slide through.
     * @param dataSize      size in T type elements wise.
     * @param windowSize    sliding window size in T type wise elements.
     * @param stride        stride size in T type wise elements.
     */
    SlidingWindow(T* data, size_t dataSize,
                  size_t windowSize, size_t stride)
    {
        m_start = data;
        m_dataSize = dataSize;
        m_size = windowSize;
        m_stride = stride;
    }

    SlidingWindow() = default;

    ~SlidingWindow() = default;

    /**
     * Get the next data window.
     * @return pointer to the next window, if next window is not available nullptr is returned.
     */
    virtual T* Next()
    {
        if (HasNext())
        {
            m_count++;
            return m_start + Index() * m_stride;
        }
        else
        {
            return nullptr;
        }
    }

    /**
     * Checks if the next data portion is available.
     * @return true if next data portion is available
     */
    bool HasNext()
    {
        return this->m_count < 1 + this->FractionalTotalStrides() && (this->NextWindowStartIndex() < this->m_dataSize);
    }

    /**
     * Resest the slider to the initial position.
     */
    virtual void Reset()
    {
        m_count = 0;
    }

    /**
     * Resest the slider to the initial position.
     */
    virtual size_t GetWindowSize()
    {
        return m_size;
    }

    /**
     * Resets the slider to the start of the new data.
     * New data size MUST be the same as the old one.
     * @param newStart pointer to the new data to slide through.
     */
    virtual void Reset(T* newStart)
    {
        m_start = newStart;
        Reset();
    }

    /**
     * Gets current index of the sliding window.
     * @return current position of the sliding window in number of strides
     */
    size_t Index()
    {
        return m_count == 0? 0: m_count - 1;
    }

    /**
     * Gets the index from the start of the data where the next window will begin.
     * While Index() returns the index of sliding window itself this function returns the index of the data
     * element itself.
     * @return Index from the start of the data where the next sliding window will begin.
     */
    virtual size_t NextWindowStartIndex()
    {
        return m_count == 0? 0: ((m_count) * m_stride);
    }

    /**
     * Go to given sliding window index.
     * @param index new position of the sliding window. if index is invalid (greater than possible range of strides)
     *              then next call to Next() will return nullptr.
     */
    void FastForward(size_t index)
    {
        m_count = index;
    }

    /**
     * Calculates whole number of times the window can stride through the given data.
     * @return maximum number of strides.
     */
    size_t TotalStrides()
    {
        if (m_size > m_dataSize)
        {
            return 0;
        }
        return ((m_dataSize - m_size)/m_stride);
    }

    /**
     * Calculates number of times the window can stride through the given data. May not be a whole number.
     * @return Number of strides to cover all data.
     */
    float FractionalTotalStrides()
    {
        if(this->m_size > this->m_dataSize)
        {
            return this->m_dataSize / this->m_size;
        }
        else
        {
            return ((this->m_dataSize - this->m_size)/ static_cast<float>(this->m_stride));
        }

    }

    /**
     * Calculates the remaining data left to be processed
     * @return The remaining unprocessed data
     */
    int RemainingData()
    {
        return this->m_dataSize - this->NextWindowStartIndex();
    }
};