1*05767d91SRobert Wu /* 2*05767d91SRobert Wu * Copyright 2018 The Android Open Source Project 3*05767d91SRobert Wu * 4*05767d91SRobert Wu * Licensed under the Apache License, Version 2.0 (the "License"); 5*05767d91SRobert Wu * you may not use this file except in compliance with the License. 6*05767d91SRobert Wu * You may obtain a copy of the License at 7*05767d91SRobert Wu * 8*05767d91SRobert Wu * http://www.apache.org/licenses/LICENSE-2.0 9*05767d91SRobert Wu * 10*05767d91SRobert Wu * Unless required by applicable law or agreed to in writing, software 11*05767d91SRobert Wu * distributed under the License is distributed on an "AS IS" BASIS, 12*05767d91SRobert Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*05767d91SRobert Wu * See the License for the specific language governing permissions and 14*05767d91SRobert Wu * limitations under the License. 15*05767d91SRobert Wu */ 16*05767d91SRobert Wu 17*05767d91SRobert Wu #ifndef SHARED_MIXER_H 18*05767d91SRobert Wu #define SHARED_MIXER_H 19*05767d91SRobert Wu 20*05767d91SRobert Wu #include <array> 21*05767d91SRobert Wu #include "IRenderableAudio.h" 22*05767d91SRobert Wu 23*05767d91SRobert Wu /** 24*05767d91SRobert Wu * A Mixer object which sums the output from multiple tracks into a single output. The number of 25*05767d91SRobert Wu * input channels on each track must match the number of output channels (default 1=mono). This can 26*05767d91SRobert Wu * be changed by calling `setChannelCount`. 27*05767d91SRobert Wu * The inputs to the mixer are not owned by the mixer, they should not be deleted while rendering. 28*05767d91SRobert Wu */ 29*05767d91SRobert Wu class Mixer : public IRenderableAudio { 30*05767d91SRobert Wu 31*05767d91SRobert Wu public: renderAudio(float * audioData,int32_t numFrames)32*05767d91SRobert Wu void renderAudio(float *audioData, int32_t numFrames) { 33*05767d91SRobert Wu 34*05767d91SRobert Wu int numSamples = numFrames * mChannelCount; 35*05767d91SRobert Wu if (numSamples > mBufferSize) { 36*05767d91SRobert Wu mMixingBuffer = std::make_unique<float[]>(numSamples); 37*05767d91SRobert Wu mBufferSize = numSamples; 38*05767d91SRobert Wu } 39*05767d91SRobert Wu 40*05767d91SRobert Wu // Zero out the incoming container array 41*05767d91SRobert Wu memset(audioData, 0, sizeof(float) * numSamples); 42*05767d91SRobert Wu 43*05767d91SRobert Wu for (int i = 0; i < mTracks.size(); ++i) { 44*05767d91SRobert Wu mTracks[i]->renderAudio(mMixingBuffer.get(), numFrames); 45*05767d91SRobert Wu 46*05767d91SRobert Wu for (int j = 0; j < numSamples; ++j) { 47*05767d91SRobert Wu audioData[j] += mMixingBuffer[j]; 48*05767d91SRobert Wu } 49*05767d91SRobert Wu } 50*05767d91SRobert Wu } 51*05767d91SRobert Wu addTrack(IRenderableAudio * renderer)52*05767d91SRobert Wu void addTrack(IRenderableAudio *renderer){ 53*05767d91SRobert Wu mTracks.push_back(renderer); 54*05767d91SRobert Wu } 55*05767d91SRobert Wu setChannelCount(int32_t channelCount)56*05767d91SRobert Wu void setChannelCount(int32_t channelCount){ mChannelCount = channelCount; } 57*05767d91SRobert Wu removeAllTracks()58*05767d91SRobert Wu void removeAllTracks(){ 59*05767d91SRobert Wu mTracks.clear(); 60*05767d91SRobert Wu } 61*05767d91SRobert Wu 62*05767d91SRobert Wu private: 63*05767d91SRobert Wu int32_t mBufferSize = 0; 64*05767d91SRobert Wu std::unique_ptr<float[]> mMixingBuffer; 65*05767d91SRobert Wu std::vector<IRenderableAudio*> mTracks; 66*05767d91SRobert Wu int32_t mChannelCount = 1; // Default to mono 67*05767d91SRobert Wu }; 68*05767d91SRobert Wu 69*05767d91SRobert Wu 70*05767d91SRobert Wu #endif //SHARED_MIXER_H 71