Home | History | Annotate | Download | only in testlibs
      1 /* //device/servers/AudioFlinger/AudioCoefInterpolator.cpp
      2  **
      3  ** Copyright 2008, The Android Open Source Project
      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 
     18 #include <string.h>
     19 
     20 #include <cutils/compiler.h>
     21 
     22 #include "AudioCoefInterpolator.h"
     23 
     24 namespace android {
     25 
     26 AudioCoefInterpolator::AudioCoefInterpolator(size_t nInDims,
     27                                              const size_t inDims[],
     28                                              size_t nOutDims,
     29                                              const audio_coef_t * table) {
     30     mNumInDims = nInDims;
     31     memcpy(mInDims, inDims, nInDims * sizeof(size_t));
     32     mNumOutDims = nOutDims;
     33     mTable = table;
     34     // Initialize offsets array
     35     size_t dim = nInDims - 1;
     36     mInDimOffsets[nInDims - 1] = nOutDims;
     37     while (dim-- > 0) {
     38         mInDimOffsets[dim] = mInDimOffsets[dim + 1] * mInDims[dim + 1];
     39     }
     40 }
     41 
     42 void AudioCoefInterpolator::getCoef(const int intCoord[], uint32_t fracCoord[],
     43                                     audio_coef_t out[]) {
     44     size_t index = 0;
     45     size_t dim = mNumInDims;
     46     while (dim-- > 0) {
     47         if (CC_UNLIKELY(intCoord[dim] < 0)) {
     48             fracCoord[dim] = 0;
     49         } else if (CC_UNLIKELY(intCoord[dim] >= (int)mInDims[dim] - 1)) {
     50             fracCoord[dim] = 0;
     51             index += mInDimOffsets[dim] * (mInDims[dim] - 1);
     52         } else {
     53             index += mInDimOffsets[dim] * intCoord[dim];
     54         }
     55     }
     56     getCoefRecurse(index, fracCoord, out, 0);
     57 }
     58 
     59 void AudioCoefInterpolator::getCoefRecurse(size_t index,
     60                                            const uint32_t fracCoord[],
     61                                            audio_coef_t out[], size_t dim) {
     62     if (dim == mNumInDims) {
     63         memcpy(out, mTable + index, mNumOutDims * sizeof(audio_coef_t));
     64     } else {
     65         getCoefRecurse(index, fracCoord, out, dim + 1);
     66         if (CC_LIKELY(fracCoord != 0)) {
     67            audio_coef_t tempCoef[MAX_OUT_DIMS];
     68            getCoefRecurse(index + mInDimOffsets[dim], fracCoord, tempCoef,
     69                            dim + 1);
     70             size_t d = mNumOutDims;
     71             while (d-- > 0) {
     72                 out[d] = interp(out[d], tempCoef[d], fracCoord[dim]);
     73             }
     74         }
     75     }
     76 }
     77 
     78 audio_coef_t AudioCoefInterpolator::interp(audio_coef_t lo, audio_coef_t hi,
     79                                            uint32_t frac) {
     80     int64_t delta = static_cast<int64_t>(hi-lo) * frac;
     81     return lo + static_cast<audio_coef_t> (delta >> 32);
     82 }
     83 
     84 }
     85