| /* //device/servers/AudioFlinger/AudioCoefInterpolator.cpp |
| ** |
| ** Copyright 2008, The Android Open Source Project |
| ** |
| ** Licensed under the Apache License, Version 2.0 (the "License"); |
| ** you may not use this file except in compliance with the License. |
| ** You may obtain a copy of the License at |
| ** |
| ** http://www.apache.org/licenses/LICENSE-2.0 |
| ** |
| ** Unless required by applicable law or agreed to in writing, software |
| ** distributed under the License is distributed on an "AS IS" BASIS, |
| ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| ** See the License for the specific language governing permissions and |
| ** limitations under the License. |
| */ |
| |
| #include <string.h> |
| |
| #include <cutils/compiler.h> |
| |
| #include "AudioCoefInterpolator.h" |
| |
| namespace android { |
| |
| AudioCoefInterpolator::AudioCoefInterpolator(size_t nInDims, |
| const size_t inDims[], |
| size_t nOutDims, |
| const audio_coef_t * table) { |
| mNumInDims = nInDims; |
| memcpy(mInDims, inDims, nInDims * sizeof(size_t)); |
| mNumOutDims = nOutDims; |
| mTable = table; |
| // Initialize offsets array |
| size_t dim = nInDims - 1; |
| mInDimOffsets[nInDims - 1] = nOutDims; |
| while (dim-- > 0) { |
| mInDimOffsets[dim] = mInDimOffsets[dim + 1] * mInDims[dim + 1]; |
| } |
| } |
| |
| void AudioCoefInterpolator::getCoef(const int intCoord[], uint32_t fracCoord[], |
| audio_coef_t out[]) { |
| size_t index = 0; |
| size_t dim = mNumInDims; |
| while (dim-- > 0) { |
| if (CC_UNLIKELY(intCoord[dim] < 0)) { |
| fracCoord[dim] = 0; |
| } else if (CC_UNLIKELY(intCoord[dim] >= (int)mInDims[dim] - 1)) { |
| fracCoord[dim] = 0; |
| index += mInDimOffsets[dim] * (mInDims[dim] - 1); |
| } else { |
| index += mInDimOffsets[dim] * intCoord[dim]; |
| } |
| } |
| getCoefRecurse(index, fracCoord, out, 0); |
| } |
| |
| void AudioCoefInterpolator::getCoefRecurse(size_t index, |
| const uint32_t fracCoord[], |
| audio_coef_t out[], size_t dim) { |
| if (dim == mNumInDims) { |
| memcpy(out, mTable + index, mNumOutDims * sizeof(audio_coef_t)); |
| } else { |
| getCoefRecurse(index, fracCoord, out, dim + 1); |
| if (CC_LIKELY(fracCoord != 0)) { |
| audio_coef_t tempCoef[MAX_OUT_DIMS]; |
| getCoefRecurse(index + mInDimOffsets[dim], fracCoord, tempCoef, |
| dim + 1); |
| size_t d = mNumOutDims; |
| while (d-- > 0) { |
| out[d] = interp(out[d], tempCoef[d], fracCoord[dim]); |
| } |
| } |
| } |
| } |
| |
| audio_coef_t AudioCoefInterpolator::interp(audio_coef_t lo, audio_coef_t hi, |
| uint32_t frac) { |
| int64_t delta = static_cast<int64_t>(hi-lo) * frac; |
| return lo + static_cast<audio_coef_t> (delta >> 32); |
| } |
| |
| } |