1 /*
2 * Copyright 2017 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 #include "common/OboeDebug.h"
18 #include "EngineOpenSLES.h"
19 #include "OpenSLESUtilities.h"
20
21 using namespace oboe;
22
getInstance()23 EngineOpenSLES &EngineOpenSLES::getInstance() {
24 static EngineOpenSLES sInstance;
25 return sInstance;
26 }
27
open()28 SLresult EngineOpenSLES::open() {
29 std::lock_guard<std::mutex> lock(mLock);
30
31 SLresult result = SL_RESULT_SUCCESS;
32 if (mOpenCount++ == 0) {
33
34 // create engine
35 result = slCreateEngine(&mEngineObject, 0, NULL, 0, NULL, NULL);
36 if (SL_RESULT_SUCCESS != result) {
37 LOGE("EngineOpenSLES - slCreateEngine() result:%s", getSLErrStr(result));
38 goto error;
39 }
40
41 // realize the engine
42 result = (*mEngineObject)->Realize(mEngineObject, SL_BOOLEAN_FALSE);
43 if (SL_RESULT_SUCCESS != result) {
44 LOGE("EngineOpenSLES - Realize() engine result:%s", getSLErrStr(result));
45 goto error;
46 }
47
48 // get the engine interface, which is needed in order to create other objects
49 result = (*mEngineObject)->GetInterface(mEngineObject, SL_IID_ENGINE, &mEngineInterface);
50 if (SL_RESULT_SUCCESS != result) {
51 LOGE("EngineOpenSLES - GetInterface() engine result:%s", getSLErrStr(result));
52 goto error;
53 }
54 }
55
56 return result;
57
58 error:
59 close();
60 return result;
61 }
62
close()63 void EngineOpenSLES::close() {
64 std::lock_guard<std::mutex> lock(mLock);
65 if (--mOpenCount == 0) {
66 if (mEngineObject != nullptr) {
67 (*mEngineObject)->Destroy(mEngineObject);
68 mEngineObject = nullptr;
69 mEngineInterface = nullptr;
70 }
71 }
72 }
73
createOutputMix(SLObjectItf * objectItf)74 SLresult EngineOpenSLES::createOutputMix(SLObjectItf *objectItf) {
75 return (*mEngineInterface)->CreateOutputMix(mEngineInterface, objectItf, 0, 0, 0);
76 }
77
createAudioPlayer(SLObjectItf * objectItf,SLDataSource * audioSource,SLDataSink * audioSink)78 SLresult EngineOpenSLES::createAudioPlayer(SLObjectItf *objectItf,
79 SLDataSource *audioSource,
80 SLDataSink *audioSink) {
81
82 const SLInterfaceID ids[] = {SL_IID_BUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION};
83 const SLboolean reqs[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
84
85 return (*mEngineInterface)->CreateAudioPlayer(mEngineInterface, objectItf, audioSource,
86 audioSink,
87 sizeof(ids) / sizeof(ids[0]), ids, reqs);
88 }
89
createAudioRecorder(SLObjectItf * objectItf,SLDataSource * audioSource,SLDataSink * audioSink)90 SLresult EngineOpenSLES::createAudioRecorder(SLObjectItf *objectItf,
91 SLDataSource *audioSource,
92 SLDataSink *audioSink) {
93
94 const SLInterfaceID ids[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION };
95 const SLboolean reqs[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
96
97 return (*mEngineInterface)->CreateAudioRecorder(mEngineInterface, objectItf, audioSource,
98 audioSink,
99 sizeof(ids) / sizeof(ids[0]), ids, reqs);
100 }
101
102