AudioEndpoint.cpp revision 87c9f646a94259d7c321c3b3d5947fa1778f5ac2
1/* 2 * Copyright (C) 2016 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#define LOG_TAG "AAudio" 18//#define LOG_NDEBUG 0 19#include <utils/Log.h> 20 21#include <cassert> 22#include <aaudio/AAudio.h> 23 24#include "AudioEndpointParcelable.h" 25#include "AudioEndpoint.h" 26#include "AAudioServiceMessage.h" 27 28using namespace android; 29using namespace aaudio; 30 31#define RIDICULOUSLY_LARGE_BUFFER_CAPACITY (256 * 1024) 32#define RIDICULOUSLY_LARGE_FRAME_SIZE 4096 33 34AudioEndpoint::AudioEndpoint() 35 : mFreeRunning(false) 36 , mDataReadCounter(0) 37 , mDataWriteCounter(0) 38{ 39} 40 41AudioEndpoint::~AudioEndpoint() 42{ 43} 44 45static aaudio_result_t AudioEndpoint_validateQueueDescriptor(const char *type, 46 const RingBufferDescriptor *descriptor) { 47 if (descriptor == nullptr) { 48 ALOGE("AudioEndpoint_validateQueueDescriptor() NULL descriptor"); 49 return AAUDIO_ERROR_NULL; 50 } 51 52 if (descriptor->capacityInFrames < 1 53 || descriptor->capacityInFrames > RIDICULOUSLY_LARGE_BUFFER_CAPACITY) { 54 ALOGE("AudioEndpoint_validateQueueDescriptor() bad capacityInFrames = %d", 55 descriptor->capacityInFrames); 56 return AAUDIO_ERROR_OUT_OF_RANGE; 57 } 58 59 // Reject extreme values to catch bugs and prevent numeric overflows. 60 if (descriptor->bytesPerFrame < 1 61 || descriptor->bytesPerFrame > RIDICULOUSLY_LARGE_FRAME_SIZE) { 62 ALOGE("AudioEndpoint_validateQueueDescriptor() bad bytesPerFrame = %d", 63 descriptor->bytesPerFrame); 64 return AAUDIO_ERROR_OUT_OF_RANGE; 65 } 66 67 if (descriptor->dataAddress == nullptr) { 68 ALOGE("AudioEndpoint_validateQueueDescriptor() NULL dataAddress"); 69 return AAUDIO_ERROR_NULL; 70 } 71 ALOGV("AudioEndpoint_validateQueueDescriptor %s, dataAddress at %p ====================", 72 type, 73 descriptor->dataAddress); 74 ALOGV("AudioEndpoint_validateQueueDescriptor readCounter at %p, writeCounter at %p", 75 descriptor->readCounterAddress, 76 descriptor->writeCounterAddress); 77 78 // Try to READ from the data area. 79 // This code will crash if the mmap failed. 80 uint8_t value = descriptor->dataAddress[0]; 81 ALOGV("AudioEndpoint_validateQueueDescriptor() dataAddress[0] = %d, then try to write", 82 (int) value); 83 // Try to WRITE to the data area. 84 descriptor->dataAddress[0] = value * 3; 85 ALOGV("AudioEndpoint_validateQueueDescriptor() wrote successfully"); 86 87 if (descriptor->readCounterAddress) { 88 fifo_counter_t counter = *descriptor->readCounterAddress; 89 ALOGV("AudioEndpoint_validateQueueDescriptor() *readCounterAddress = %d, now write", 90 (int) counter); 91 *descriptor->readCounterAddress = counter; 92 ALOGV("AudioEndpoint_validateQueueDescriptor() wrote readCounterAddress successfully"); 93 } 94 95 if (descriptor->writeCounterAddress) { 96 fifo_counter_t counter = *descriptor->writeCounterAddress; 97 ALOGV("AudioEndpoint_validateQueueDescriptor() *writeCounterAddress = %d, now write", 98 (int) counter); 99 *descriptor->writeCounterAddress = counter; 100 ALOGV("AudioEndpoint_validateQueueDescriptor() wrote writeCounterAddress successfully"); 101 } 102 103 return AAUDIO_OK; 104} 105 106aaudio_result_t AudioEndpoint_validateDescriptor(const EndpointDescriptor *pEndpointDescriptor) { 107 aaudio_result_t result = AudioEndpoint_validateQueueDescriptor("messages", 108 &pEndpointDescriptor->upMessageQueueDescriptor); 109 if (result == AAUDIO_OK) { 110 result = AudioEndpoint_validateQueueDescriptor("data", 111 &pEndpointDescriptor->dataQueueDescriptor); 112 } 113 return result; 114} 115 116aaudio_result_t AudioEndpoint::configure(const EndpointDescriptor *pEndpointDescriptor) 117{ 118 aaudio_result_t result = AudioEndpoint_validateDescriptor(pEndpointDescriptor); 119 if (result != AAUDIO_OK) { 120 ALOGE("AudioEndpoint_validateQueueDescriptor returned %d %s", 121 result, AAudio_convertResultToText(result)); 122 return result; 123 } 124 125 // ============================ up message queue ============================= 126 const RingBufferDescriptor *descriptor = &pEndpointDescriptor->upMessageQueueDescriptor; 127 if(descriptor->bytesPerFrame != sizeof(AAudioServiceMessage)) { 128 ALOGE("AudioEndpoint::configure() bytesPerFrame != sizeof(AAudioServiceMessage) = %d", 129 descriptor->bytesPerFrame); 130 return AAUDIO_ERROR_INTERNAL; 131 } 132 133 if(descriptor->readCounterAddress == nullptr || descriptor->writeCounterAddress == nullptr) { 134 ALOGE("AudioEndpoint_validateQueueDescriptor() NULL counter address"); 135 return AAUDIO_ERROR_NULL; 136 } 137 138 mUpCommandQueue = new FifoBuffer( 139 descriptor->bytesPerFrame, 140 descriptor->capacityInFrames, 141 descriptor->readCounterAddress, 142 descriptor->writeCounterAddress, 143 descriptor->dataAddress 144 ); 145 146 // ============================ down data queue ============================= 147 descriptor = &pEndpointDescriptor->dataQueueDescriptor; 148 ALOGV("AudioEndpoint::configure() data framesPerBurst = %d", descriptor->framesPerBurst); 149 ALOGV("AudioEndpoint::configure() data readCounterAddress = %p", descriptor->readCounterAddress); 150 mFreeRunning = descriptor->readCounterAddress == nullptr; 151 ALOGV("AudioEndpoint::configure() mFreeRunning = %d", mFreeRunning ? 1 : 0); 152 int64_t *readCounterAddress = (descriptor->readCounterAddress == nullptr) 153 ? &mDataReadCounter 154 : descriptor->readCounterAddress; 155 int64_t *writeCounterAddress = (descriptor->writeCounterAddress == nullptr) 156 ? &mDataWriteCounter 157 : descriptor->writeCounterAddress; 158 159 mDataQueue = new FifoBuffer( 160 descriptor->bytesPerFrame, 161 descriptor->capacityInFrames, 162 readCounterAddress, 163 writeCounterAddress, 164 descriptor->dataAddress 165 ); 166 uint32_t threshold = descriptor->capacityInFrames / 2; 167 mDataQueue->setThreshold(threshold); 168 return result; 169} 170 171aaudio_result_t AudioEndpoint::readUpCommand(AAudioServiceMessage *commandPtr) 172{ 173 return mUpCommandQueue->read(commandPtr, 1); 174} 175 176aaudio_result_t AudioEndpoint::writeDataNow(const void *buffer, int32_t numFrames) 177{ 178 return mDataQueue->write(buffer, numFrames); 179} 180 181void AudioEndpoint::getEmptyFramesAvailable(WrappingBuffer *wrappingBuffer) { 182 mDataQueue->getEmptyRoomAvailable(wrappingBuffer); 183} 184 185int32_t AudioEndpoint::getEmptyFramesAvailable() 186{ 187 return mDataQueue->getFifoControllerBase()->getEmptyFramesAvailable(); 188} 189 190void AudioEndpoint::getFullFramesAvailable(WrappingBuffer *wrappingBuffer) 191{ 192 return mDataQueue->getFullDataAvailable(wrappingBuffer); 193} 194 195int32_t AudioEndpoint::getFullFramesAvailable() 196{ 197 return mDataQueue->getFifoControllerBase()->getFullFramesAvailable(); 198} 199 200void AudioEndpoint::advanceWriteIndex(int32_t deltaFrames) { 201 mDataQueue->getFifoControllerBase()->advanceWriteIndex(deltaFrames); 202} 203 204void AudioEndpoint::advanceReadIndex(int32_t deltaFrames) { 205 mDataQueue->getFifoControllerBase()->advanceReadIndex(deltaFrames); 206} 207 208void AudioEndpoint::setDataReadCounter(fifo_counter_t framesRead) 209{ 210 mDataQueue->setReadCounter(framesRead); 211} 212 213fifo_counter_t AudioEndpoint::getDataReadCounter() 214{ 215 return mDataQueue->getReadCounter(); 216} 217 218void AudioEndpoint::setDataWriteCounter(fifo_counter_t framesRead) 219{ 220 mDataQueue->setWriteCounter(framesRead); 221} 222 223fifo_counter_t AudioEndpoint::getDataWriteCounter() 224{ 225 return mDataQueue->getWriteCounter(); 226} 227 228int32_t AudioEndpoint::setBufferSizeInFrames(int32_t requestedFrames, 229 int32_t *actualFrames) 230{ 231 if (requestedFrames < ENDPOINT_DATA_QUEUE_SIZE_MIN) { 232 requestedFrames = ENDPOINT_DATA_QUEUE_SIZE_MIN; 233 } 234 mDataQueue->setThreshold(requestedFrames); 235 *actualFrames = mDataQueue->getThreshold(); 236 return AAUDIO_OK; 237} 238 239int32_t AudioEndpoint::getBufferSizeInFrames() const 240{ 241 return mDataQueue->getThreshold(); 242} 243 244int32_t AudioEndpoint::getBufferCapacityInFrames() const 245{ 246 return (int32_t)mDataQueue->getBufferCapacityInFrames(); 247} 248 249