AudioCoefInterpolator.cpp 2.9 KB

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