AudioResamplerCubic.cpp revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdint.h> 18#include <string.h> 19#include <sys/types.h> 20#include <cutils/log.h> 21 22#include "AudioResampler.h" 23#include "AudioResamplerCubic.h" 24 25#define LOG_TAG "AudioSRC" 26 27namespace android { 28// ---------------------------------------------------------------------------- 29 30void AudioResamplerCubic::init() { 31 memset(&left, 0, sizeof(state)); 32 memset(&right, 0, sizeof(state)); 33} 34 35void AudioResamplerCubic::resample(int32_t* out, size_t outFrameCount, 36 AudioBufferProvider* provider) { 37 38 // should never happen, but we overflow if it does 39 // LOG_ASSERT(outFrameCount < 32767); 40 41 // select the appropriate resampler 42 switch (mChannelCount) { 43 case 1: 44 resampleMono16(out, outFrameCount, provider); 45 break; 46 case 2: 47 resampleStereo16(out, outFrameCount, provider); 48 break; 49 } 50} 51 52void AudioResamplerCubic::resampleStereo16(int32_t* out, size_t outFrameCount, 53 AudioBufferProvider* provider) { 54 55 int32_t vl = mVolume[0]; 56 int32_t vr = mVolume[1]; 57 58 size_t inputIndex = mInputIndex; 59 uint32_t phaseFraction = mPhaseFraction; 60 uint32_t phaseIncrement = mPhaseIncrement; 61 size_t outputIndex = 0; 62 size_t outputSampleCount = outFrameCount * 2; 63 64 // fetch first buffer 65 if (mBuffer.raw == NULL) { 66 provider->getNextBuffer(&mBuffer); 67 if (mBuffer.raw == NULL) 68 return; 69 // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount); 70 } 71 int16_t *in = mBuffer.i16; 72 73 while (outputIndex < outputSampleCount) { 74 int32_t sample; 75 int32_t x; 76 77 // calculate output sample 78 x = phaseFraction >> kPreInterpShift; 79 out[outputIndex++] += vl * interp(&left, x); 80 out[outputIndex++] += vr * interp(&right, x); 81 // out[outputIndex++] += vr * in[inputIndex*2]; 82 83 // increment phase 84 phaseFraction += phaseIncrement; 85 uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits); 86 phaseFraction &= kPhaseMask; 87 88 // time to fetch another sample 89 while (indexIncrement--) { 90 91 inputIndex++; 92 if (inputIndex == mBuffer.frameCount) { 93 inputIndex = 0; 94 provider->releaseBuffer(&mBuffer); 95 provider->getNextBuffer(&mBuffer); 96 if (mBuffer.raw == NULL) 97 goto save_state; // ugly, but efficient 98 in = mBuffer.i16; 99 // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount); 100 } 101 102 // advance sample state 103 advance(&left, in[inputIndex*2]); 104 advance(&right, in[inputIndex*2+1]); 105 } 106 } 107 108save_state: 109 // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction); 110 mInputIndex = inputIndex; 111 mPhaseFraction = phaseFraction; 112} 113 114void AudioResamplerCubic::resampleMono16(int32_t* out, size_t outFrameCount, 115 AudioBufferProvider* provider) { 116 117 int32_t vl = mVolume[0]; 118 int32_t vr = mVolume[1]; 119 120 size_t inputIndex = mInputIndex; 121 uint32_t phaseFraction = mPhaseFraction; 122 uint32_t phaseIncrement = mPhaseIncrement; 123 size_t outputIndex = 0; 124 size_t outputSampleCount = outFrameCount * 2; 125 126 // fetch first buffer 127 if (mBuffer.raw == NULL) { 128 provider->getNextBuffer(&mBuffer); 129 if (mBuffer.raw == NULL) 130 return; 131 // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount); 132 } 133 int16_t *in = mBuffer.i16; 134 135 while (outputIndex < outputSampleCount) { 136 int32_t sample; 137 int32_t x; 138 139 // calculate output sample 140 x = phaseFraction >> kPreInterpShift; 141 sample = interp(&left, x); 142 out[outputIndex++] += vl * sample; 143 out[outputIndex++] += vr * sample; 144 145 // increment phase 146 phaseFraction += phaseIncrement; 147 uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits); 148 phaseFraction &= kPhaseMask; 149 150 // time to fetch another sample 151 while (indexIncrement--) { 152 153 inputIndex++; 154 if (inputIndex == mBuffer.frameCount) { 155 inputIndex = 0; 156 provider->releaseBuffer(&mBuffer); 157 provider->getNextBuffer(&mBuffer); 158 if (mBuffer.raw == NULL) 159 goto save_state; // ugly, but efficient 160 // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount); 161 in = mBuffer.i16; 162 } 163 164 // advance sample state 165 advance(&left, in[inputIndex]); 166 } 167 } 168 169save_state: 170 // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction); 171 mInputIndex = inputIndex; 172 mPhaseFraction = phaseFraction; 173} 174 175// ---------------------------------------------------------------------------- 176} 177; // namespace android 178 179