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