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 "AudioSRC" 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 void 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 resampleMono16(out, outFrameCount, provider); 45 break; 46 case 2: 47 resampleStereo16(out, outFrameCount, provider); 48 break; 49 } 50 } 51 52 void 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 size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate; 64 65 // fetch first buffer 66 if (mBuffer.frameCount == 0) { 67 mBuffer.frameCount = inFrameCount; 68 provider->getNextBuffer(&mBuffer, mPTS); 69 if (mBuffer.raw == NULL) 70 return; 71 // ALOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount); 72 } 73 int16_t *in = mBuffer.i16; 74 75 while (outputIndex < outputSampleCount) { 76 int32_t sample; 77 int32_t x; 78 79 // calculate output sample 80 x = phaseFraction >> kPreInterpShift; 81 out[outputIndex++] += vl * interp(&left, x); 82 out[outputIndex++] += vr * interp(&right, x); 83 // out[outputIndex++] += vr * in[inputIndex*2]; 84 85 // increment phase 86 phaseFraction += phaseIncrement; 87 uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits); 88 phaseFraction &= kPhaseMask; 89 90 // time to fetch another sample 91 while (indexIncrement--) { 92 93 inputIndex++; 94 if (inputIndex == mBuffer.frameCount) { 95 inputIndex = 0; 96 provider->releaseBuffer(&mBuffer); 97 mBuffer.frameCount = inFrameCount; 98 provider->getNextBuffer(&mBuffer, 99 calculateOutputPTS(outputIndex / 2)); 100 if (mBuffer.raw == NULL) 101 goto save_state; // ugly, but efficient 102 in = mBuffer.i16; 103 // ALOGW("New buffer: offset=%p, frames=%d", mBuffer.raw, mBuffer.frameCount); 104 } 105 106 // advance sample state 107 advance(&left, in[inputIndex*2]); 108 advance(&right, in[inputIndex*2+1]); 109 } 110 } 111 112 save_state: 113 // ALOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction); 114 mInputIndex = inputIndex; 115 mPhaseFraction = phaseFraction; 116 } 117 118 void AudioResamplerCubic::resampleMono16(int32_t* out, size_t outFrameCount, 119 AudioBufferProvider* provider) { 120 121 int32_t vl = mVolume[0]; 122 int32_t vr = mVolume[1]; 123 124 size_t inputIndex = mInputIndex; 125 uint32_t phaseFraction = mPhaseFraction; 126 uint32_t phaseIncrement = mPhaseIncrement; 127 size_t outputIndex = 0; 128 size_t outputSampleCount = outFrameCount * 2; 129 size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate; 130 131 // fetch first buffer 132 if (mBuffer.frameCount == 0) { 133 mBuffer.frameCount = inFrameCount; 134 provider->getNextBuffer(&mBuffer, mPTS); 135 if (mBuffer.raw == NULL) 136 return; 137 // ALOGW("New buffer: offset=%p, frames=%d", mBuffer.raw, mBuffer.frameCount); 138 } 139 int16_t *in = mBuffer.i16; 140 141 while (outputIndex < outputSampleCount) { 142 int32_t sample; 143 int32_t x; 144 145 // calculate output sample 146 x = phaseFraction >> kPreInterpShift; 147 sample = interp(&left, x); 148 out[outputIndex++] += vl * sample; 149 out[outputIndex++] += vr * sample; 150 151 // increment phase 152 phaseFraction += phaseIncrement; 153 uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits); 154 phaseFraction &= kPhaseMask; 155 156 // time to fetch another sample 157 while (indexIncrement--) { 158 159 inputIndex++; 160 if (inputIndex == mBuffer.frameCount) { 161 inputIndex = 0; 162 provider->releaseBuffer(&mBuffer); 163 mBuffer.frameCount = inFrameCount; 164 provider->getNextBuffer(&mBuffer, 165 calculateOutputPTS(outputIndex / 2)); 166 if (mBuffer.raw == NULL) 167 goto save_state; // ugly, but efficient 168 // ALOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount); 169 in = mBuffer.i16; 170 } 171 172 // advance sample state 173 advance(&left, in[inputIndex]); 174 } 175 } 176 177 save_state: 178 // ALOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction); 179 mInputIndex = inputIndex; 180 mPhaseFraction = phaseFraction; 181 } 182 183 // ---------------------------------------------------------------------------- 184 } 185 ; // namespace android 186