1 /* 2 * Copyright (C) 2019 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 <string.h> 18 19 #include "wav/WavStreamReader.h" 20 21 #include "OneShotSampleSource.h" 22 23 namespace iolib { 24 mixAudio(float * outBuff,int numChannels,int32_t numFrames)25void OneShotSampleSource::mixAudio(float* outBuff, int numChannels, int32_t numFrames) { 26 int32_t numSamples = mSampleBuffer->getNumSamples(); 27 int32_t sampleChannels = mSampleBuffer->getProperties().channelCount; 28 int32_t totalSamplesNeeded = numFrames * numChannels; // Total samples to fill the output buffer 29 int32_t samplesProcessed = 0; 30 bool isLoopMode = mIsLoopMode; 31 32 while (samplesProcessed < totalSamplesNeeded && mIsPlaying) { 33 int32_t samplesLeft = numSamples - mCurSampleIndex; 34 int32_t framesLeft = (totalSamplesNeeded - samplesProcessed) / numChannels; 35 int32_t numWriteFrames = std::min(framesLeft, samplesLeft / sampleChannels); 36 37 if (numWriteFrames > 0) { 38 const float* data = mSampleBuffer->getSampleData(); 39 if ((sampleChannels == 1) && (numChannels == 1)) { 40 // MONO output from MONO samples 41 for (int32_t frameIndex = 0; frameIndex < numWriteFrames; frameIndex++) { 42 outBuff[samplesProcessed + frameIndex] += data[mCurSampleIndex++] * mGain; 43 } 44 } else if ((sampleChannels == 1) && (numChannels == 2)) { 45 // STEREO output from MONO samples 46 int dstSampleIndex = samplesProcessed; 47 for (int32_t frameIndex = 0; frameIndex < numWriteFrames; frameIndex++) { 48 outBuff[dstSampleIndex++] += data[mCurSampleIndex] * mLeftGain; 49 outBuff[dstSampleIndex++] += data[mCurSampleIndex++] * mRightGain; 50 } 51 } else if ((sampleChannels == 2) && (numChannels == 1)) { 52 // MONO output from STEREO samples 53 int dstSampleIndex = samplesProcessed; 54 for (int32_t frameIndex = 0; frameIndex < numWriteFrames; frameIndex++) { 55 outBuff[dstSampleIndex++] += data[mCurSampleIndex++] * mLeftGain + 56 data[mCurSampleIndex++] * mRightGain; 57 } 58 } else if ((sampleChannels == 2) && (numChannels == 2)) { 59 // STEREO output from STEREO samples 60 int dstSampleIndex = samplesProcessed; 61 for (int32_t frameIndex = 0; frameIndex < numWriteFrames; frameIndex++) { 62 outBuff[dstSampleIndex++] += data[mCurSampleIndex++] * mLeftGain; 63 outBuff[dstSampleIndex++] += data[mCurSampleIndex++] * mRightGain; 64 } 65 } 66 67 samplesProcessed += numWriteFrames * numChannels; 68 69 if (mCurSampleIndex >= numSamples) { 70 if (isLoopMode) { 71 mCurSampleIndex = 0; 72 } else { 73 mIsPlaying = false; 74 } 75 } 76 } else { 77 break; // No more samples to write in the current chunk 78 } 79 } 80 } 81 82 } // namespace wavlib 83