Home | History | Annotate | Download | only in dsp
      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>
     24 using FloatVec = std::vector<float>;
     25 using IntVec = std::vector<int>;
     26 using ComplexVec  = std::vector<std::complex<float>>;
     27 
     28 // =======
     29 // Helper Functions
     30 // =======
     31 template <class T>
     32 static T dBtoLinear(T valueDb) {
     33     return pow (10, valueDb / 20.0);
     34 }
     35 
     36 template <class T>
     37 static 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 
     47 enum 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 
     57 template <typename T>
     58 static 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 
     65 template <typename T>
     66 static 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 
     89 template <typename T>
     90 static 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 
    114 template <typename T>
    115 static 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 
    140 template <typename T>
    141 static 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