1c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/* 2c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Copyright (C) 2017 The Android Open Source Project 3c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * 4c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Licensed under the Apache License, Version 2.0 (the "License"); 5c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * you may not use this file except in compliance with the License. 6c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * You may obtain a copy of the License at 7c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * 8c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * http://www.apache.org/licenses/LICENSE-2.0 9c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * 10c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Unless required by applicable law or agreed to in writing, software 11c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * distributed under the License is distributed on an "AS IS" BASIS, 12c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * See the License for the specific language governing permissions and 14c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * limitations under the License. 15c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk */ 16c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 17c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#define LOG_TAG "AAudioService" 18c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk//#define LOG_NDEBUG 0 19c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <utils/Log.h> 20c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 21c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <mutex> 22c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 23c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <aaudio/AAudio.h> 24c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 25c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "binding/IAAudioService.h" 26c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 27c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "binding/AAudioServiceMessage.h" 28c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "AAudioServiceStreamBase.h" 29c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "AAudioServiceStreamShared.h" 30c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "AAudioEndpointManager.h" 31c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "AAudioService.h" 32c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "AAudioServiceEndpoint.h" 33c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 34c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing namespace android; 35c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing namespace aaudio; 36c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 37c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#define MIN_BURSTS_PER_BUFFER 2 38c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#define MAX_BURSTS_PER_BUFFER 32 39c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 40c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil BurkAAudioServiceStreamShared::AAudioServiceStreamShared(AAudioService &audioService) 41c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk : mAudioService(audioService) 42c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk { 43c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 44c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 45c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil BurkAAudioServiceStreamShared::~AAudioServiceStreamShared() { 46c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk close(); 47c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 48c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 49c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::open(const aaudio::AAudioStreamRequest &request, 50c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk aaudio::AAudioStreamConfiguration &configurationOutput) { 51c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 52c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk aaudio_result_t result = AAudioServiceStreamBase::open(request, configurationOutput); 53c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk if (result != AAUDIO_OK) { 54c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk ALOGE("AAudioServiceStreamBase open returned %d", result); 55c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return result; 56c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 57c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 58c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration(); 59c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk int32_t deviceId = configurationInput.getDeviceId(); 60c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk aaudio_direction_t direction = request.getDirection(); 61c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 62c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance(); 6371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService, deviceId, direction); 64c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk if (mServiceEndpoint == nullptr) { 6587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk ALOGE("AAudioServiceStreamShared::open(), mServiceEndPoint = %p", mServiceEndpoint); 66c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAUDIO_ERROR_UNAVAILABLE; 67c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 68c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 69c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk // Is the request compatible with the shared endpoint? 70c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mAudioFormat = configurationInput.getAudioFormat(); 71c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk if (mAudioFormat == AAUDIO_FORMAT_UNSPECIFIED) { 72c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mAudioFormat = AAUDIO_FORMAT_PCM_FLOAT; 73c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } else if (mAudioFormat != AAUDIO_FORMAT_PCM_FLOAT) { 7471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk ALOGE("AAudioServiceStreamShared::open(), mAudioFormat = %d, need FLOAT", mAudioFormat); 75c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAUDIO_ERROR_INVALID_FORMAT; 76c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 77c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 78c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mSampleRate = configurationInput.getSampleRate(); 7937a466ae847cf08fc346e629fe4cf964ad67063fGlenn Kasten if (mSampleRate == AAUDIO_UNSPECIFIED) { 80c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mSampleRate = mServiceEndpoint->getSampleRate(); 81c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } else if (mSampleRate != mServiceEndpoint->getSampleRate()) { 8271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk ALOGE("AAudioServiceStreamShared::open(), mAudioFormat = %d, need %d", 8371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk mSampleRate, mServiceEndpoint->getSampleRate()); 84c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAUDIO_ERROR_INVALID_RATE; 85c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 86c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 87c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mSamplesPerFrame = configurationInput.getSamplesPerFrame(); 8837a466ae847cf08fc346e629fe4cf964ad67063fGlenn Kasten if (mSamplesPerFrame == AAUDIO_UNSPECIFIED) { 89c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mSamplesPerFrame = mServiceEndpoint->getSamplesPerFrame(); 90c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } else if (mSamplesPerFrame != mServiceEndpoint->getSamplesPerFrame()) { 9171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk ALOGE("AAudioServiceStreamShared::open(), mSamplesPerFrame = %d, need %d", 9271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk mSamplesPerFrame, mServiceEndpoint->getSamplesPerFrame()); 93c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAUDIO_ERROR_OUT_OF_RANGE; 94c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 95c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 96c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk // Determine this stream's shared memory buffer capacity. 97c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mFramesPerBurst = mServiceEndpoint->getFramesPerBurst(); 98c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk int32_t minCapacityFrames = configurationInput.getBufferCapacity(); 9971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk int32_t numBursts = MAX_BURSTS_PER_BUFFER; 10071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk if (minCapacityFrames != AAUDIO_UNSPECIFIED) { 10171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk numBursts = (minCapacityFrames + mFramesPerBurst - 1) / mFramesPerBurst; 10271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk if (numBursts < MIN_BURSTS_PER_BUFFER) { 10371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk numBursts = MIN_BURSTS_PER_BUFFER; 10471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk } else if (numBursts > MAX_BURSTS_PER_BUFFER) { 10571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk numBursts = MAX_BURSTS_PER_BUFFER; 10671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk } 107c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 108c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mCapacityInFrames = numBursts * mFramesPerBurst; 109c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk ALOGD("AAudioServiceStreamShared::open(), mCapacityInFrames = %d", mCapacityInFrames); 110c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 111c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk // Create audio data shared memory buffer for client. 112c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mAudioDataQueue = new SharedRingBuffer(); 113c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mAudioDataQueue->allocate(calculateBytesPerFrame(), mCapacityInFrames); 114c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 115c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk // Fill in configuration for client. 116c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk configurationOutput.setSampleRate(mSampleRate); 117c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk configurationOutput.setSamplesPerFrame(mSamplesPerFrame); 118c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk configurationOutput.setAudioFormat(mAudioFormat); 119c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk configurationOutput.setDeviceId(deviceId); 120c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 121c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mServiceEndpoint->registerStream(this); 122c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 123c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAUDIO_OK; 124c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 125c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 126c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/** 127c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Start the flow of audio data. 128c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * 129c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete. 130c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk */ 131c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::start() { 13271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk AAudioServiceEndpoint *endpoint = mServiceEndpoint; 13371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk if (endpoint == nullptr) { 13471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk return AAUDIO_ERROR_INVALID_STATE; 13571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk } 13687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // For output streams, this will add the stream to the mixer. 13771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk aaudio_result_t result = endpoint->startStream(this); 138c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk if (result != AAUDIO_OK) { 139c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk ALOGE("AAudioServiceStreamShared::start() mServiceEndpoint returned %d", result); 140c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk processError(); 141c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } else { 142c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk result = AAudioServiceStreamBase::start(); 143c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 144c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAUDIO_OK; 145c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 146c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 147c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/** 148c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Stop the flow of data so that start() can resume without loss of data. 149c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * 150c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * An AAUDIO_SERVICE_EVENT_PAUSED will be sent to the client when complete. 151c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk*/ 152c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::pause() { 15371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk AAudioServiceEndpoint *endpoint = mServiceEndpoint; 15471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk if (endpoint == nullptr) { 15571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk return AAUDIO_ERROR_INVALID_STATE; 15671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk } 15771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk // Add this stream to the mixer. 15871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk aaudio_result_t result = endpoint->stopStream(this); 15971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk if (result != AAUDIO_OK) { 16071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk ALOGE("AAudioServiceStreamShared::pause() mServiceEndpoint returned %d", result); 16171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk processError(); 16271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk } 16371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk return AAudioServiceStreamBase::pause(); 16471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk} 16571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk 16671f35bb687476694882a617ba4a810a0bb56fe23Phil Burkaaudio_result_t AAudioServiceStreamShared::stop() { 16771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk AAudioServiceEndpoint *endpoint = mServiceEndpoint; 16871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk if (endpoint == nullptr) { 16971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk return AAUDIO_ERROR_INVALID_STATE; 17071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk } 171c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk // Add this stream to the mixer. 17271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk aaudio_result_t result = endpoint->stopStream(this); 173c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk if (result != AAUDIO_OK) { 174c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk ALOGE("AAudioServiceStreamShared::stop() mServiceEndpoint returned %d", result); 175c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk processError(); 176c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 17771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk return AAudioServiceStreamBase::stop(); 178c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 179c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 180c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/** 181c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Discard any data held by the underlying HAL or Service. 182c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * 183c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * An AAUDIO_SERVICE_EVENT_FLUSHED will be sent to the client when complete. 184c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk */ 185c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::flush() { 186c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk // TODO make sure we are paused 18771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk // TODO actually flush the data 18871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk return AAudioServiceStreamBase::flush() ; 189c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 190c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 191c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::close() { 192c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk pause(); 193c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk // TODO wait for pause() to synchronize 19471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk AAudioServiceEndpoint *endpoint = mServiceEndpoint; 19571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk if (endpoint != nullptr) { 19671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk endpoint->unregisterStream(this); 19771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk 19871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance(); 19971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk mEndpointManager.closeEndpoint(endpoint); 20071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk mServiceEndpoint = nullptr; 20171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk } 202942bdc0aebc88dc8b12c0e7742ec0003bbb8b80fPhil Burk if (mAudioDataQueue != nullptr) { 203942bdc0aebc88dc8b12c0e7742ec0003bbb8b80fPhil Burk delete mAudioDataQueue; 204942bdc0aebc88dc8b12c0e7742ec0003bbb8b80fPhil Burk mAudioDataQueue = nullptr; 205942bdc0aebc88dc8b12c0e7742ec0003bbb8b80fPhil Burk } 206c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAudioServiceStreamBase::close(); 207c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 208c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 209c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/** 210c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Get an immutable description of the data queue created by this service. 211c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk */ 212c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::getDownDataDescription(AudioEndpointParcelable &parcelable) 213c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk{ 214c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk // Gather information on the data queue. 215c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mAudioDataQueue->fillParcelable(parcelable, 216c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk parcelable.mDownDataQueueParcelable); 217c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk parcelable.mDownDataQueueParcelable.setFramesPerBurst(getFramesPerBurst()); 218c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAUDIO_OK; 219c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 220c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 221c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkvoid AAudioServiceStreamShared::onStop() { 222c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 223c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 224c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkvoid AAudioServiceStreamShared::onDisconnect() { 225c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mServiceEndpoint->close(); 226c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mServiceEndpoint = nullptr; 227c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 228c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 22971f35bb687476694882a617ba4a810a0bb56fe23Phil Burkvoid AAudioServiceStreamShared::markTransferTime(int64_t nanoseconds) { 23071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk mMarkedPosition = mAudioDataQueue->getFifoBuffer()->getReadCounter(); 23171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk mMarkedTime = nanoseconds; 23271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk} 233c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk 234c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::getFreeRunningPosition(int64_t *positionFrames, 235c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk int64_t *timeNanos) { 23671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk // TODO get these two numbers as an atomic pair 23771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk *positionFrames = mMarkedPosition; 23871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk *timeNanos = mMarkedTime; 239c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return AAUDIO_OK; 240c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk} 241