85 lines
3.0 KiB
C++
85 lines
3.0 KiB
C++
/* //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 "AudioCoefInterpolator.h"
|
|
|
|
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
|
|
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
|
|
|
|
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 (UNLIKELY(intCoord[dim] < 0)) {
|
|
fracCoord[dim] = 0;
|
|
} else if (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 (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);
|
|
}
|
|
|
|
}
|