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 kBufferQueueLength = 2; // double buffered for callbacks
34 
35 /**
36  * INTERNAL USE ONLY
37  *
38  * A stream that wraps OpenSL ES.
39  *
40  * Do not instantiate this class directly.
41  * Use an OboeStreamBuilder to create one.
42  */
43 
44 class AudioStreamOpenSLES : public AudioStreamBuffered {
45 public:
46 
47     AudioStreamOpenSLES();
48     explicit AudioStreamOpenSLES(const AudioStreamBuilder &builder);
49 
50     virtual ~AudioStreamOpenSLES() = default;
51 
52     virtual Result open() override;
53 
54     /**
55      * Query the current state, eg. OBOE_STREAM_STATE_PAUSING
56      *
57      * @return state or a negative error.
58      */
getState()59     StreamState getState() const override { return mState.load(); }
60 
61     int32_t getFramesPerBurst() override;
62 
63 
getAudioApi()64     AudioApi getAudioApi() const override {
65         return AudioApi::OpenSLES;
66     }
67 
68     /**
69      * Process next OpenSL ES buffer.
70      * Called by by OpenSL ES framework.
71      *
72      * This is public, but don't call it directly.
73      */
74     void processBufferCallback(SLAndroidSimpleBufferQueueItf bq);
75 
76     Result waitForStateChange(StreamState currentState,
77                               StreamState *nextState,
78                               int64_t timeoutNanoseconds) override;
79 
80 protected:
81 
82     // This must be called under mLock.
83     Result close_l();
84 
85     SLuint32 channelCountToChannelMaskDefault(int channelCount) const;
86 
onBeforeDestroy()87     virtual Result onBeforeDestroy() { return Result::OK; }
onAfterDestroy()88     virtual Result onAfterDestroy() { return Result::OK; }
89 
90     static SLuint32 getDefaultByteOrder();
91 
92     SLresult registerBufferQueueCallback();
93 
94     int32_t getBufferDepth(SLAndroidSimpleBufferQueueItf bq);
95 
96     SLresult enqueueCallbackBuffer(SLAndroidSimpleBufferQueueItf bq);
97 
98     SLresult configurePerformanceMode(SLAndroidConfigurationItf configItf);
99 
100     SLresult updateStreamParameters(SLAndroidConfigurationItf configItf);
101 
102     PerformanceMode convertPerformanceMode(SLuint32 openslMode) const;
103     SLuint32 convertPerformanceMode(PerformanceMode oboeMode) const;
104 
105     Result configureBufferSizes(int32_t sampleRate);
106 
107     void logUnsupportedAttributes();
108 
109     /**
110      * Internal use only.
111      * Use this instead of directly setting the internal state variable.
112      */
setState(StreamState state)113     void setState(StreamState state) {
114         mState.store(state);
115     }
116 
117     int64_t getFramesProcessedByServer();
118 
119     // OpenSLES stuff
120     SLObjectItf                   mObjectInterface = nullptr;
121     SLAndroidSimpleBufferQueueItf mSimpleBufferQueueInterface = nullptr;
122 
123     int32_t                       mBytesPerCallback = oboe::kUnspecified;
124     MonotonicCounter              mPositionMillis; // for tracking OpenSL ES service position
125 
126 private:
127     std::unique_ptr<uint8_t[]>    mCallbackBuffer;
128     std::atomic<StreamState>      mState{StreamState::Uninitialized};
129 
130 };
131 
132 } // namespace oboe
133 
134 #endif // OBOE_AUDIO_STREAM_OPENSL_ES_H_
135