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), mCurSampleIndex(0), mIsPlaying(false), mIsLoopMode(false), mGain(1.0f) { 43 setPan(pan); 44 } ~SampleSource()45 virtual ~SampleSource() {} 46 setPlayMode()47 void setPlayMode() { mCurSampleIndex = 0; mIsPlaying = true; } setStopMode()48 void setStopMode() { mIsPlaying = false; mCurSampleIndex = 0; } 49 setLoopMode(bool isLoopMode)50 void setLoopMode(bool isLoopMode) { mIsLoopMode = isLoopMode; } 51 isPlaying()52 bool isPlaying() { return mIsPlaying; } 53 setPan(float pan)54 void setPan(float pan) { 55 if (pan < PAN_HARDLEFT) { 56 mPan = PAN_HARDLEFT; 57 } else if (pan > PAN_HARDRIGHT) { 58 mPan = PAN_HARDRIGHT; 59 } else { 60 mPan = pan; 61 } 62 calcGainFactors(); 63 } 64 getPan()65 float getPan() { 66 return mPan; 67 } 68 setGain(float gain)69 void setGain(float gain) { 70 mGain = gain; 71 calcGainFactors(); 72 } 73 getGain()74 float getGain() { 75 return mGain; 76 } 77 78 protected: 79 SampleBuffer *mSampleBuffer; 80 81 int32_t mCurSampleIndex; 82 83 bool mIsPlaying; 84 std::atomic<bool> mIsLoopMode; 85 86 // Logical pan value 87 float mPan; 88 89 // precomputed channel gains for pan 90 float mLeftGain; 91 float mRightGain; 92 93 // Overall gain 94 float mGain; 95 96 private: calcGainFactors()97 void calcGainFactors() { 98 // useful panning information: http://www.cs.cmu.edu/~music/icm-online/readings/panlaws/ 99 float rightPan = (mPan * 0.5) + 0.5; 100 mRightGain = rightPan * mGain; 101 mLeftGain = (1.0 - rightPan) * mGain; } 102 }; 103 104 } // namespace wavlib 105 106 #endif //_PLAYER_SAMPLESOURCE_ 107