blob: 6ec285fcfd80bdc778fd2f72246c61ddfc8f0dfa [file] [log] [blame]
Phil Burk204a1632017-01-03 17:23:43 -08001/*
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
Phil Burk5ed503c2017-02-01 09:38:15 -080017#define LOG_TAG "AAudio"
Phil Burk204a1632017-01-03 17:23:43 -080018//#define LOG_NDEBUG 0
19#include <utils/Log.h>
20
21#include <cassert>
Phil Burke4d7bb42017-03-28 11:32:39 -070022#include <aaudio/AAudio.h>
Phil Burk204a1632017-01-03 17:23:43 -080023
24#include "AudioEndpointParcelable.h"
25#include "AudioEndpoint.h"
Phil Burk5ed503c2017-02-01 09:38:15 -080026#include "AAudioServiceMessage.h"
Phil Burk204a1632017-01-03 17:23:43 -080027
28using namespace android;
Phil Burk5ed503c2017-02-01 09:38:15 -080029using namespace aaudio;
Phil Burk204a1632017-01-03 17:23:43 -080030
Phil Burk5204d312017-05-04 17:16:13 -070031#define RIDICULOUSLY_LARGE_BUFFER_CAPACITY (256 * 1024)
32#define RIDICULOUSLY_LARGE_FRAME_SIZE 4096
33
Phil Burk204a1632017-01-03 17:23:43 -080034AudioEndpoint::AudioEndpoint()
Phil Burk87c9f642017-05-17 07:22:39 -070035 : mFreeRunning(false)
Phil Burk204a1632017-01-03 17:23:43 -080036 , mDataReadCounter(0)
37 , mDataWriteCounter(0)
38{
39}
40
41AudioEndpoint::~AudioEndpoint()
42{
43}
44
Phil Burkc0c70e32017-02-09 13:18:38 -080045static aaudio_result_t AudioEndpoint_validateQueueDescriptor(const char *type,
Phil Burk204a1632017-01-03 17:23:43 -080046 const RingBufferDescriptor *descriptor) {
Phil Burkc0c70e32017-02-09 13:18:38 -080047 if (descriptor == nullptr) {
48 ALOGE("AudioEndpoint_validateQueueDescriptor() NULL descriptor");
49 return AAUDIO_ERROR_NULL;
50 }
Phil Burk5204d312017-05-04 17:16:13 -070051
52 if (descriptor->capacityInFrames < 1
53 || descriptor->capacityInFrames > RIDICULOUSLY_LARGE_BUFFER_CAPACITY) {
Phil Burkc0c70e32017-02-09 13:18:38 -080054 ALOGE("AudioEndpoint_validateQueueDescriptor() bad capacityInFrames = %d",
55 descriptor->capacityInFrames);
56 return AAUDIO_ERROR_OUT_OF_RANGE;
57 }
Phil Burk5204d312017-05-04 17:16:13 -070058
59 // Reject extreme values to catch bugs and prevent numeric overflows.
60 if (descriptor->bytesPerFrame < 1
61 || descriptor->bytesPerFrame > RIDICULOUSLY_LARGE_FRAME_SIZE) {
Phil Burkc0c70e32017-02-09 13:18:38 -080062 ALOGE("AudioEndpoint_validateQueueDescriptor() bad bytesPerFrame = %d",
63 descriptor->bytesPerFrame);
64 return AAUDIO_ERROR_OUT_OF_RANGE;
65 }
Phil Burk5204d312017-05-04 17:16:13 -070066
Phil Burkc0c70e32017-02-09 13:18:38 -080067 if (descriptor->dataAddress == nullptr) {
68 ALOGE("AudioEndpoint_validateQueueDescriptor() NULL dataAddress");
69 return AAUDIO_ERROR_NULL;
70 }
Phil Burk71f35bb2017-04-13 16:05:07 -070071 ALOGV("AudioEndpoint_validateQueueDescriptor %s, dataAddress at %p ====================",
Phil Burk204a1632017-01-03 17:23:43 -080072 type,
73 descriptor->dataAddress);
Phil Burk71f35bb2017-04-13 16:05:07 -070074 ALOGV("AudioEndpoint_validateQueueDescriptor readCounter at %p, writeCounter at %p",
Phil Burk204a1632017-01-03 17:23:43 -080075 descriptor->readCounterAddress,
76 descriptor->writeCounterAddress);
77
78 // Try to READ from the data area.
Phil Burkc0c70e32017-02-09 13:18:38 -080079 // This code will crash if the mmap failed.
Phil Burk204a1632017-01-03 17:23:43 -080080 uint8_t value = descriptor->dataAddress[0];
Phil Burk71f35bb2017-04-13 16:05:07 -070081 ALOGV("AudioEndpoint_validateQueueDescriptor() dataAddress[0] = %d, then try to write",
Phil Burk204a1632017-01-03 17:23:43 -080082 (int) value);
83 // Try to WRITE to the data area.
Phil Burkc0c70e32017-02-09 13:18:38 -080084 descriptor->dataAddress[0] = value * 3;
Phil Burk71f35bb2017-04-13 16:05:07 -070085 ALOGV("AudioEndpoint_validateQueueDescriptor() wrote successfully");
Phil Burk204a1632017-01-03 17:23:43 -080086
87 if (descriptor->readCounterAddress) {
88 fifo_counter_t counter = *descriptor->readCounterAddress;
Phil Burk71f35bb2017-04-13 16:05:07 -070089 ALOGV("AudioEndpoint_validateQueueDescriptor() *readCounterAddress = %d, now write",
Phil Burk204a1632017-01-03 17:23:43 -080090 (int) counter);
91 *descriptor->readCounterAddress = counter;
Phil Burk71f35bb2017-04-13 16:05:07 -070092 ALOGV("AudioEndpoint_validateQueueDescriptor() wrote readCounterAddress successfully");
Phil Burk204a1632017-01-03 17:23:43 -080093 }
Phil Burk5204d312017-05-04 17:16:13 -070094
Phil Burk204a1632017-01-03 17:23:43 -080095 if (descriptor->writeCounterAddress) {
96 fifo_counter_t counter = *descriptor->writeCounterAddress;
Phil Burk71f35bb2017-04-13 16:05:07 -070097 ALOGV("AudioEndpoint_validateQueueDescriptor() *writeCounterAddress = %d, now write",
Phil Burk204a1632017-01-03 17:23:43 -080098 (int) counter);
99 *descriptor->writeCounterAddress = counter;
Phil Burk71f35bb2017-04-13 16:05:07 -0700100 ALOGV("AudioEndpoint_validateQueueDescriptor() wrote writeCounterAddress successfully");
Phil Burk204a1632017-01-03 17:23:43 -0800101 }
Phil Burk5204d312017-05-04 17:16:13 -0700102
Phil Burkc0c70e32017-02-09 13:18:38 -0800103 return AAUDIO_OK;
Phil Burk204a1632017-01-03 17:23:43 -0800104}
105
Phil Burkc0c70e32017-02-09 13:18:38 -0800106aaudio_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",
Phil Burk87c9f642017-05-17 07:22:39 -0700111 &pEndpointDescriptor->dataQueueDescriptor);
Phil Burkc0c70e32017-02-09 13:18:38 -0800112 }
113 return result;
Phil Burk204a1632017-01-03 17:23:43 -0800114}
115
Phil Burkfd34a932017-07-19 07:03:52 -0700116aaudio_result_t AudioEndpoint::configure(const EndpointDescriptor *pEndpointDescriptor,
117 aaudio_direction_t direction)
Phil Burk204a1632017-01-03 17:23:43 -0800118{
Phil Burkc0c70e32017-02-09 13:18:38 -0800119 aaudio_result_t result = AudioEndpoint_validateDescriptor(pEndpointDescriptor);
120 if (result != AAUDIO_OK) {
Phil Burk71f35bb2017-04-13 16:05:07 -0700121 ALOGE("AudioEndpoint_validateQueueDescriptor returned %d %s",
Phil Burkc0c70e32017-02-09 13:18:38 -0800122 result, AAudio_convertResultToText(result));
123 return result;
124 }
Phil Burk204a1632017-01-03 17:23:43 -0800125
Phil Burk5204d312017-05-04 17:16:13 -0700126 // ============================ up message queue =============================
Phil Burk204a1632017-01-03 17:23:43 -0800127 const RingBufferDescriptor *descriptor = &pEndpointDescriptor->upMessageQueueDescriptor;
Phil Burk5204d312017-05-04 17:16:13 -0700128 if(descriptor->bytesPerFrame != sizeof(AAudioServiceMessage)) {
129 ALOGE("AudioEndpoint::configure() bytesPerFrame != sizeof(AAudioServiceMessage) = %d",
130 descriptor->bytesPerFrame);
131 return AAUDIO_ERROR_INTERNAL;
132 }
133
134 if(descriptor->readCounterAddress == nullptr || descriptor->writeCounterAddress == nullptr) {
135 ALOGE("AudioEndpoint_validateQueueDescriptor() NULL counter address");
136 return AAUDIO_ERROR_NULL;
137 }
138
Phil Burk204a1632017-01-03 17:23:43 -0800139 mUpCommandQueue = new FifoBuffer(
140 descriptor->bytesPerFrame,
141 descriptor->capacityInFrames,
142 descriptor->readCounterAddress,
143 descriptor->writeCounterAddress,
144 descriptor->dataAddress
145 );
Phil Burk5204d312017-05-04 17:16:13 -0700146
Phil Burkfd34a932017-07-19 07:03:52 -0700147 // ============================ data queue =============================
Phil Burk87c9f642017-05-17 07:22:39 -0700148 descriptor = &pEndpointDescriptor->dataQueueDescriptor;
Phil Burk71f35bb2017-04-13 16:05:07 -0700149 ALOGV("AudioEndpoint::configure() data framesPerBurst = %d", descriptor->framesPerBurst);
Phil Burkfd34a932017-07-19 07:03:52 -0700150 ALOGV("AudioEndpoint::configure() data readCounterAddress = %p",
151 descriptor->readCounterAddress);
152
153 // An example of free running is when the other side is read or written by hardware DMA
154 // or a DSP. It does not update its counter so we have to update it.
155 int64_t *remoteCounter = (direction == AAUDIO_DIRECTION_OUTPUT)
156 ? descriptor->readCounterAddress // read by other side
157 : descriptor->writeCounterAddress; // written by other side
158 mFreeRunning = (remoteCounter == nullptr);
Phil Burk87c9f642017-05-17 07:22:39 -0700159 ALOGV("AudioEndpoint::configure() mFreeRunning = %d", mFreeRunning ? 1 : 0);
Phil Burkfd34a932017-07-19 07:03:52 -0700160
Phil Burk204a1632017-01-03 17:23:43 -0800161 int64_t *readCounterAddress = (descriptor->readCounterAddress == nullptr)
162 ? &mDataReadCounter
163 : descriptor->readCounterAddress;
164 int64_t *writeCounterAddress = (descriptor->writeCounterAddress == nullptr)
165 ? &mDataWriteCounter
166 : descriptor->writeCounterAddress;
Phil Burkc0c70e32017-02-09 13:18:38 -0800167
Phil Burk87c9f642017-05-17 07:22:39 -0700168 mDataQueue = new FifoBuffer(
Phil Burk204a1632017-01-03 17:23:43 -0800169 descriptor->bytesPerFrame,
170 descriptor->capacityInFrames,
171 readCounterAddress,
172 writeCounterAddress,
173 descriptor->dataAddress
174 );
175 uint32_t threshold = descriptor->capacityInFrames / 2;
Phil Burk87c9f642017-05-17 07:22:39 -0700176 mDataQueue->setThreshold(threshold);
Phil Burk204a1632017-01-03 17:23:43 -0800177 return result;
178}
179
Phil Burk5ed503c2017-02-01 09:38:15 -0800180aaudio_result_t AudioEndpoint::readUpCommand(AAudioServiceMessage *commandPtr)
Phil Burk204a1632017-01-03 17:23:43 -0800181{
182 return mUpCommandQueue->read(commandPtr, 1);
183}
184
Phil Burkfd34a932017-07-19 07:03:52 -0700185int32_t AudioEndpoint::getEmptyFramesAvailable(WrappingBuffer *wrappingBuffer) {
186 return mDataQueue->getEmptyRoomAvailable(wrappingBuffer);
Phil Burkc0c70e32017-02-09 13:18:38 -0800187}
188
Phil Burk87c9f642017-05-17 07:22:39 -0700189int32_t AudioEndpoint::getEmptyFramesAvailable()
190{
191 return mDataQueue->getFifoControllerBase()->getEmptyFramesAvailable();
192}
193
Phil Burkfd34a932017-07-19 07:03:52 -0700194int32_t AudioEndpoint::getFullFramesAvailable(WrappingBuffer *wrappingBuffer)
Phil Burk87c9f642017-05-17 07:22:39 -0700195{
196 return mDataQueue->getFullDataAvailable(wrappingBuffer);
Phil Burk4485d412017-05-09 15:55:02 -0700197}
198
199int32_t AudioEndpoint::getFullFramesAvailable()
200{
Phil Burk87c9f642017-05-17 07:22:39 -0700201 return mDataQueue->getFifoControllerBase()->getFullFramesAvailable();
Phil Burk4485d412017-05-09 15:55:02 -0700202}
203
Phil Burkc0c70e32017-02-09 13:18:38 -0800204void AudioEndpoint::advanceWriteIndex(int32_t deltaFrames) {
Phil Burk87c9f642017-05-17 07:22:39 -0700205 mDataQueue->getFifoControllerBase()->advanceWriteIndex(deltaFrames);
Phil Burkc0c70e32017-02-09 13:18:38 -0800206}
207
Phil Burk87c9f642017-05-17 07:22:39 -0700208void AudioEndpoint::advanceReadIndex(int32_t deltaFrames) {
209 mDataQueue->getFifoControllerBase()->advanceReadIndex(deltaFrames);
Phil Burk204a1632017-01-03 17:23:43 -0800210}
211
Phil Burk87c9f642017-05-17 07:22:39 -0700212void AudioEndpoint::setDataReadCounter(fifo_counter_t framesRead)
Phil Burk204a1632017-01-03 17:23:43 -0800213{
Phil Burk87c9f642017-05-17 07:22:39 -0700214 mDataQueue->setReadCounter(framesRead);
Phil Burk204a1632017-01-03 17:23:43 -0800215}
216
Phil Burk87c9f642017-05-17 07:22:39 -0700217fifo_counter_t AudioEndpoint::getDataReadCounter()
Phil Burk204a1632017-01-03 17:23:43 -0800218{
Phil Burk87c9f642017-05-17 07:22:39 -0700219 return mDataQueue->getReadCounter();
Phil Burk204a1632017-01-03 17:23:43 -0800220}
221
Phil Burk87c9f642017-05-17 07:22:39 -0700222void AudioEndpoint::setDataWriteCounter(fifo_counter_t framesRead)
Phil Burk204a1632017-01-03 17:23:43 -0800223{
Phil Burk87c9f642017-05-17 07:22:39 -0700224 mDataQueue->setWriteCounter(framesRead);
225}
226
227fifo_counter_t AudioEndpoint::getDataWriteCounter()
228{
229 return mDataQueue->getWriteCounter();
Phil Burk204a1632017-01-03 17:23:43 -0800230}
231
Phil Burk3316d5e2017-02-15 11:23:01 -0800232int32_t AudioEndpoint::setBufferSizeInFrames(int32_t requestedFrames,
233 int32_t *actualFrames)
Phil Burk204a1632017-01-03 17:23:43 -0800234{
235 if (requestedFrames < ENDPOINT_DATA_QUEUE_SIZE_MIN) {
236 requestedFrames = ENDPOINT_DATA_QUEUE_SIZE_MIN;
237 }
Phil Burk87c9f642017-05-17 07:22:39 -0700238 mDataQueue->setThreshold(requestedFrames);
239 *actualFrames = mDataQueue->getThreshold();
Phil Burk5ed503c2017-02-01 09:38:15 -0800240 return AAUDIO_OK;
Phil Burk204a1632017-01-03 17:23:43 -0800241}
242
243int32_t AudioEndpoint::getBufferSizeInFrames() const
244{
Phil Burk87c9f642017-05-17 07:22:39 -0700245 return mDataQueue->getThreshold();
Phil Burk204a1632017-01-03 17:23:43 -0800246}
247
248int32_t AudioEndpoint::getBufferCapacityInFrames() const
249{
Phil Burk87c9f642017-05-17 07:22:39 -0700250 return (int32_t)mDataQueue->getBufferCapacityInFrames();
Phil Burk204a1632017-01-03 17:23:43 -0800251}
252
Phil Burkec89b2e2017-06-20 15:05:06 -0700253void AudioEndpoint::dump() const {
254 ALOGD("AudioEndpoint: data readCounter = %lld", (long long) mDataQueue->getReadCounter());
255 ALOGD("AudioEndpoint: data writeCounter = %lld", (long long) mDataQueue->getWriteCounter());
256}