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