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 #define LOG_TAG "AudioResamplerCubic" 18 19 #include <stdint.h> 20 #include <string.h> 21 #include <sys/types.h> 22 #include <cutils/log.h> 23 24 #include "AudioResampler.h" 25 #include "AudioResamplerCubic.h" 26 27 namespace android { 28 // ---------------------------------------------------------------------------- 29 30 void AudioResamplerCubic::init() { 31 memset(&left, 0, sizeof(state)); 32 memset(&right, 0, sizeof(state)); 33 } 34 35 size_t AudioResamplerCubic::resample(int32_t* out, size_t outFrameCount, 36 AudioBufferProvider* provider) { 37 38 // should never happen, but we overflow if it does 39 // ALOG_ASSERT(outFrameCount < 32767); 40 41 // select the appropriate resampler 42 switch (mChannelCount) { 43 case 1: 44 return resampleMono16(out, outFrameCount, provider); 45 case 2: 46 return resampleStereo16(out, outFrameCount, provider); 47 default: 48 LOG_ALWAYS_FATAL("invalid channel count: %d", mChannelCount); 49 return 0; 50 } 51 } 52 53 size_t AudioResamplerCubic::resampleStereo16(int32_t* out, size_t outFrameCount, 54 AudioBufferProvider* provider) { 55 56 int32_t vl = mVolume[0]; 57 int32_t vr = mVolume[1]; 58 59 size_t inputIndex = mInputIndex; 60 uint32_t phaseFraction = mPhaseFraction; 61 uint32_t phaseIncrement = mPhaseIncrement; 62 size_t outputIndex = 0; 63 size_t outputSampleCount = outFrameCount * 2; 64 size_t inFrameCount = getInFrameCountRequired(outFrameCount); 65 66 // fetch first buffer 67 if (mBuffer.frameCount == 0) { 68 mBuffer.frameCount = inFrameCount; 69 provider->getNextBuffer(&mBuffer, mPTS); 70 if (mBuffer.raw == NULL) { 71 return 0; 72 } 73 // ALOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount); 74 } 75 int16_t *in = mBuffer.i16; 76 77 while (outputIndex < outputSampleCount) { 78 int32_t sample; 79 int32_t x; 80 81 // calculate output sample 82 x = phaseFraction >> kPreInterpShift; 83 out[outputIndex++] += vl * interp(&left, x); 84 out[outputIndex++] += vr * interp(&right, x); 85 // out[outputIndex++] += vr * in[inputIndex*2]; 86 87 // increment phase 88 phaseFraction += phaseIncrement; 89 uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits); 90 phaseFraction &= kPhaseMask; 91 92 // time to fetch another sample 93 while (indexIncrement--) { 94 95 inputIndex++; 96 if (inputIndex == mBuffer.frameCount) { 97 inputIndex = 0; 98 provider->releaseBuffer(&mBuffer); 99 mBuffer.frameCount = inFrameCount; 100 provider->getNextBuffer(&mBuffer, 101 calculateOutputPTS(outputIndex / 2)); 102 if (mBuffer.raw == NULL) { 103 goto save_state; // ugly, but efficient 104 } 105 in = mBuffer.i16; 106 // ALOGW("New buffer: offset=%p, frames=%d", mBuffer.raw, mBuffer.frameCount); 107 } 108 109 // advance sample state 110 advance(&left, in[inputIndex*2]); 111 advance(&right, in[inputIndex*2+1]); 112 } 113 } 114 115 save_state: 116 // ALOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction); 117 mInputIndex = inputIndex; 118 mPhaseFraction = phaseFraction; 119 return outputIndex / 2 /* channels for stereo */; 120 } 121 122 size_t AudioResamplerCubic::resampleMono16(int32_t* out, size_t outFrameCount, 123 AudioBufferProvider* provider) { 124 125 int32_t vl = mVolume[0]; 126 int32_t vr = mVolume[1]; 127 128 size_t inputIndex = mInputIndex; 129 uint32_t phaseFraction = mPhaseFraction; 130 uint32_t phaseIncrement = mPhaseIncrement; 131 size_t outputIndex = 0; 132 size_t outputSampleCount = outFrameCount * 2; 133 size_t inFrameCount = getInFrameCountRequired(outFrameCount); 134 135 // fetch first buffer 136 if (mBuffer.frameCount == 0) { 137 mBuffer.frameCount = inFrameCount; 138 provider->getNextBuffer(&mBuffer, mPTS); 139 if (mBuffer.raw == NULL) { 140 return 0; 141 } 142 // ALOGW("New buffer: offset=%p, frames=%d", mBuffer.raw, mBuffer.frameCount); 143 } 144 int16_t *in = mBuffer.i16; 145 146 while (outputIndex < outputSampleCount) { 147 int32_t sample; 148 int32_t x; 149 150 // calculate output sample 151 x = phaseFraction >> kPreInterpShift; 152 sample = interp(&left, x); 153 out[outputIndex++] += vl * sample; 154 out[outputIndex++] += vr * sample; 155 156 // increment phase 157 phaseFraction += phaseIncrement; 158 uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits); 159 phaseFraction &= kPhaseMask; 160 161 // time to fetch another sample 162 while (indexIncrement--) { 163 164 inputIndex++; 165 if (inputIndex == mBuffer.frameCount) { 166 inputIndex = 0; 167 provider->releaseBuffer(&mBuffer); 168 mBuffer.frameCount = inFrameCount; 169 provider->getNextBuffer(&mBuffer, 170 calculateOutputPTS(outputIndex / 2)); 171 if (mBuffer.raw == NULL) { 172 goto save_state; // ugly, but efficient 173 } 174 // ALOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount); 175 in = mBuffer.i16; 176 } 177 178 // advance sample state 179 advance(&left, in[inputIndex]); 180 } 181 } 182 183 save_state: 184 // ALOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction); 185 mInputIndex = inputIndex; 186 mPhaseFraction = phaseFraction; 187 return outputIndex; 188 } 189 190 // ---------------------------------------------------------------------------- 191 } // namespace android 192