/* //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);
}

}
