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