xref: /aosp_15_r20/cts/apps/CtsVerifier/jni/megaaudio/common/OboeStream.cpp (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1*b7c941bbSAndroid Build Coastguard Worker /*
2*b7c941bbSAndroid Build Coastguard Worker  * Copyright 2020 The Android Open Source Project
3*b7c941bbSAndroid Build Coastguard Worker  *
4*b7c941bbSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*b7c941bbSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*b7c941bbSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*b7c941bbSAndroid Build Coastguard Worker  *
8*b7c941bbSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*b7c941bbSAndroid Build Coastguard Worker  *
10*b7c941bbSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*b7c941bbSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*b7c941bbSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b7c941bbSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*b7c941bbSAndroid Build Coastguard Worker  * limitations under the License.
15*b7c941bbSAndroid Build Coastguard Worker  */
16*b7c941bbSAndroid Build Coastguard Worker #include <android/log.h>
17*b7c941bbSAndroid Build Coastguard Worker 
18*b7c941bbSAndroid Build Coastguard Worker #include <oboe/Oboe.h>
19*b7c941bbSAndroid Build Coastguard Worker 
20*b7c941bbSAndroid Build Coastguard Worker #include "OboeStream.h"
21*b7c941bbSAndroid Build Coastguard Worker 
22*b7c941bbSAndroid Build Coastguard Worker static const char * const TAG = "OboeStream(native)";
23*b7c941bbSAndroid Build Coastguard Worker 
24*b7c941bbSAndroid Build Coastguard Worker using namespace oboe;
25*b7c941bbSAndroid Build Coastguard Worker 
OboeErrorToMegaAudioError(oboe::Result oboeError)26*b7c941bbSAndroid Build Coastguard Worker StreamBase::Result OboeStream::OboeErrorToMegaAudioError(oboe::Result oboeError) {
27*b7c941bbSAndroid Build Coastguard Worker 
28*b7c941bbSAndroid Build Coastguard Worker     StreamBase::Result maErr = ERROR_UNKNOWN;
29*b7c941bbSAndroid Build Coastguard Worker 
30*b7c941bbSAndroid Build Coastguard Worker     switch (oboeError) {
31*b7c941bbSAndroid Build Coastguard Worker         case oboe::Result::OK:
32*b7c941bbSAndroid Build Coastguard Worker             maErr = OK;
33*b7c941bbSAndroid Build Coastguard Worker             break;
34*b7c941bbSAndroid Build Coastguard Worker         case oboe::Result::ErrorInternal:
35*b7c941bbSAndroid Build Coastguard Worker             maErr = ERROR_UNKNOWN;
36*b7c941bbSAndroid Build Coastguard Worker             break;
37*b7c941bbSAndroid Build Coastguard Worker         case oboe::Result::ErrorClosed:
38*b7c941bbSAndroid Build Coastguard Worker             maErr = ERROR_INVALID_STATE;
39*b7c941bbSAndroid Build Coastguard Worker             break;
40*b7c941bbSAndroid Build Coastguard Worker         default:
41*b7c941bbSAndroid Build Coastguard Worker             maErr = ERROR_UNKNOWN;
42*b7c941bbSAndroid Build Coastguard Worker             break;
43*b7c941bbSAndroid Build Coastguard Worker     }
44*b7c941bbSAndroid Build Coastguard Worker 
45*b7c941bbSAndroid Build Coastguard Worker     return maErr;
46*b7c941bbSAndroid Build Coastguard Worker }
47*b7c941bbSAndroid Build Coastguard Worker 
teardownStream()48*b7c941bbSAndroid Build Coastguard Worker StreamBase::Result OboeStream::teardownStream() {
49*b7c941bbSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mStreamLock);
50*b7c941bbSAndroid Build Coastguard Worker     return teardownStream_l();
51*b7c941bbSAndroid Build Coastguard Worker }
52*b7c941bbSAndroid Build Coastguard Worker 
teardownStream_l()53*b7c941bbSAndroid Build Coastguard Worker StreamBase::Result OboeStream::teardownStream_l() {
54*b7c941bbSAndroid Build Coastguard Worker     // tear down the player
55*b7c941bbSAndroid Build Coastguard Worker     if (mAudioStream == nullptr) {
56*b7c941bbSAndroid Build Coastguard Worker         return ERROR_INVALID_STATE;
57*b7c941bbSAndroid Build Coastguard Worker     } else {
58*b7c941bbSAndroid Build Coastguard Worker         oboe::Result result = oboe::Result::OK;
59*b7c941bbSAndroid Build Coastguard Worker         result = mAudioStream->stop();
60*b7c941bbSAndroid Build Coastguard Worker         if (result == oboe::Result::OK) {
61*b7c941bbSAndroid Build Coastguard Worker             result = mAudioStream->close();
62*b7c941bbSAndroid Build Coastguard Worker         }
63*b7c941bbSAndroid Build Coastguard Worker         mAudioStream = nullptr;
64*b7c941bbSAndroid Build Coastguard Worker         return OboeErrorToMegaAudioError(result);
65*b7c941bbSAndroid Build Coastguard Worker     }
66*b7c941bbSAndroid Build Coastguard Worker }
67*b7c941bbSAndroid Build Coastguard Worker 
startStream()68*b7c941bbSAndroid Build Coastguard Worker StreamBase::Result OboeStream::startStream() {
69*b7c941bbSAndroid Build Coastguard Worker     // Don't cover up (potential) bugs in AAudio
70*b7c941bbSAndroid Build Coastguard Worker     oboe::OboeGlobals::setWorkaroundsEnabled(false);
71*b7c941bbSAndroid Build Coastguard Worker 
72*b7c941bbSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mStreamLock);
73*b7c941bbSAndroid Build Coastguard Worker 
74*b7c941bbSAndroid Build Coastguard Worker     oboe::Result result = oboe::Result::ErrorInternal;
75*b7c941bbSAndroid Build Coastguard Worker     if (mAudioStream != nullptr) {
76*b7c941bbSAndroid Build Coastguard Worker         result = mAudioStream->requestStart();
77*b7c941bbSAndroid Build Coastguard Worker         if (result != oboe::Result::OK){
78*b7c941bbSAndroid Build Coastguard Worker             __android_log_print(
79*b7c941bbSAndroid Build Coastguard Worker                     ANDROID_LOG_ERROR,
80*b7c941bbSAndroid Build Coastguard Worker                     TAG,
81*b7c941bbSAndroid Build Coastguard Worker                     "requestStart failed. Error: %s", convertToText(result));
82*b7c941bbSAndroid Build Coastguard Worker 
83*b7c941bbSAndroid Build Coastguard Worker             // clean up
84*b7c941bbSAndroid Build Coastguard Worker             teardownStream_l();
85*b7c941bbSAndroid Build Coastguard Worker         }
86*b7c941bbSAndroid Build Coastguard Worker     }
87*b7c941bbSAndroid Build Coastguard Worker     mStreamStarted = result == oboe::Result::OK;
88*b7c941bbSAndroid Build Coastguard Worker 
89*b7c941bbSAndroid Build Coastguard Worker     return OboeErrorToMegaAudioError(result);
90*b7c941bbSAndroid Build Coastguard Worker }
91*b7c941bbSAndroid Build Coastguard Worker 
stopStream()92*b7c941bbSAndroid Build Coastguard Worker StreamBase::Result OboeStream::stopStream() {
93*b7c941bbSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mStreamLock);
94*b7c941bbSAndroid Build Coastguard Worker 
95*b7c941bbSAndroid Build Coastguard Worker     Result errCode = ERROR_UNKNOWN;
96*b7c941bbSAndroid Build Coastguard Worker     if (mAudioStream == nullptr) {
97*b7c941bbSAndroid Build Coastguard Worker         errCode = ERROR_INVALID_STATE;
98*b7c941bbSAndroid Build Coastguard Worker     } else {
99*b7c941bbSAndroid Build Coastguard Worker         oboe::Result result = mAudioStream->stop();
100*b7c941bbSAndroid Build Coastguard Worker         mStreamStarted = false;
101*b7c941bbSAndroid Build Coastguard Worker 
102*b7c941bbSAndroid Build Coastguard Worker         errCode = OboeErrorToMegaAudioError(result);
103*b7c941bbSAndroid Build Coastguard Worker     }
104*b7c941bbSAndroid Build Coastguard Worker 
105*b7c941bbSAndroid Build Coastguard Worker     mStreamStarted = false;
106*b7c941bbSAndroid Build Coastguard Worker     return errCode;
107*b7c941bbSAndroid Build Coastguard Worker }
108*b7c941bbSAndroid Build Coastguard Worker 
getTimeStamp(oboe::FrameTimestamp * timeStamp)109*b7c941bbSAndroid Build Coastguard Worker StreamBase::Result OboeStream::getTimeStamp(oboe::FrameTimestamp* timeStamp) {
110*b7c941bbSAndroid Build Coastguard Worker     Result errCode = ERROR_UNKNOWN;
111*b7c941bbSAndroid Build Coastguard Worker     if (mAudioStream == nullptr) {
112*b7c941bbSAndroid Build Coastguard Worker         __android_log_print(ANDROID_LOG_ERROR, TAG, "ERROR_INVALID_STATE");
113*b7c941bbSAndroid Build Coastguard Worker         errCode = ERROR_INVALID_STATE;
114*b7c941bbSAndroid Build Coastguard Worker     } else {
115*b7c941bbSAndroid Build Coastguard Worker         ResultWithValue<oboe::FrameTimestamp> result = mAudioStream->getTimestamp(CLOCK_MONOTONIC);
116*b7c941bbSAndroid Build Coastguard Worker 
117*b7c941bbSAndroid Build Coastguard Worker         *timeStamp = result.value();
118*b7c941bbSAndroid Build Coastguard Worker 
119*b7c941bbSAndroid Build Coastguard Worker         errCode = OK;
120*b7c941bbSAndroid Build Coastguard Worker     }
121*b7c941bbSAndroid Build Coastguard Worker 
122*b7c941bbSAndroid Build Coastguard Worker     return errCode;
123*b7c941bbSAndroid Build Coastguard Worker }
124*b7c941bbSAndroid Build Coastguard Worker 
getState() const125*b7c941bbSAndroid Build Coastguard Worker oboe::StreamState OboeStream::getState() const {
126*b7c941bbSAndroid Build Coastguard Worker     return mAudioStream != nullptr ? mAudioStream->getState() : oboe::StreamState::Unknown;
127*b7c941bbSAndroid Build Coastguard Worker }
128*b7c941bbSAndroid Build Coastguard Worker 
getLastErrorCallbackResult()129*b7c941bbSAndroid Build Coastguard Worker int OboeStream::getLastErrorCallbackResult() {
130*b7c941bbSAndroid Build Coastguard Worker     return (int) (mAudioStream != nullptr
131*b7c941bbSAndroid Build Coastguard Worker                     ? (int) mAudioStream->getLastErrorCallbackResult() : StreamBase::ERROR_INVALID_STATE);
132*b7c941bbSAndroid Build Coastguard Worker }
133*b7c941bbSAndroid Build Coastguard Worker 
getRoutedDeviceId()134*b7c941bbSAndroid Build Coastguard Worker int32_t OboeStream::getRoutedDeviceId() {
135*b7c941bbSAndroid Build Coastguard Worker     return (int32_t) (mAudioStream != nullptr
136*b7c941bbSAndroid Build Coastguard Worker                                ? (int32_t) mAudioStream->getDeviceId()
137*b7c941bbSAndroid Build Coastguard Worker                                : ROUTING_DEVICE_NONE);
138*b7c941bbSAndroid Build Coastguard Worker }
139*b7c941bbSAndroid Build Coastguard Worker 
getSharingMode()140*b7c941bbSAndroid Build Coastguard Worker int32_t OboeStream::getSharingMode() {
141*b7c941bbSAndroid Build Coastguard Worker     return (int32_t) (mAudioStream != nullptr
142*b7c941bbSAndroid Build Coastguard Worker                                ? (int32_t) mAudioStream->getSharingMode()
143*b7c941bbSAndroid Build Coastguard Worker                                : SHARING_MODE_INVALID);
144*b7c941bbSAndroid Build Coastguard Worker }
145*b7c941bbSAndroid Build Coastguard Worker 
getChannelCount()146*b7c941bbSAndroid Build Coastguard Worker int32_t OboeStream::getChannelCount() {
147*b7c941bbSAndroid Build Coastguard Worker     return (int32_t) (mAudioStream != nullptr
148*b7c941bbSAndroid Build Coastguard Worker                                ? (int32_t) mAudioStream->getChannelCount()
149*b7c941bbSAndroid Build Coastguard Worker                                : -1);
150*b7c941bbSAndroid Build Coastguard Worker }
151*b7c941bbSAndroid Build Coastguard Worker 
isMMap()152*b7c941bbSAndroid Build Coastguard Worker bool OboeStream::isMMap() {
153*b7c941bbSAndroid Build Coastguard Worker     return OboeExtensions::isMMapUsed(mAudioStream.get());
154*b7c941bbSAndroid Build Coastguard Worker }
155*b7c941bbSAndroid Build Coastguard Worker 
156