blob: cba981d019dd88ad79b44df453801f6145171e6a [file] [log] [blame]
alexander3c798932021-03-26 21:42:19 +00001/*
2 * Copyright (c) 2021 Arm Limited. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17#ifndef AUDIO_UTILS_HPP
18#define AUDIO_UTILS_HPP
19
20#include <cstddef>
21#include <cstdint>
22
23namespace arm {
24namespace app {
25namespace audio {
26
27 template<class T>
28 class SlidingWindow {
29 public:
30
31 /**
32 * @brief Creates the window slider through the given data.
33 *
34 * @param[in] data Pointer to the data to slide through.
35 * @param[in] dataSize Size in T type elements wise.
36 * @param[in] windowSize Sliding window size in T type wise elements.
37 * @param[in] stride Stride size in T type wise elements.
38 */
39 SlidingWindow(T *data, size_t dataSize,
40 size_t windowSize, size_t stride) {
41 m_start = data;
42 m_dataSize = dataSize;
43 m_size = windowSize;
44 m_stride = stride;
45 }
46
47 SlidingWindow() = default;
48
49 ~SlidingWindow() = default;
50
51 /**
52 * @brief Get the next data window.
53 * @return Pointer to the next window, if next window is not available nullptr is returned.
54 */
55 virtual T *Next() {
56 if (HasNext()) {
57 m_count++;
58 return m_start + Index() * m_stride;
59 } else {
60 return nullptr;
61 }
62 }
63
64 /**
65 * @brief Checks if the next data portion is available.
66 * @return true if next data portion is available.
67 */
68 virtual bool HasNext() {
69 return m_size + m_count * m_stride <= m_dataSize;
70 }
71
72 /**
73 * @brief Reset the slider to the initial position.
74 */
75 virtual void Reset() {
76 m_count = 0;
77 }
78
79 /**
80 * @brief Resets the slider to the start of the new data.
81 * New data size MUST be the same as the old one.
82 * @param[in] newStart Pointer to the new data to slide through.
83 */
84 virtual void Reset(T *newStart) {
85 m_start = newStart;
86 Reset();
87 }
88
89 /**
90 * @brief Gets current index of the sliding window.
91 * @return Current position of the sliding window in number of strides.
92 */
93 size_t Index() {
94 return m_count == 0? 0: m_count - 1;
95 }
96
97 /**
98 * @brief Gets the index from the start of the data where the next window will begin.
99 * While Index() returns the index of sliding window itself this function
100 * returns the index of the data element itself.
101 * @return Index from the start of the data where the next sliding window will begin.
102 */
103 virtual uint32_t NextWindowStartIndex() {
104 return m_count == 0? 0: ((m_count) * m_stride);
105 }
106
107 /**
108 * @brief Go to given sliding window index.
109 * @param[in] index New position of the sliding window. If index is invalid
110 * (greater than possible range of strides) then next call to Next() will return nullptr.
111 */
112 void FastForward(size_t index) {
113 m_count = index;
114 }
115
116 /**
117 * @brief Calculates whole number of times the window can stride through the given data.
118 * @return Maximum number of whole strides.
119 */
120 size_t TotalStrides() {
121 if (m_size > m_dataSize) {
122 return 0;
123 }
124 return ((m_dataSize - m_size)/m_stride);
125 }
126
127 /**
128 * @brief Calculates number of times the window can stride through the given data.
129 * May not be a whole number.
130 * @return Number of strides to cover all data.
131 */
132 float FractionalTotalStrides() {
133 if (this->m_dataSize < this->m_size) {
134 return 0;
135 } else {
136 return ((this->m_dataSize - this->m_size)/ static_cast<float>(this->m_stride));
137 }
138 }
139
140 protected:
141 T *m_start = nullptr;
142 size_t m_dataSize = 0;
143 size_t m_size = 0;
144 size_t m_stride = 0;
145 size_t m_count = 0;
146 };
147
148 /*
149 * Sliding window for ASR will cover the whole of the input, even if
150 * this means the last window is not a full window length.
151 */
152 template<class T>
153 class ASRSlidingWindow : public SlidingWindow<T> {
154 public:
155 using SlidingWindow<T>::SlidingWindow;
156
157 /**
158 * @brief Checks if the next data portion is available.
159 * @return true if next data portion is available.
160 */
161 bool HasNext() {
162 return this->m_count < 1 + this->FractionalTotalStrides() && (this->NextWindowStartIndex() < this->m_dataSize);
163 }
164 };
165
166
167} /* namespace audio */
168} /* namespace app */
169} /* namespace arm */
170
171#endif /* AUDIO_UTILS_HPP */