xref: /aosp_15_r20/external/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp (revision 05767d913155b055644481607e6fa1e35e2fe72c)
1*05767d91SRobert Wu /*
2*05767d91SRobert Wu  * Copyright 2017 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 #include <cassert>
18*05767d91SRobert Wu 
19*05767d91SRobert Wu #include <SLES/OpenSLES.h>
20*05767d91SRobert Wu #include <SLES/OpenSLES_Android.h>
21*05767d91SRobert Wu #include <common/AudioClock.h>
22*05767d91SRobert Wu 
23*05767d91SRobert Wu #include "common/OboeDebug.h"
24*05767d91SRobert Wu #include "oboe/AudioStreamBuilder.h"
25*05767d91SRobert Wu #include "AudioOutputStreamOpenSLES.h"
26*05767d91SRobert Wu #include "AudioStreamOpenSLES.h"
27*05767d91SRobert Wu #include "OpenSLESUtilities.h"
28*05767d91SRobert Wu #include "OutputMixerOpenSLES.h"
29*05767d91SRobert Wu 
30*05767d91SRobert Wu using namespace oboe;
31*05767d91SRobert Wu 
OpenSLES_convertOutputUsage(Usage oboeUsage)32*05767d91SRobert Wu static SLuint32 OpenSLES_convertOutputUsage(Usage oboeUsage) {
33*05767d91SRobert Wu     SLuint32 openslStream;
34*05767d91SRobert Wu     switch(oboeUsage) {
35*05767d91SRobert Wu         case Usage::Media:
36*05767d91SRobert Wu         case Usage::Game:
37*05767d91SRobert Wu             openslStream = SL_ANDROID_STREAM_MEDIA;
38*05767d91SRobert Wu             break;
39*05767d91SRobert Wu         case Usage::VoiceCommunication:
40*05767d91SRobert Wu         case Usage::VoiceCommunicationSignalling:
41*05767d91SRobert Wu             openslStream = SL_ANDROID_STREAM_VOICE;
42*05767d91SRobert Wu             break;
43*05767d91SRobert Wu         case Usage::Alarm:
44*05767d91SRobert Wu             openslStream = SL_ANDROID_STREAM_ALARM;
45*05767d91SRobert Wu             break;
46*05767d91SRobert Wu         case Usage::Notification:
47*05767d91SRobert Wu         case Usage::NotificationEvent:
48*05767d91SRobert Wu             openslStream = SL_ANDROID_STREAM_NOTIFICATION;
49*05767d91SRobert Wu             break;
50*05767d91SRobert Wu         case Usage::NotificationRingtone:
51*05767d91SRobert Wu             openslStream = SL_ANDROID_STREAM_RING;
52*05767d91SRobert Wu             break;
53*05767d91SRobert Wu         case Usage::AssistanceAccessibility:
54*05767d91SRobert Wu         case Usage::AssistanceNavigationGuidance:
55*05767d91SRobert Wu         case Usage::AssistanceSonification:
56*05767d91SRobert Wu         case Usage::Assistant:
57*05767d91SRobert Wu         default:
58*05767d91SRobert Wu             openslStream = SL_ANDROID_STREAM_SYSTEM;
59*05767d91SRobert Wu             break;
60*05767d91SRobert Wu     }
61*05767d91SRobert Wu     return openslStream;
62*05767d91SRobert Wu }
63*05767d91SRobert Wu 
AudioOutputStreamOpenSLES(const AudioStreamBuilder & builder)64*05767d91SRobert Wu AudioOutputStreamOpenSLES::AudioOutputStreamOpenSLES(const AudioStreamBuilder &builder)
65*05767d91SRobert Wu         : AudioStreamOpenSLES(builder) {
66*05767d91SRobert Wu }
67*05767d91SRobert Wu 
68*05767d91SRobert Wu // These will wind up in <SLES/OpenSLES_Android.h>
69*05767d91SRobert Wu constexpr int SL_ANDROID_SPEAKER_STEREO = (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT);
70*05767d91SRobert Wu 
71*05767d91SRobert Wu constexpr int SL_ANDROID_SPEAKER_QUAD = (SL_ANDROID_SPEAKER_STEREO
72*05767d91SRobert Wu         | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT);
73*05767d91SRobert Wu 
74*05767d91SRobert Wu constexpr int SL_ANDROID_SPEAKER_5DOT1 = (SL_ANDROID_SPEAKER_QUAD
75*05767d91SRobert Wu         | SL_SPEAKER_FRONT_CENTER  | SL_SPEAKER_LOW_FREQUENCY);
76*05767d91SRobert Wu 
77*05767d91SRobert Wu constexpr int SL_ANDROID_SPEAKER_7DOT1 = (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT
78*05767d91SRobert Wu         | SL_SPEAKER_SIDE_RIGHT);
79*05767d91SRobert Wu 
channelCountToChannelMask(int channelCount) const80*05767d91SRobert Wu SLuint32 AudioOutputStreamOpenSLES::channelCountToChannelMask(int channelCount) const {
81*05767d91SRobert Wu     SLuint32 channelMask = 0;
82*05767d91SRobert Wu 
83*05767d91SRobert Wu     switch (channelCount) {
84*05767d91SRobert Wu         case  1:
85*05767d91SRobert Wu             channelMask = SL_SPEAKER_FRONT_CENTER;
86*05767d91SRobert Wu             break;
87*05767d91SRobert Wu 
88*05767d91SRobert Wu         case  2:
89*05767d91SRobert Wu             channelMask = SL_ANDROID_SPEAKER_STEREO;
90*05767d91SRobert Wu             break;
91*05767d91SRobert Wu 
92*05767d91SRobert Wu         case  4: // Quad
93*05767d91SRobert Wu             channelMask = SL_ANDROID_SPEAKER_QUAD;
94*05767d91SRobert Wu             break;
95*05767d91SRobert Wu 
96*05767d91SRobert Wu         case  6: // 5.1
97*05767d91SRobert Wu             channelMask = SL_ANDROID_SPEAKER_5DOT1;
98*05767d91SRobert Wu             break;
99*05767d91SRobert Wu 
100*05767d91SRobert Wu         case  8: // 7.1
101*05767d91SRobert Wu             channelMask = SL_ANDROID_SPEAKER_7DOT1;
102*05767d91SRobert Wu             break;
103*05767d91SRobert Wu 
104*05767d91SRobert Wu         default:
105*05767d91SRobert Wu             channelMask = channelCountToChannelMaskDefault(channelCount);
106*05767d91SRobert Wu             break;
107*05767d91SRobert Wu     }
108*05767d91SRobert Wu     return channelMask;
109*05767d91SRobert Wu }
110*05767d91SRobert Wu 
open()111*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::open() {
112*05767d91SRobert Wu     logUnsupportedAttributes();
113*05767d91SRobert Wu 
114*05767d91SRobert Wu     SLAndroidConfigurationItf configItf = nullptr;
115*05767d91SRobert Wu 
116*05767d91SRobert Wu 
117*05767d91SRobert Wu     if (getSdkVersion() < __ANDROID_API_L__ && mFormat == AudioFormat::Float){
118*05767d91SRobert Wu         // TODO: Allow floating point format on API <21 using float->int16 converter
119*05767d91SRobert Wu         return Result::ErrorInvalidFormat;
120*05767d91SRobert Wu     }
121*05767d91SRobert Wu 
122*05767d91SRobert Wu     // If audio format is unspecified then choose a suitable default.
123*05767d91SRobert Wu     // API 21+: FLOAT
124*05767d91SRobert Wu     // API <21: INT16
125*05767d91SRobert Wu     if (mFormat == AudioFormat::Unspecified){
126*05767d91SRobert Wu         mFormat = (getSdkVersion() < __ANDROID_API_L__) ?
127*05767d91SRobert Wu                   AudioFormat::I16 : AudioFormat::Float;
128*05767d91SRobert Wu     }
129*05767d91SRobert Wu 
130*05767d91SRobert Wu     Result oboeResult = AudioStreamOpenSLES::open();
131*05767d91SRobert Wu     if (Result::OK != oboeResult)  return oboeResult;
132*05767d91SRobert Wu 
133*05767d91SRobert Wu     SLresult result = OutputMixerOpenSL::getInstance().open();
134*05767d91SRobert Wu     if (SL_RESULT_SUCCESS != result) {
135*05767d91SRobert Wu         AudioStreamOpenSLES::close();
136*05767d91SRobert Wu         return Result::ErrorInternal;
137*05767d91SRobert Wu     }
138*05767d91SRobert Wu 
139*05767d91SRobert Wu     SLuint32 bitsPerSample = static_cast<SLuint32>(getBytesPerSample() * kBitsPerByte);
140*05767d91SRobert Wu 
141*05767d91SRobert Wu     // configure audio source
142*05767d91SRobert Wu     mBufferQueueLength = calculateOptimalBufferQueueLength();
143*05767d91SRobert Wu     SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
144*05767d91SRobert Wu             SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,    // locatorType
145*05767d91SRobert Wu             static_cast<SLuint32>(mBufferQueueLength)};   // numBuffers
146*05767d91SRobert Wu 
147*05767d91SRobert Wu     // Define the audio data format.
148*05767d91SRobert Wu     SLDataFormat_PCM format_pcm = {
149*05767d91SRobert Wu             SL_DATAFORMAT_PCM,       // formatType
150*05767d91SRobert Wu             static_cast<SLuint32>(mChannelCount),           // numChannels
151*05767d91SRobert Wu             static_cast<SLuint32>(mSampleRate * kMillisPerSecond),    // milliSamplesPerSec
152*05767d91SRobert Wu             bitsPerSample,                      // bitsPerSample
153*05767d91SRobert Wu             bitsPerSample,                      // containerSize;
154*05767d91SRobert Wu             channelCountToChannelMask(mChannelCount), // channelMask
155*05767d91SRobert Wu             getDefaultByteOrder(),
156*05767d91SRobert Wu     };
157*05767d91SRobert Wu 
158*05767d91SRobert Wu     SLDataSource audioSrc = {&loc_bufq, &format_pcm};
159*05767d91SRobert Wu 
160*05767d91SRobert Wu     /**
161*05767d91SRobert Wu      * API 21 (Lollipop) introduced support for floating-point data representation and an extended
162*05767d91SRobert Wu      * data format type: SLAndroidDataFormat_PCM_EX. If running on API 21+ use this newer format
163*05767d91SRobert Wu      * type, creating it from our original format.
164*05767d91SRobert Wu      */
165*05767d91SRobert Wu     SLAndroidDataFormat_PCM_EX format_pcm_ex;
166*05767d91SRobert Wu     if (getSdkVersion() >= __ANDROID_API_L__) {
167*05767d91SRobert Wu         SLuint32 representation = OpenSLES_ConvertFormatToRepresentation(getFormat());
168*05767d91SRobert Wu         // Fill in the format structure.
169*05767d91SRobert Wu         format_pcm_ex = OpenSLES_createExtendedFormat(format_pcm, representation);
170*05767d91SRobert Wu         // Use in place of the previous format.
171*05767d91SRobert Wu         audioSrc.pFormat = &format_pcm_ex;
172*05767d91SRobert Wu     }
173*05767d91SRobert Wu 
174*05767d91SRobert Wu     result = OutputMixerOpenSL::getInstance().createAudioPlayer(&mObjectInterface,
175*05767d91SRobert Wu                                                                           &audioSrc);
176*05767d91SRobert Wu     if (SL_RESULT_SUCCESS != result) {
177*05767d91SRobert Wu         LOGE("createAudioPlayer() result:%s", getSLErrStr(result));
178*05767d91SRobert Wu         goto error;
179*05767d91SRobert Wu     }
180*05767d91SRobert Wu 
181*05767d91SRobert Wu     // Configure the stream.
182*05767d91SRobert Wu     result = (*mObjectInterface)->GetInterface(mObjectInterface,
183*05767d91SRobert Wu                                                SL_IID_ANDROIDCONFIGURATION,
184*05767d91SRobert Wu                                                (void *)&configItf);
185*05767d91SRobert Wu     if (SL_RESULT_SUCCESS != result) {
186*05767d91SRobert Wu         LOGW("%s() GetInterface(SL_IID_ANDROIDCONFIGURATION) failed with %s",
187*05767d91SRobert Wu              __func__, getSLErrStr(result));
188*05767d91SRobert Wu     } else {
189*05767d91SRobert Wu         result = configurePerformanceMode(configItf);
190*05767d91SRobert Wu         if (SL_RESULT_SUCCESS != result) {
191*05767d91SRobert Wu             goto error;
192*05767d91SRobert Wu         }
193*05767d91SRobert Wu 
194*05767d91SRobert Wu         SLuint32 presetValue = OpenSLES_convertOutputUsage(getUsage());
195*05767d91SRobert Wu         result = (*configItf)->SetConfiguration(configItf,
196*05767d91SRobert Wu                                                 SL_ANDROID_KEY_STREAM_TYPE,
197*05767d91SRobert Wu                                                 &presetValue,
198*05767d91SRobert Wu                                                 sizeof(presetValue));
199*05767d91SRobert Wu         if (SL_RESULT_SUCCESS != result) {
200*05767d91SRobert Wu             goto error;
201*05767d91SRobert Wu         }
202*05767d91SRobert Wu     }
203*05767d91SRobert Wu 
204*05767d91SRobert Wu     result = (*mObjectInterface)->Realize(mObjectInterface, SL_BOOLEAN_FALSE);
205*05767d91SRobert Wu     if (SL_RESULT_SUCCESS != result) {
206*05767d91SRobert Wu         LOGE("Realize player object result:%s", getSLErrStr(result));
207*05767d91SRobert Wu         goto error;
208*05767d91SRobert Wu     }
209*05767d91SRobert Wu 
210*05767d91SRobert Wu     result = (*mObjectInterface)->GetInterface(mObjectInterface, SL_IID_PLAY, &mPlayInterface);
211*05767d91SRobert Wu     if (SL_RESULT_SUCCESS != result) {
212*05767d91SRobert Wu         LOGE("GetInterface PLAY result:%s", getSLErrStr(result));
213*05767d91SRobert Wu         goto error;
214*05767d91SRobert Wu     }
215*05767d91SRobert Wu 
216*05767d91SRobert Wu     result = finishCommonOpen(configItf);
217*05767d91SRobert Wu     if (SL_RESULT_SUCCESS != result) {
218*05767d91SRobert Wu         goto error;
219*05767d91SRobert Wu     }
220*05767d91SRobert Wu 
221*05767d91SRobert Wu     setState(StreamState::Open);
222*05767d91SRobert Wu     return Result::OK;
223*05767d91SRobert Wu 
224*05767d91SRobert Wu error:
225*05767d91SRobert Wu     close();  // Clean up various OpenSL objects and prevent resource leaks.
226*05767d91SRobert Wu     return Result::ErrorInternal; // TODO convert error from SLES to OBOE
227*05767d91SRobert Wu }
228*05767d91SRobert Wu 
onAfterDestroy()229*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::onAfterDestroy() {
230*05767d91SRobert Wu     OutputMixerOpenSL::getInstance().close();
231*05767d91SRobert Wu     return Result::OK;
232*05767d91SRobert Wu }
233*05767d91SRobert Wu 
close()234*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::close() {
235*05767d91SRobert Wu     LOGD("AudioOutputStreamOpenSLES::%s()", __func__);
236*05767d91SRobert Wu     std::lock_guard<std::mutex> lock(mLock);
237*05767d91SRobert Wu     Result result = Result::OK;
238*05767d91SRobert Wu     if (getState() == StreamState::Closed){
239*05767d91SRobert Wu         result = Result::ErrorClosed;
240*05767d91SRobert Wu     } else {
241*05767d91SRobert Wu         (void) requestPause_l();
242*05767d91SRobert Wu         if (OboeGlobals::areWorkaroundsEnabled()) {
243*05767d91SRobert Wu             sleepBeforeClose();
244*05767d91SRobert Wu         }
245*05767d91SRobert Wu         // invalidate any interfaces
246*05767d91SRobert Wu         mPlayInterface = nullptr;
247*05767d91SRobert Wu         result = AudioStreamOpenSLES::close_l();
248*05767d91SRobert Wu     }
249*05767d91SRobert Wu     return result;
250*05767d91SRobert Wu }
251*05767d91SRobert Wu 
setPlayState_l(SLuint32 newState)252*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::setPlayState_l(SLuint32 newState) {
253*05767d91SRobert Wu 
254*05767d91SRobert Wu     LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__);
255*05767d91SRobert Wu     Result result = Result::OK;
256*05767d91SRobert Wu 
257*05767d91SRobert Wu     if (mPlayInterface == nullptr){
258*05767d91SRobert Wu         LOGE("AudioOutputStreamOpenSLES::%s() mPlayInterface is null", __func__);
259*05767d91SRobert Wu         return Result::ErrorInvalidState;
260*05767d91SRobert Wu     }
261*05767d91SRobert Wu 
262*05767d91SRobert Wu     SLresult slResult = (*mPlayInterface)->SetPlayState(mPlayInterface, newState);
263*05767d91SRobert Wu     if (SL_RESULT_SUCCESS != slResult) {
264*05767d91SRobert Wu         LOGW("AudioOutputStreamOpenSLES(): %s() returned %s", __func__, getSLErrStr(slResult));
265*05767d91SRobert Wu         result = Result::ErrorInternal; // TODO convert slResult to Result::Error
266*05767d91SRobert Wu     }
267*05767d91SRobert Wu     return result;
268*05767d91SRobert Wu }
269*05767d91SRobert Wu 
requestStart()270*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::requestStart() {
271*05767d91SRobert Wu     LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__);
272*05767d91SRobert Wu 
273*05767d91SRobert Wu     mLock.lock();
274*05767d91SRobert Wu     StreamState initialState = getState();
275*05767d91SRobert Wu     switch (initialState) {
276*05767d91SRobert Wu         case StreamState::Starting:
277*05767d91SRobert Wu         case StreamState::Started:
278*05767d91SRobert Wu             mLock.unlock();
279*05767d91SRobert Wu             return Result::OK;
280*05767d91SRobert Wu         case StreamState::Closed:
281*05767d91SRobert Wu             mLock.unlock();
282*05767d91SRobert Wu             return Result::ErrorClosed;
283*05767d91SRobert Wu         default:
284*05767d91SRobert Wu             break;
285*05767d91SRobert Wu     }
286*05767d91SRobert Wu 
287*05767d91SRobert Wu     // We use a callback if the user requests one
288*05767d91SRobert Wu     // OR if we have an internal callback to read the blocking IO buffer.
289*05767d91SRobert Wu     setDataCallbackEnabled(true);
290*05767d91SRobert Wu 
291*05767d91SRobert Wu     setState(StreamState::Starting);
292*05767d91SRobert Wu     closePerformanceHint();
293*05767d91SRobert Wu 
294*05767d91SRobert Wu     if (getBufferDepth(mSimpleBufferQueueInterface) == 0) {
295*05767d91SRobert Wu         // Enqueue the first buffer if needed to start the streaming.
296*05767d91SRobert Wu         // We may need to stop the current stream.
297*05767d91SRobert Wu         bool shouldStopStream = processBufferCallback(mSimpleBufferQueueInterface);
298*05767d91SRobert Wu         if (shouldStopStream) {
299*05767d91SRobert Wu             LOGD("Stopping the current stream.");
300*05767d91SRobert Wu             if (requestStop_l() != Result::OK) {
301*05767d91SRobert Wu                 LOGW("Failed to flush the stream. Error %s", convertToText(flush()));
302*05767d91SRobert Wu             }
303*05767d91SRobert Wu             setState(initialState);
304*05767d91SRobert Wu             mLock.unlock();
305*05767d91SRobert Wu             return Result::ErrorClosed;
306*05767d91SRobert Wu         }
307*05767d91SRobert Wu     }
308*05767d91SRobert Wu 
309*05767d91SRobert Wu     Result result = setPlayState_l(SL_PLAYSTATE_PLAYING);
310*05767d91SRobert Wu     if (result == Result::OK) {
311*05767d91SRobert Wu         setState(StreamState::Started);
312*05767d91SRobert Wu         mLock.unlock();
313*05767d91SRobert Wu     } else {
314*05767d91SRobert Wu         setState(initialState);
315*05767d91SRobert Wu         mLock.unlock();
316*05767d91SRobert Wu     }
317*05767d91SRobert Wu     return result;
318*05767d91SRobert Wu }
319*05767d91SRobert Wu 
requestPause()320*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::requestPause() {
321*05767d91SRobert Wu     LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__);
322*05767d91SRobert Wu     std::lock_guard<std::mutex> lock(mLock);
323*05767d91SRobert Wu     return requestPause_l();
324*05767d91SRobert Wu }
325*05767d91SRobert Wu 
326*05767d91SRobert Wu // Call under mLock
requestPause_l()327*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::requestPause_l() {
328*05767d91SRobert Wu     StreamState initialState = getState();
329*05767d91SRobert Wu     switch (initialState) {
330*05767d91SRobert Wu         case StreamState::Pausing:
331*05767d91SRobert Wu         case StreamState::Paused:
332*05767d91SRobert Wu             return Result::OK;
333*05767d91SRobert Wu         case StreamState::Uninitialized:
334*05767d91SRobert Wu         case StreamState::Closed:
335*05767d91SRobert Wu             return Result::ErrorClosed;
336*05767d91SRobert Wu         default:
337*05767d91SRobert Wu             break;
338*05767d91SRobert Wu     }
339*05767d91SRobert Wu 
340*05767d91SRobert Wu     setState(StreamState::Pausing);
341*05767d91SRobert Wu     Result result = setPlayState_l(SL_PLAYSTATE_PAUSED);
342*05767d91SRobert Wu     if (result == Result::OK) {
343*05767d91SRobert Wu         // Note that OpenSL ES does NOT reset its millisecond position when OUTPUT is paused.
344*05767d91SRobert Wu         int64_t framesWritten = getFramesWritten();
345*05767d91SRobert Wu         if (framesWritten >= 0) {
346*05767d91SRobert Wu             setFramesRead(framesWritten);
347*05767d91SRobert Wu         }
348*05767d91SRobert Wu         setState(StreamState::Paused);
349*05767d91SRobert Wu     } else {
350*05767d91SRobert Wu         setState(initialState);
351*05767d91SRobert Wu     }
352*05767d91SRobert Wu     return result;
353*05767d91SRobert Wu }
354*05767d91SRobert Wu 
355*05767d91SRobert Wu /**
356*05767d91SRobert Wu  * Flush/clear the queue buffers
357*05767d91SRobert Wu  */
requestFlush()358*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::requestFlush() {
359*05767d91SRobert Wu     std::lock_guard<std::mutex> lock(mLock);
360*05767d91SRobert Wu     return requestFlush_l();
361*05767d91SRobert Wu }
362*05767d91SRobert Wu 
requestFlush_l()363*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::requestFlush_l() {
364*05767d91SRobert Wu     LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__);
365*05767d91SRobert Wu     if (getState() == StreamState::Closed) {
366*05767d91SRobert Wu         return Result::ErrorClosed;
367*05767d91SRobert Wu     }
368*05767d91SRobert Wu 
369*05767d91SRobert Wu     Result result = Result::OK;
370*05767d91SRobert Wu     if (mPlayInterface == nullptr || mSimpleBufferQueueInterface == nullptr) {
371*05767d91SRobert Wu         result = Result::ErrorInvalidState;
372*05767d91SRobert Wu     } else {
373*05767d91SRobert Wu         SLresult slResult = (*mSimpleBufferQueueInterface)->Clear(mSimpleBufferQueueInterface);
374*05767d91SRobert Wu         if (slResult != SL_RESULT_SUCCESS){
375*05767d91SRobert Wu             LOGW("Failed to clear buffer queue. OpenSLES error: %s", getSLErrStr(slResult));
376*05767d91SRobert Wu             result = Result::ErrorInternal;
377*05767d91SRobert Wu         }
378*05767d91SRobert Wu     }
379*05767d91SRobert Wu     return result;
380*05767d91SRobert Wu }
381*05767d91SRobert Wu 
requestStop()382*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::requestStop() {
383*05767d91SRobert Wu     std::lock_guard<std::mutex> lock(mLock);
384*05767d91SRobert Wu     return requestStop_l();
385*05767d91SRobert Wu }
386*05767d91SRobert Wu 
requestStop_l()387*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::requestStop_l() {
388*05767d91SRobert Wu     LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__);
389*05767d91SRobert Wu 
390*05767d91SRobert Wu     StreamState initialState = getState();
391*05767d91SRobert Wu     switch (initialState) {
392*05767d91SRobert Wu         case StreamState::Stopping:
393*05767d91SRobert Wu         case StreamState::Stopped:
394*05767d91SRobert Wu             return Result::OK;
395*05767d91SRobert Wu         case StreamState::Uninitialized:
396*05767d91SRobert Wu         case StreamState::Closed:
397*05767d91SRobert Wu             return Result::ErrorClosed;
398*05767d91SRobert Wu         default:
399*05767d91SRobert Wu             break;
400*05767d91SRobert Wu     }
401*05767d91SRobert Wu 
402*05767d91SRobert Wu     setState(StreamState::Stopping);
403*05767d91SRobert Wu 
404*05767d91SRobert Wu     Result result = setPlayState_l(SL_PLAYSTATE_STOPPED);
405*05767d91SRobert Wu     if (result == Result::OK) {
406*05767d91SRobert Wu 
407*05767d91SRobert Wu         // Also clear the buffer queue so the old data won't be played if the stream is restarted.
408*05767d91SRobert Wu         // Call the _l function that expects to already be under a lock.
409*05767d91SRobert Wu         if (requestFlush_l() != Result::OK) {
410*05767d91SRobert Wu             LOGW("Failed to flush the stream. Error %s", convertToText(flush()));
411*05767d91SRobert Wu         }
412*05767d91SRobert Wu 
413*05767d91SRobert Wu         mPositionMillis.reset32(); // OpenSL ES resets its millisecond position when stopped.
414*05767d91SRobert Wu         int64_t framesWritten = getFramesWritten();
415*05767d91SRobert Wu         if (framesWritten >= 0) {
416*05767d91SRobert Wu             setFramesRead(framesWritten);
417*05767d91SRobert Wu         }
418*05767d91SRobert Wu         setState(StreamState::Stopped);
419*05767d91SRobert Wu     } else {
420*05767d91SRobert Wu         setState(initialState);
421*05767d91SRobert Wu     }
422*05767d91SRobert Wu     return result;
423*05767d91SRobert Wu }
424*05767d91SRobert Wu 
setFramesRead(int64_t framesRead)425*05767d91SRobert Wu void AudioOutputStreamOpenSLES::setFramesRead(int64_t framesRead) {
426*05767d91SRobert Wu     int64_t millisWritten = framesRead * kMillisPerSecond / getSampleRate();
427*05767d91SRobert Wu     mPositionMillis.set(millisWritten);
428*05767d91SRobert Wu }
429*05767d91SRobert Wu 
updateFramesRead()430*05767d91SRobert Wu void AudioOutputStreamOpenSLES::updateFramesRead() {
431*05767d91SRobert Wu     if (usingFIFO()) {
432*05767d91SRobert Wu         AudioStreamBuffered::updateFramesRead();
433*05767d91SRobert Wu     } else {
434*05767d91SRobert Wu         mFramesRead = getFramesProcessedByServer();
435*05767d91SRobert Wu     }
436*05767d91SRobert Wu }
437*05767d91SRobert Wu 
updateServiceFrameCounter()438*05767d91SRobert Wu Result AudioOutputStreamOpenSLES::updateServiceFrameCounter() {
439*05767d91SRobert Wu     Result result = Result::OK;
440*05767d91SRobert Wu     // Avoid deadlock if another thread is trying to stop or close this stream
441*05767d91SRobert Wu     // and this is being called from a callback.
442*05767d91SRobert Wu     if (mLock.try_lock()) {
443*05767d91SRobert Wu 
444*05767d91SRobert Wu         if (mPlayInterface == nullptr) {
445*05767d91SRobert Wu             mLock.unlock();
446*05767d91SRobert Wu             return Result::ErrorNull;
447*05767d91SRobert Wu         }
448*05767d91SRobert Wu         SLmillisecond msec = 0;
449*05767d91SRobert Wu         SLresult slResult = (*mPlayInterface)->GetPosition(mPlayInterface, &msec);
450*05767d91SRobert Wu         if (SL_RESULT_SUCCESS != slResult) {
451*05767d91SRobert Wu             LOGW("%s(): GetPosition() returned %s", __func__, getSLErrStr(slResult));
452*05767d91SRobert Wu             // set result based on SLresult
453*05767d91SRobert Wu             result = Result::ErrorInternal;
454*05767d91SRobert Wu         } else {
455*05767d91SRobert Wu             mPositionMillis.update32(msec);
456*05767d91SRobert Wu         }
457*05767d91SRobert Wu         mLock.unlock();
458*05767d91SRobert Wu     }
459*05767d91SRobert Wu     return result;
460*05767d91SRobert Wu }
461