1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef RDSP_H
18#define RDSP_H
19
20#include <complex>
21#include <log/log.h>
22#include <vector>
23#include <map>
24using FloatVec = std::vector<float>;
25using IntVec = std::vector<int>;
26using ComplexVec  = std::vector<std::complex<float>>;
27
28// =======
29// Helper Functions
30// =======
31template <class T>
32static T dBtoLinear(T valueDb) {
33    return pow (10, valueDb / 20.0);
34}
35
36template <class T>
37static T linearToDb(T value) {
38    return 20 * log10(value);
39}
40
41// =======
42// DSP window creation
43// =======
44
45#define TWOPI (M_PI * 2)
46
47enum rdsp_window_type {
48    RDSP_WINDOW_RECTANGULAR,
49    RDSP_WINDOW_TRIANGULAR,
50    RDSP_WINDOW_TRIANGULAR_FLAT_TOP,
51    RDSP_WINDOW_HAMMING,
52    RDSP_WINDOW_HAMMING_FLAT_TOP,
53    RDSP_WINDOW_HANNING,
54    RDSP_WINDOW_HANNING_FLAT_TOP,
55};
56
57template <typename T>
58static void fillRectangular(T &v) {
59    const size_t size = v.size();
60    for (size_t i = 0; i < size; i++) {
61        v[i] = 1.0;
62    }
63} //rectangular
64
65template <typename T>
66static void fillTriangular(T &v, size_t overlap) {
67    const size_t size = v.size();
68    //ramp up
69    size_t i = 0;
70    if (overlap > 0) {
71        for (; i < overlap; i++) {
72            v[i] = (2.0 * i + 1) / (2 * overlap);
73        }
74    }
75
76    //flat top
77    for (; i < size - overlap; i++) {
78        v[i] = 1.0;
79    }
80
81    //ramp down
82    if (overlap > 0) {
83        for (; i < size; i++) {
84            v[i] = (2.0 * (size - i) - 1) / (2 * overlap);
85        }
86    }
87} //triangular
88
89template <typename T>
90static void fillHamming(T &v, size_t overlap) {
91    const size_t size = v.size();
92    const size_t twoOverlap = 2 * overlap;
93    size_t i = 0;
94    if (overlap > 0) {
95        for (; i < overlap; i++) {
96            v[i] = 0.54 - 0.46 * cos(TWOPI * i /(twoOverlap - 1));
97        }
98    }
99
100    //flat top
101    for (; i < size - overlap; i++) {
102        v[i] = 1.0;
103    }
104
105    //ramp down
106    if (overlap > 0) {
107        for (; i < size; i++) {
108            int k = i - ((int)size - 2 * overlap);
109            v[i] = 0.54 - 0.46 * cos(TWOPI * k / (twoOverlap - 1));
110        }
111    }
112} //hamming
113
114template <typename T>
115static void fillHanning(T &v, size_t overlap) {
116    const size_t size = v.size();
117    const size_t twoOverlap = 2 * overlap;
118    //ramp up
119    size_t i = 0;
120    if (overlap > 0) {
121        for (; i < overlap; i++) {
122            v[i] = 0.5 * (1.0 - cos(TWOPI * i / (twoOverlap - 1)));
123        }
124    }
125
126    //flat top
127    for (; i < size - overlap; i++) {
128        v[i] = 1.0;
129    }
130
131    //ramp down
132    if (overlap > 0) {
133        for (; i < size; i++) {
134            int k = i - ((int)size - 2 * overlap);
135            v[i] = 0.5 * (1.0 - cos(TWOPI * k / (twoOverlap - 1)));
136        }
137    }
138}
139
140template <typename T>
141static void fill_window(T &v, int type, size_t size, size_t overlap) {
142    if (overlap > size / 2) {
143        overlap = size / 2;
144    }
145    v.resize(size);
146
147    switch (type) {
148    case RDSP_WINDOW_RECTANGULAR:
149        fillRectangular(v);
150        break;
151    case RDSP_WINDOW_TRIANGULAR:
152        fillTriangular(v, size / 2);
153        break;
154    case RDSP_WINDOW_TRIANGULAR_FLAT_TOP:
155        fillTriangular(v, overlap);
156        break;
157    case RDSP_WINDOW_HAMMING:
158        fillHamming(v, size / 2);
159        break;
160    case RDSP_WINDOW_HAMMING_FLAT_TOP:
161        fillHamming(v, overlap);
162        break;
163    case RDSP_WINDOW_HANNING:
164        fillHanning(v, size / 2);
165        break;
166    case RDSP_WINDOW_HANNING_FLAT_TOP:
167        fillHanning(v, overlap);
168        break;
169    default:
170        ALOGE("Error: unknown window type %d", type);
171    }
172}
173
174//};
175#endif //RDSP_H
176