1 /* 2 * Copyright 2020 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 #include <android/log.h> 17 18 #include <oboe/Oboe.h> 19 20 #include "OboeStream.h" 21 22 static const char * const TAG = "OboeStream(native)"; 23 24 using namespace oboe; 25 OboeErrorToMegaAudioError(oboe::Result oboeError)26StreamBase::Result OboeStream::OboeErrorToMegaAudioError(oboe::Result oboeError) { 27 28 StreamBase::Result maErr = ERROR_UNKNOWN; 29 30 switch (oboeError) { 31 case oboe::Result::OK: 32 maErr = OK; 33 break; 34 case oboe::Result::ErrorInternal: 35 maErr = ERROR_UNKNOWN; 36 break; 37 case oboe::Result::ErrorClosed: 38 maErr = ERROR_INVALID_STATE; 39 break; 40 default: 41 maErr = ERROR_UNKNOWN; 42 break; 43 } 44 45 return maErr; 46 } 47 teardownStream()48StreamBase::Result OboeStream::teardownStream() { 49 std::lock_guard<std::mutex> lock(mStreamLock); 50 return teardownStream_l(); 51 } 52 teardownStream_l()53StreamBase::Result OboeStream::teardownStream_l() { 54 // tear down the player 55 if (mAudioStream == nullptr) { 56 return ERROR_INVALID_STATE; 57 } else { 58 oboe::Result result = oboe::Result::OK; 59 result = mAudioStream->stop(); 60 if (result == oboe::Result::OK) { 61 result = mAudioStream->close(); 62 } 63 mAudioStream = nullptr; 64 return OboeErrorToMegaAudioError(result); 65 } 66 } 67 startStream()68StreamBase::Result OboeStream::startStream() { 69 // Don't cover up (potential) bugs in AAudio 70 oboe::OboeGlobals::setWorkaroundsEnabled(false); 71 72 std::lock_guard<std::mutex> lock(mStreamLock); 73 74 oboe::Result result = oboe::Result::ErrorInternal; 75 if (mAudioStream != nullptr) { 76 result = mAudioStream->requestStart(); 77 if (result != oboe::Result::OK){ 78 __android_log_print( 79 ANDROID_LOG_ERROR, 80 TAG, 81 "requestStart failed. Error: %s", convertToText(result)); 82 83 // clean up 84 teardownStream_l(); 85 } 86 } 87 mStreamStarted = result == oboe::Result::OK; 88 89 return OboeErrorToMegaAudioError(result); 90 } 91 stopStream()92StreamBase::Result OboeStream::stopStream() { 93 std::lock_guard<std::mutex> lock(mStreamLock); 94 95 Result errCode = ERROR_UNKNOWN; 96 if (mAudioStream == nullptr) { 97 errCode = ERROR_INVALID_STATE; 98 } else { 99 oboe::Result result = mAudioStream->stop(); 100 mStreamStarted = false; 101 102 errCode = OboeErrorToMegaAudioError(result); 103 } 104 105 mStreamStarted = false; 106 return errCode; 107 } 108 getTimeStamp(oboe::FrameTimestamp * timeStamp)109StreamBase::Result OboeStream::getTimeStamp(oboe::FrameTimestamp* timeStamp) { 110 Result errCode = ERROR_UNKNOWN; 111 if (mAudioStream == nullptr) { 112 __android_log_print(ANDROID_LOG_ERROR, TAG, "ERROR_INVALID_STATE"); 113 errCode = ERROR_INVALID_STATE; 114 } else { 115 ResultWithValue<oboe::FrameTimestamp> result = mAudioStream->getTimestamp(CLOCK_MONOTONIC); 116 117 *timeStamp = result.value(); 118 119 errCode = OK; 120 } 121 122 return errCode; 123 } 124 getState() const125oboe::StreamState OboeStream::getState() const { 126 return mAudioStream != nullptr ? mAudioStream->getState() : oboe::StreamState::Unknown; 127 } 128 getLastErrorCallbackResult()129int OboeStream::getLastErrorCallbackResult() { 130 return (int) (mAudioStream != nullptr 131 ? (int) mAudioStream->getLastErrorCallbackResult() : StreamBase::ERROR_INVALID_STATE); 132 } 133 getRoutedDeviceId()134int32_t OboeStream::getRoutedDeviceId() { 135 return (int32_t) (mAudioStream != nullptr 136 ? (int32_t) mAudioStream->getDeviceId() 137 : ROUTING_DEVICE_NONE); 138 } 139 getSharingMode()140int32_t OboeStream::getSharingMode() { 141 return (int32_t) (mAudioStream != nullptr 142 ? (int32_t) mAudioStream->getSharingMode() 143 : SHARING_MODE_INVALID); 144 } 145 getChannelCount()146int32_t OboeStream::getChannelCount() { 147 return (int32_t) (mAudioStream != nullptr 148 ? (int32_t) mAudioStream->getChannelCount() 149 : -1); 150 } 151 isMMap()152bool OboeStream::isMMap() { 153 return OboeExtensions::isMMapUsed(mAudioStream.get()); 154 } 155 156