summaryrefslogtreecommitdiff
path: root/source/application/main/include/AudioUtils.hpp
blob: cba981d019dd88ad79b44df453801f6145171e6a (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
162
163
164
165
166
167
168
169
170
171
/*
 * Copyright (c) 2021 Arm Limited. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef AUDIO_UTILS_HPP
#define AUDIO_UTILS_HPP

#include <cstddef>
#include <cstdint>

namespace arm {
namespace app {
namespace audio {

    template<class T>
    class SlidingWindow {
    public:

        /**
         * @brief     Creates the window slider through the given data.
         *
         * @param[in] data         Pointer to the data to slide through.
         * @param[in] dataSize     Size in T type elements wise.
         * @param[in] windowSize   Sliding window size in T type wise elements.
         * @param[in] 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;

        /**
         * @brief  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;
            }
        }

        /**
         * @brief  Checks if the next data portion is available.
         * @return true if next data portion is available.
         */
        virtual bool HasNext() {
            return m_size + m_count * m_stride <= m_dataSize;
        }

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

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

        /**
         * @brief  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;
        }

        /**
         * @brief  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 uint32_t NextWindowStartIndex() {
            return m_count == 0? 0: ((m_count) * m_stride);
        }

        /**
         * @brief     Go to given sliding window index.
         * @param[in] 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;
        }

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

        /**
         * @brief  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_dataSize < this->m_size) {
                return 0;
            } else {
                return ((this->m_dataSize - this->m_size)/ static_cast<float>(this->m_stride));
            }
        }

    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;
    };

    /*
     * Sliding window for ASR will cover the whole of the input, even if
     * this means the last window is not a full window length.
     */
    template<class T>
    class ASRSlidingWindow : public SlidingWindow<T> {
    public:
        using SlidingWindow<T>::SlidingWindow;

        /**
         * @brief  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);
        }
    };


} /* namespace audio */
} /* namespace app */
} /* namespace arm */

#endif /* AUDIO_UTILS_HPP */