1*05767d91SRobert Wu /* 2*05767d91SRobert Wu * Copyright 2015 The Android Open Source Project 3*05767d91SRobert Wu * 4*05767d91SRobert Wu * Licensed under the Apache License, Version 2.0 (the "License"); 5*05767d91SRobert Wu * you may not use this file except in compliance with the License. 6*05767d91SRobert Wu * You may obtain a copy of the License at 7*05767d91SRobert Wu * 8*05767d91SRobert Wu * http://www.apache.org/licenses/LICENSE-2.0 9*05767d91SRobert Wu * 10*05767d91SRobert Wu * Unless required by applicable law or agreed to in writing, software 11*05767d91SRobert Wu * distributed under the License is distributed on an "AS IS" BASIS, 12*05767d91SRobert Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*05767d91SRobert Wu * See the License for the specific language governing permissions and 14*05767d91SRobert Wu * limitations under the License. 15*05767d91SRobert Wu */ 16*05767d91SRobert Wu 17*05767d91SRobert Wu #ifndef OBOE_AUDIO_STREAM_OPENSL_ES_H_ 18*05767d91SRobert Wu #define OBOE_AUDIO_STREAM_OPENSL_ES_H_ 19*05767d91SRobert Wu 20*05767d91SRobert Wu #include <memory> 21*05767d91SRobert Wu 22*05767d91SRobert Wu #include <SLES/OpenSLES.h> 23*05767d91SRobert Wu #include <SLES/OpenSLES_Android.h> 24*05767d91SRobert Wu 25*05767d91SRobert Wu #include "oboe/Oboe.h" 26*05767d91SRobert Wu #include "common/MonotonicCounter.h" 27*05767d91SRobert Wu #include "opensles/AudioStreamBuffered.h" 28*05767d91SRobert Wu #include "opensles/EngineOpenSLES.h" 29*05767d91SRobert Wu 30*05767d91SRobert Wu namespace oboe { 31*05767d91SRobert Wu 32*05767d91SRobert Wu constexpr int kBitsPerByte = 8; 33*05767d91SRobert Wu constexpr int kBufferQueueLengthDefault = 2; // double buffered for callbacks 34*05767d91SRobert Wu constexpr int kBufferQueueLengthMax = 8; // AudioFlinger won't use more than 8 35*05767d91SRobert Wu 36*05767d91SRobert Wu /** 37*05767d91SRobert Wu * INTERNAL USE ONLY 38*05767d91SRobert Wu * 39*05767d91SRobert Wu * A stream that wraps OpenSL ES. 40*05767d91SRobert Wu * 41*05767d91SRobert Wu * Do not instantiate this class directly. 42*05767d91SRobert Wu * Use an OboeStreamBuilder to create one. 43*05767d91SRobert Wu */ 44*05767d91SRobert Wu 45*05767d91SRobert Wu class AudioStreamOpenSLES : public AudioStreamBuffered { 46*05767d91SRobert Wu public: 47*05767d91SRobert Wu 48*05767d91SRobert Wu AudioStreamOpenSLES(); 49*05767d91SRobert Wu explicit AudioStreamOpenSLES(const AudioStreamBuilder &builder); 50*05767d91SRobert Wu 51*05767d91SRobert Wu virtual ~AudioStreamOpenSLES() = default; 52*05767d91SRobert Wu 53*05767d91SRobert Wu virtual Result open() override; 54*05767d91SRobert Wu 55*05767d91SRobert Wu /** 56*05767d91SRobert Wu * Query the current state, eg. OBOE_STREAM_STATE_PAUSING 57*05767d91SRobert Wu * 58*05767d91SRobert Wu * @return state or a negative error. 59*05767d91SRobert Wu */ getState()60*05767d91SRobert Wu StreamState getState() override { return mState.load(); } 61*05767d91SRobert Wu getAudioApi()62*05767d91SRobert Wu AudioApi getAudioApi() const override { 63*05767d91SRobert Wu return AudioApi::OpenSLES; 64*05767d91SRobert Wu } 65*05767d91SRobert Wu 66*05767d91SRobert Wu /** 67*05767d91SRobert Wu * Process next OpenSL ES buffer. 68*05767d91SRobert Wu * Called by by OpenSL ES framework. 69*05767d91SRobert Wu * 70*05767d91SRobert Wu * This is public, but don't call it directly. 71*05767d91SRobert Wu * 72*05767d91SRobert Wu * @return whether the current stream should be stopped. 73*05767d91SRobert Wu */ 74*05767d91SRobert Wu bool processBufferCallback(SLAndroidSimpleBufferQueueItf bq); 75*05767d91SRobert Wu 76*05767d91SRobert Wu Result waitForStateChange(StreamState currentState, 77*05767d91SRobert Wu StreamState *nextState, 78*05767d91SRobert Wu int64_t timeoutNanoseconds) override; 79*05767d91SRobert Wu 80*05767d91SRobert Wu protected: 81*05767d91SRobert Wu 82*05767d91SRobert Wu /** 83*05767d91SRobert Wu * Finish setting up the stream. Common for INPUT and OUTPUT. 84*05767d91SRobert Wu * 85*05767d91SRobert Wu * @param configItf 86*05767d91SRobert Wu * @return SL_RESULT_SUCCESS if OK. 87*05767d91SRobert Wu */ 88*05767d91SRobert Wu SLresult finishCommonOpen(SLAndroidConfigurationItf configItf); 89*05767d91SRobert Wu 90*05767d91SRobert Wu // This must be called under mLock. 91*05767d91SRobert Wu Result close_l(); 92*05767d91SRobert Wu 93*05767d91SRobert Wu SLuint32 channelCountToChannelMaskDefault(int channelCount) const; 94*05767d91SRobert Wu onBeforeDestroy()95*05767d91SRobert Wu virtual Result onBeforeDestroy() { return Result::OK; } onAfterDestroy()96*05767d91SRobert Wu virtual Result onAfterDestroy() { return Result::OK; } 97*05767d91SRobert Wu 98*05767d91SRobert Wu static SLuint32 getDefaultByteOrder(); 99*05767d91SRobert Wu 100*05767d91SRobert Wu int32_t getBufferDepth(SLAndroidSimpleBufferQueueItf bq); 101*05767d91SRobert Wu 102*05767d91SRobert Wu int32_t calculateOptimalBufferQueueLength(); 103*05767d91SRobert Wu int32_t estimateNativeFramesPerBurst(); 104*05767d91SRobert Wu 105*05767d91SRobert Wu SLresult enqueueCallbackBuffer(SLAndroidSimpleBufferQueueItf bq); 106*05767d91SRobert Wu 107*05767d91SRobert Wu SLresult configurePerformanceMode(SLAndroidConfigurationItf configItf); 108*05767d91SRobert Wu 109*05767d91SRobert Wu PerformanceMode convertPerformanceMode(SLuint32 openslMode) const; 110*05767d91SRobert Wu SLuint32 convertPerformanceMode(PerformanceMode oboeMode) const; 111*05767d91SRobert Wu 112*05767d91SRobert Wu void logUnsupportedAttributes(); 113*05767d91SRobert Wu 114*05767d91SRobert Wu /** 115*05767d91SRobert Wu * Internal use only. 116*05767d91SRobert Wu * Use this instead of directly setting the internal state variable. 117*05767d91SRobert Wu */ setState(StreamState state)118*05767d91SRobert Wu void setState(StreamState state) { 119*05767d91SRobert Wu mState.store(state); 120*05767d91SRobert Wu } 121*05767d91SRobert Wu 122*05767d91SRobert Wu int64_t getFramesProcessedByServer(); 123*05767d91SRobert Wu 124*05767d91SRobert Wu // OpenSLES stuff 125*05767d91SRobert Wu SLObjectItf mObjectInterface = nullptr; 126*05767d91SRobert Wu SLAndroidSimpleBufferQueueItf mSimpleBufferQueueInterface = nullptr; 127*05767d91SRobert Wu int mBufferQueueLength = 0; 128*05767d91SRobert Wu 129*05767d91SRobert Wu int32_t mBytesPerCallback = oboe::kUnspecified; 130*05767d91SRobert Wu MonotonicCounter mPositionMillis; // for tracking OpenSL ES service position 131*05767d91SRobert Wu 132*05767d91SRobert Wu private: 133*05767d91SRobert Wu 134*05767d91SRobert Wu constexpr static int kDoubleBufferCount = 2; 135*05767d91SRobert Wu 136*05767d91SRobert Wu SLresult registerBufferQueueCallback(); 137*05767d91SRobert Wu SLresult updateStreamParameters(SLAndroidConfigurationItf configItf); 138*05767d91SRobert Wu Result configureBufferSizes(int32_t sampleRate); 139*05767d91SRobert Wu 140*05767d91SRobert Wu std::unique_ptr<uint8_t[]> mCallbackBuffer[kBufferQueueLengthMax]; 141*05767d91SRobert Wu int mCallbackBufferIndex = 0; 142*05767d91SRobert Wu std::atomic<StreamState> mState{StreamState::Uninitialized}; 143*05767d91SRobert Wu 144*05767d91SRobert Wu }; 145*05767d91SRobert Wu 146*05767d91SRobert Wu } // namespace oboe 147*05767d91SRobert Wu 148*05767d91SRobert Wu #endif // OBOE_AUDIO_STREAM_OPENSL_ES_H_ 149