1 /* 2 * Copyright (C) 2020 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 #ifndef _PLAYER_SAMPLESOURCE_ 18 #define _PLAYER_SAMPLESOURCE_ 19 20 #include <cstdint> 21 22 #include "DataSource.h" 23 24 #include "SampleBuffer.h" 25 26 namespace iolib { 27 28 /** 29 * Defines an interface for audio data provided to a player object. 30 * Concrete examples include OneShotSampleBuffer. One could imagine a LoopingSampleBuffer. 31 * Supports stereo position via mPan member. 32 */ 33 class SampleSource: public DataSource { 34 public: 35 // Pan position of the audio in a stereo mix 36 // [left:-1.0f] <- [center: 0.0f] -> -[right: 1.0f] 37 static constexpr float PAN_HARDLEFT = -1.0f; 38 static constexpr float PAN_HARDRIGHT = 1.0f; 39 static constexpr float PAN_CENTER = 0.0f; 40 SampleSource(SampleBuffer * sampleBuffer,float pan)41 SampleSource(SampleBuffer *sampleBuffer, float pan) 42 : mSampleBuffer(sampleBuffer), mCurFrameIndex(0), mIsPlaying(false), mGain(1.0f) { 43 setPan(pan); 44 } ~SampleSource()45 virtual ~SampleSource() {} 46 setPlayMode()47 void setPlayMode() { mCurFrameIndex = 0; mIsPlaying = true; } setStopMode()48 void setStopMode() { mIsPlaying = false; mCurFrameIndex = 0; } 49 isPlaying()50 bool isPlaying() { return mIsPlaying; } 51 setPan(float pan)52 void setPan(float pan) { 53 if (pan < PAN_HARDLEFT) { 54 mPan = PAN_HARDLEFT; 55 } else if (pan > PAN_HARDRIGHT) { 56 mPan = PAN_HARDRIGHT; 57 } else { 58 mPan = pan; 59 } 60 calcGainFactors(); 61 } 62 getPan()63 float getPan() { 64 return mPan; 65 } 66 setGain(float gain)67 void setGain(float gain) { 68 mGain = gain; 69 calcGainFactors(); 70 } 71 getGain()72 float getGain() { 73 return mGain; 74 } 75 76 protected: 77 SampleBuffer *mSampleBuffer; 78 79 int32_t mCurFrameIndex; 80 81 bool mIsPlaying; 82 83 // Logical pan value 84 float mPan; 85 86 // precomputed channel gains for pan 87 float mLeftGain; 88 float mRightGain; 89 90 // Overall gain 91 float mGain; 92 93 private: calcGainFactors()94 void calcGainFactors() { 95 // useful panning information: http://www.cs.cmu.edu/~music/icm-online/readings/panlaws/ 96 float rightPan = (mPan * 0.5) + 0.5; 97 mRightGain = rightPan * mGain; 98 mLeftGain = (1.0 - rightPan) * mGain; } 99 }; 100 101 } // namespace wavlib 102 103 #endif //_PLAYER_SAMPLESOURCE_ 104