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 WorkerStreamBase::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 WorkerStreamBase::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 WorkerStreamBase::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 WorkerStreamBase::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 WorkerStreamBase::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 WorkerStreamBase::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 Workeroboe::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 Workerint 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 Workerint32_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 Workerint32_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 Workerint32_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 Workerbool OboeStream::isMMap() { 153*b7c941bbSAndroid Build Coastguard Worker return OboeExtensions::isMMapUsed(mAudioStream.get()); 154*b7c941bbSAndroid Build Coastguard Worker } 155*b7c941bbSAndroid Build Coastguard Worker 156