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