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