• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 OBOE_AUDIO_STREAM_OPENSL_ES_H_
18 #define OBOE_AUDIO_STREAM_OPENSL_ES_H_
19 
20 #include <memory>
21 
22 #include "oboe/Oboe.h"
23 #include "common/MonotonicCounter.h"
24 #include "opensles/AudioStreamBuffered.h"
25 #include "opensles/EngineOpenSLES.h"
26 
27 namespace oboe {
28 
29 constexpr int kBitsPerByte = 8;
30 constexpr int kBufferQueueLengthDefault = 2; // double buffered for callbacks
31 constexpr int kBufferQueueLengthMax = 8; // AudioFlinger won't use more than 8
32 
33 /**
34  * INTERNAL USE ONLY
35  *
36  * A stream that wraps OpenSL ES.
37  *
38  * Do not instantiate this class directly.
39  * Use an OboeStreamBuilder to create one.
40  */
41 
42 class AudioStreamOpenSLES : public AudioStreamBuffered {
43 public:
44 
45     AudioStreamOpenSLES();
46     explicit AudioStreamOpenSLES(const AudioStreamBuilder &builder);
47 
48     virtual ~AudioStreamOpenSLES() = default;
49 
50     virtual Result open() override;
51 
52     /**
53      * Query the current state, eg. OBOE_STREAM_STATE_PAUSING
54      *
55      * @return state or a negative error.
56      */
getState()57     StreamState getState() override { return mState.load(); }
58 
getAudioApi()59     AudioApi getAudioApi() const override {
60         return AudioApi::OpenSLES;
61     }
62 
63     /**
64      * Process next OpenSL ES buffer.
65      * Called by by OpenSL ES framework.
66      *
67      * This is public, but don't call it directly.
68      *
69      * @return whether the current stream should be stopped.
70      */
71     bool processBufferCallback(SLAndroidSimpleBufferQueueItf bq);
72 
73     Result waitForStateChange(StreamState currentState,
74                               StreamState *nextState,
75                               int64_t timeoutNanoseconds) override;
76 
77 protected:
78 
79     /**
80      * Finish setting up the stream. Common for INPUT and OUTPUT.
81      *
82      * @param configItf
83      * @return SL_RESULT_SUCCESS if OK.
84      */
85     SLresult finishCommonOpen(SLAndroidConfigurationItf configItf);
86 
87     // This must be called under mLock.
88     Result close_l();
89 
90     SLuint32 channelCountToChannelMaskDefault(int channelCount) const;
91 
onBeforeDestroy()92     virtual Result onBeforeDestroy() { return Result::OK; }
onAfterDestroy()93     virtual Result onAfterDestroy() { return Result::OK; }
94 
95     static SLuint32 getDefaultByteOrder();
96 
97     int32_t getBufferDepth(SLAndroidSimpleBufferQueueItf bq);
98 
99     int32_t calculateOptimalBufferQueueLength();
100     int32_t estimateNativeFramesPerBurst();
101 
102     SLresult enqueueCallbackBuffer(SLAndroidSimpleBufferQueueItf bq);
103 
104     SLresult configurePerformanceMode(SLAndroidConfigurationItf configItf);
105 
106     PerformanceMode convertPerformanceMode(SLuint32 openslMode) const;
107     SLuint32 convertPerformanceMode(PerformanceMode oboeMode) const;
108 
109     void logUnsupportedAttributes();
110 
111     /**
112      * Internal use only.
113      * Use this instead of directly setting the internal state variable.
114      */
setState(StreamState state)115     void setState(StreamState state) {
116         mState.store(state);
117     }
118 
119     int64_t getFramesProcessedByServer();
120 
121     // OpenSLES stuff
122     SLObjectItf                   mObjectInterface = nullptr;
123     SLAndroidSimpleBufferQueueItf mSimpleBufferQueueInterface = nullptr;
124     int                           mBufferQueueLength = 0;
125 
126     int32_t                       mBytesPerCallback = oboe::kUnspecified;
127     MonotonicCounter              mPositionMillis; // for tracking OpenSL ES service position
128 
129 private:
130 
131     constexpr static int kDoubleBufferCount = 2;
132 
133     SLresult registerBufferQueueCallback();
134     SLresult updateStreamParameters(SLAndroidConfigurationItf configItf);
135     Result configureBufferSizes(int32_t sampleRate);
136 
137     std::unique_ptr<uint8_t[]>    mCallbackBuffer[kBufferQueueLengthMax];
138     int                           mCallbackBufferIndex = 0;
139     std::atomic<StreamState>      mState{StreamState::Uninitialized};
140 
141 };
142 
143 } // namespace oboe
144 
145 #endif // OBOE_AUDIO_STREAM_OPENSL_ES_H_
146