• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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 LE_FX_ENGINE_DSP_CORE_INTERPOLATOR_BASE_INL_H_
18 #define LE_FX_ENGINE_DSP_CORE_INTERPOLATOR_BASE_INL_H_
19 
20 #include "dsp/core/basic.h"
21 
22 //#define LOG_NDEBUG 0
23 #include <cutils/log.h>
24 
25 
26 namespace le_fx {
27 
28 namespace sigmod {
29 
30 template <typename T, class Algorithm>
InterpolatorBase()31 InterpolatorBase<T, Algorithm>::InterpolatorBase() {
32   status_ = false;
33   cached_index_ = 0;
34   x_data_ = NULL;
35   y_data_ = NULL;
36   data_length_ = 0;
37   own_x_data_ = false;
38   x_start_offset_ = 0.0;
39   last_element_index_ = -1;
40   x_inverse_sampling_interval_ = 0.0;
41   state_ = NULL;
42 }
43 
44 template <typename T, class Algorithm>
~InterpolatorBase()45 InterpolatorBase<T, Algorithm>::~InterpolatorBase() {
46   delete [] state_;
47   if (own_x_data_) {
48     delete [] x_data_;
49   }
50 }
51 
52 template <typename T, class Algorithm>
Initialize(const vector<T> & x_data,const vector<T> & y_data)53 bool InterpolatorBase<T, Algorithm>::Initialize(const vector<T> &x_data,
54                                                 const vector<T> &y_data) {
55 #ifndef NDEBUG
56   if (x_data.size() != y_data.size()) {
57     LoggerError("InterpolatorBase::Initialize: xData size (%d) != yData size"
58                   " (%d)", x_data.size(), y_data.size());
59   }
60 #endif
61   return Initialize(&x_data[0], &y_data[0], x_data.size());
62 }
63 
64 template <typename T, class Algorithm>
Initialize(double x_start_offset,double x_sampling_interval,const vector<T> & y_data)65 bool InterpolatorBase<T, Algorithm>::Initialize(double x_start_offset,
66                                                 double x_sampling_interval,
67                                                 const vector<T> &y_data) {
68   return Initialize(x_start_offset,
69                     x_sampling_interval,
70                     &y_data[0],
71                     y_data.size());
72 }
73 
74 template <typename T, class Algorithm>
Initialize(double x_start_offset,double x_sampling_interval,const T * y_data,int data_length)75 bool InterpolatorBase<T, Algorithm>::Initialize(double x_start_offset,
76                                                 double x_sampling_interval,
77                                                 const T *y_data,
78                                                 int data_length) {
79   // Constructs and populate x-axis data: `x_data_`
80   T *x_data_tmp = new T[data_length];
81   float time_offset = x_start_offset;
82   for (int n = 0; n < data_length; n++) {
83     x_data_tmp[n] = time_offset;
84     time_offset += x_sampling_interval;
85   }
86   Initialize(x_data_tmp, y_data, data_length);
87   // Sets-up the regularly sampled interpolation mode
88   x_start_offset_ = x_start_offset;
89   x_inverse_sampling_interval_ = 1.0 / x_sampling_interval;
90   own_x_data_ = true;
91   return status_;
92 }
93 
94 
95 template <typename T, class Algorithm>
Initialize(const T * x_data,const T * y_data,int data_length)96 bool InterpolatorBase<T, Algorithm>::Initialize(
97     const T *x_data, const T *y_data, int data_length) {
98   // Default settings
99   cached_index_ = 0;
100   data_length_ = 0;
101   x_start_offset_ = 0;
102   x_inverse_sampling_interval_ = 0;
103   state_ = NULL;
104   // Input data is externally owned
105   own_x_data_ = false;
106   x_data_ = x_data;
107   y_data_ = y_data;
108   data_length_ = data_length;
109   last_element_index_ = data_length - 1;
110   // Check input data sanity
111   for (int n = 0; n < last_element_index_; ++n) {
112     if (x_data_[n + 1] <= x_data_[n]) {
113       ALOGE("InterpolatorBase::Initialize: xData are not ordered or "
114               "contain equal values (X[%d] <= X[%d]) (%.5e <= %.5e)",
115               n + 1, n, x_data_[n + 1], x_data_[n]);
116       status_ = false;
117       return false;
118     }
119   }
120   // Pre-compute internal state by calling the corresponding function of the
121   // derived class.
122   status_ = static_cast<Algorithm*>(this)->SetInternalState();
123   return status_;
124 }
125 
126 template <typename T, class Algorithm>
Interpolate(T x)127 T InterpolatorBase<T, Algorithm>::Interpolate(T x) {
128 #ifndef NDEBUG
129   if (cached_index_ < 0 || cached_index_ > data_length_ - 2) {
130     LoggerError("InterpolatorBase:Interpolate: CachedIndex_ out of bounds "
131                   "[0, %d, %d]", cached_index_, data_length_ - 2);
132   }
133 #endif
134   // Search for the containing interval
135   if (x <= x_data_[cached_index_]) {
136     if (cached_index_ <= 0) {
137       cached_index_ = 0;
138       return y_data_[0];
139     }
140     if (x >= x_data_[cached_index_ - 1]) {
141       cached_index_--;  // Fast descending
142     } else {
143       if (x <= x_data_[0]) {
144         cached_index_ = 0;
145         return y_data_[0];
146       }
147       cached_index_ = SearchIndex(x_data_, x, 0, cached_index_);
148     }
149   } else {
150     if (cached_index_ >= last_element_index_) {
151       cached_index_ = last_element_index_;
152       return y_data_[last_element_index_];
153     }
154     if (x > x_data_[cached_index_ + 1]) {
155       if (cached_index_ + 2 > last_element_index_) {
156         cached_index_ = last_element_index_ - 1;
157         return y_data_[last_element_index_];
158       }
159       if (x <= x_data_[cached_index_ + 2]) {
160         cached_index_++;  // Fast ascending
161       } else {
162         if (x >= x_data_[last_element_index_]) {
163           cached_index_ = last_element_index_ - 1;
164           return y_data_[last_element_index_];
165         }
166         cached_index_ = SearchIndex(
167             x_data_, x, cached_index_, last_element_index_);
168       }
169     }
170   }
171   // Compute interpolated value by calling the corresponding function of the
172   // derived class.
173   return static_cast<Algorithm*>(this)->MethodSpecificInterpolation(x);
174 }
175 
176 }  // namespace sigmod
177 
178 }  // namespace le_fx
179 
180 #endif  // LE_FX_ENGINE_DSP_CORE_INTERPOLATOR_BASE_INL_H_
181