• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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