blob: 06f66d3f255ec3bdfca318db467a2bc0701ca2a7 [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 Burkfbf031e2017-10-12 15:58:31 -070017#define LOG_TAG "AudioEndpoint"
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 Burk5edc4ea2020-04-17 08:15:42 -070035 : mFreeRunning(false)
Phil Burk204a1632017-01-03 17:23:43 -080036 , mDataReadCounter(0)
37 , mDataWriteCounter(0)
38{
39}
40
Phil Burkfbf031e2017-10-12 15:58:31 -070041// TODO Consider moving to a method in RingBufferDescriptor
Phil Burkc0c70e32017-02-09 13:18:38 -080042static aaudio_result_t AudioEndpoint_validateQueueDescriptor(const char *type,
Phil Burk204a1632017-01-03 17:23:43 -080043 const RingBufferDescriptor *descriptor) {
Phil Burkc0c70e32017-02-09 13:18:38 -080044 if (descriptor == nullptr) {
45 ALOGE("AudioEndpoint_validateQueueDescriptor() NULL descriptor");
46 return AAUDIO_ERROR_NULL;
47 }
Phil Burk5204d312017-05-04 17:16:13 -070048
49 if (descriptor->capacityInFrames < 1
50 || descriptor->capacityInFrames > RIDICULOUSLY_LARGE_BUFFER_CAPACITY) {
Phil Burkc0c70e32017-02-09 13:18:38 -080051 ALOGE("AudioEndpoint_validateQueueDescriptor() bad capacityInFrames = %d",
52 descriptor->capacityInFrames);
53 return AAUDIO_ERROR_OUT_OF_RANGE;
54 }
Phil Burk5204d312017-05-04 17:16:13 -070055
56 // Reject extreme values to catch bugs and prevent numeric overflows.
57 if (descriptor->bytesPerFrame < 1
58 || descriptor->bytesPerFrame > RIDICULOUSLY_LARGE_FRAME_SIZE) {
Phil Burkc0c70e32017-02-09 13:18:38 -080059 ALOGE("AudioEndpoint_validateQueueDescriptor() bad bytesPerFrame = %d",
60 descriptor->bytesPerFrame);
61 return AAUDIO_ERROR_OUT_OF_RANGE;
62 }
Phil Burk5204d312017-05-04 17:16:13 -070063
Phil Burkc0c70e32017-02-09 13:18:38 -080064 if (descriptor->dataAddress == nullptr) {
65 ALOGE("AudioEndpoint_validateQueueDescriptor() NULL dataAddress");
66 return AAUDIO_ERROR_NULL;
67 }
Phil Burk71f35bb2017-04-13 16:05:07 -070068 ALOGV("AudioEndpoint_validateQueueDescriptor %s, dataAddress at %p ====================",
Phil Burk204a1632017-01-03 17:23:43 -080069 type,
70 descriptor->dataAddress);
Phil Burk71f35bb2017-04-13 16:05:07 -070071 ALOGV("AudioEndpoint_validateQueueDescriptor readCounter at %p, writeCounter at %p",
Phil Burk204a1632017-01-03 17:23:43 -080072 descriptor->readCounterAddress,
73 descriptor->writeCounterAddress);
74
75 // Try to READ from the data area.
Phil Burkc0c70e32017-02-09 13:18:38 -080076 // This code will crash if the mmap failed.
Phil Burk204a1632017-01-03 17:23:43 -080077 uint8_t value = descriptor->dataAddress[0];
Phil Burk71f35bb2017-04-13 16:05:07 -070078 ALOGV("AudioEndpoint_validateQueueDescriptor() dataAddress[0] = %d, then try to write",
Phil Burk204a1632017-01-03 17:23:43 -080079 (int) value);
80 // Try to WRITE to the data area.
Phil Burkc0c70e32017-02-09 13:18:38 -080081 descriptor->dataAddress[0] = value * 3;
Phil Burk71f35bb2017-04-13 16:05:07 -070082 ALOGV("AudioEndpoint_validateQueueDescriptor() wrote successfully");
Phil Burk204a1632017-01-03 17:23:43 -080083
84 if (descriptor->readCounterAddress) {
85 fifo_counter_t counter = *descriptor->readCounterAddress;
Phil Burk71f35bb2017-04-13 16:05:07 -070086 ALOGV("AudioEndpoint_validateQueueDescriptor() *readCounterAddress = %d, now write",
Phil Burk204a1632017-01-03 17:23:43 -080087 (int) counter);
88 *descriptor->readCounterAddress = counter;
Phil Burk71f35bb2017-04-13 16:05:07 -070089 ALOGV("AudioEndpoint_validateQueueDescriptor() wrote readCounterAddress successfully");
Phil Burk204a1632017-01-03 17:23:43 -080090 }
Phil Burk5204d312017-05-04 17:16:13 -070091
Phil Burk204a1632017-01-03 17:23:43 -080092 if (descriptor->writeCounterAddress) {
93 fifo_counter_t counter = *descriptor->writeCounterAddress;
Phil Burk71f35bb2017-04-13 16:05:07 -070094 ALOGV("AudioEndpoint_validateQueueDescriptor() *writeCounterAddress = %d, now write",
Phil Burk204a1632017-01-03 17:23:43 -080095 (int) counter);
96 *descriptor->writeCounterAddress = counter;
Phil Burk71f35bb2017-04-13 16:05:07 -070097 ALOGV("AudioEndpoint_validateQueueDescriptor() wrote writeCounterAddress successfully");
Phil Burk204a1632017-01-03 17:23:43 -080098 }
Phil Burk5204d312017-05-04 17:16:13 -070099
Phil Burkc0c70e32017-02-09 13:18:38 -0800100 return AAUDIO_OK;
Phil Burk204a1632017-01-03 17:23:43 -0800101}
102
Phil Burkc0c70e32017-02-09 13:18:38 -0800103aaudio_result_t AudioEndpoint_validateDescriptor(const EndpointDescriptor *pEndpointDescriptor) {
104 aaudio_result_t result = AudioEndpoint_validateQueueDescriptor("messages",
105 &pEndpointDescriptor->upMessageQueueDescriptor);
106 if (result == AAUDIO_OK) {
107 result = AudioEndpoint_validateQueueDescriptor("data",
Phil Burk87c9f642017-05-17 07:22:39 -0700108 &pEndpointDescriptor->dataQueueDescriptor);
Phil Burkc0c70e32017-02-09 13:18:38 -0800109 }
110 return result;
Phil Burk204a1632017-01-03 17:23:43 -0800111}
112
Phil Burkfd34a932017-07-19 07:03:52 -0700113aaudio_result_t AudioEndpoint::configure(const EndpointDescriptor *pEndpointDescriptor,
114 aaudio_direction_t direction)
Phil Burk204a1632017-01-03 17:23:43 -0800115{
Phil Burkc0c70e32017-02-09 13:18:38 -0800116 aaudio_result_t result = AudioEndpoint_validateDescriptor(pEndpointDescriptor);
117 if (result != AAUDIO_OK) {
Phil Burkc0c70e32017-02-09 13:18:38 -0800118 return result;
119 }
Phil Burk204a1632017-01-03 17:23:43 -0800120
Phil Burk5204d312017-05-04 17:16:13 -0700121 // ============================ up message queue =============================
Phil Burk204a1632017-01-03 17:23:43 -0800122 const RingBufferDescriptor *descriptor = &pEndpointDescriptor->upMessageQueueDescriptor;
Phil Burk5204d312017-05-04 17:16:13 -0700123 if(descriptor->bytesPerFrame != sizeof(AAudioServiceMessage)) {
Phil Burkfbf031e2017-10-12 15:58:31 -0700124 ALOGE("configure() bytesPerFrame != sizeof(AAudioServiceMessage) = %d",
Phil Burk5204d312017-05-04 17:16:13 -0700125 descriptor->bytesPerFrame);
126 return AAUDIO_ERROR_INTERNAL;
127 }
128
129 if(descriptor->readCounterAddress == nullptr || descriptor->writeCounterAddress == nullptr) {
Phil Burkfbf031e2017-10-12 15:58:31 -0700130 ALOGE("configure() NULL counter address");
Phil Burk5204d312017-05-04 17:16:13 -0700131 return AAUDIO_ERROR_NULL;
132 }
133
Phil Burk99306c82017-08-14 12:38:58 -0700134 // Prevent memory leak and reuse.
135 if(mUpCommandQueue != nullptr || mDataQueue != nullptr) {
Phil Burkfbf031e2017-10-12 15:58:31 -0700136 ALOGE("configure() endpoint already used");
Phil Burk99306c82017-08-14 12:38:58 -0700137 return AAUDIO_ERROR_INTERNAL;
138 }
139
Phil Burk5edc4ea2020-04-17 08:15:42 -0700140 mUpCommandQueue = std::make_unique<FifoBuffer>(
Phil Burk204a1632017-01-03 17:23:43 -0800141 descriptor->bytesPerFrame,
142 descriptor->capacityInFrames,
143 descriptor->readCounterAddress,
144 descriptor->writeCounterAddress,
145 descriptor->dataAddress
146 );
Phil Burk5204d312017-05-04 17:16:13 -0700147
Phil Burkfd34a932017-07-19 07:03:52 -0700148 // ============================ data queue =============================
Phil Burk87c9f642017-05-17 07:22:39 -0700149 descriptor = &pEndpointDescriptor->dataQueueDescriptor;
Phil Burkfbf031e2017-10-12 15:58:31 -0700150 ALOGV("configure() data framesPerBurst = %d", descriptor->framesPerBurst);
151 ALOGV("configure() data readCounterAddress = %p",
Phil Burkfd34a932017-07-19 07:03:52 -0700152 descriptor->readCounterAddress);
153
154 // An example of free running is when the other side is read or written by hardware DMA
155 // or a DSP. It does not update its counter so we have to update it.
156 int64_t *remoteCounter = (direction == AAUDIO_DIRECTION_OUTPUT)
157 ? descriptor->readCounterAddress // read by other side
158 : descriptor->writeCounterAddress; // written by other side
159 mFreeRunning = (remoteCounter == nullptr);
Phil Burkfbf031e2017-10-12 15:58:31 -0700160 ALOGV("configure() mFreeRunning = %d", mFreeRunning ? 1 : 0);
Phil Burkfd34a932017-07-19 07:03:52 -0700161
Phil Burk204a1632017-01-03 17:23:43 -0800162 int64_t *readCounterAddress = (descriptor->readCounterAddress == nullptr)
163 ? &mDataReadCounter
164 : descriptor->readCounterAddress;
165 int64_t *writeCounterAddress = (descriptor->writeCounterAddress == nullptr)
166 ? &mDataWriteCounter
167 : descriptor->writeCounterAddress;
Phil Burkc0c70e32017-02-09 13:18:38 -0800168
Phil Burk5edc4ea2020-04-17 08:15:42 -0700169 mDataQueue = std::make_unique<FifoBuffer>(
Phil Burk204a1632017-01-03 17:23:43 -0800170 descriptor->bytesPerFrame,
171 descriptor->capacityInFrames,
172 readCounterAddress,
173 writeCounterAddress,
174 descriptor->dataAddress
175 );
176 uint32_t threshold = descriptor->capacityInFrames / 2;
Phil Burk87c9f642017-05-17 07:22:39 -0700177 mDataQueue->setThreshold(threshold);
Phil Burk204a1632017-01-03 17:23:43 -0800178 return result;
179}
180
Phil Burk5ed503c2017-02-01 09:38:15 -0800181aaudio_result_t AudioEndpoint::readUpCommand(AAudioServiceMessage *commandPtr)
Phil Burk204a1632017-01-03 17:23:43 -0800182{
183 return mUpCommandQueue->read(commandPtr, 1);
184}
185
Phil Burkfd34a932017-07-19 07:03:52 -0700186int32_t AudioEndpoint::getEmptyFramesAvailable(WrappingBuffer *wrappingBuffer) {
187 return mDataQueue->getEmptyRoomAvailable(wrappingBuffer);
Phil Burkc0c70e32017-02-09 13:18:38 -0800188}
189
Phil Burk5edc4ea2020-04-17 08:15:42 -0700190int32_t AudioEndpoint::getEmptyFramesAvailable() {
Phil Burk882c5202018-04-23 10:32:45 -0700191 return mDataQueue->getEmptyFramesAvailable();
Phil Burk87c9f642017-05-17 07:22:39 -0700192}
193
Phil Burk5edc4ea2020-04-17 08:15:42 -0700194int32_t AudioEndpoint::getFullFramesAvailable(WrappingBuffer *wrappingBuffer) {
Phil Burk87c9f642017-05-17 07:22:39 -0700195 return mDataQueue->getFullDataAvailable(wrappingBuffer);
Phil Burk4485d412017-05-09 15:55:02 -0700196}
197
Phil Burk5edc4ea2020-04-17 08:15:42 -0700198int32_t AudioEndpoint::getFullFramesAvailable() {
Phil Burk882c5202018-04-23 10:32:45 -0700199 return mDataQueue->getFullFramesAvailable();
Phil Burk4485d412017-05-09 15:55:02 -0700200}
201
Phil Burkc0c70e32017-02-09 13:18:38 -0800202void AudioEndpoint::advanceWriteIndex(int32_t deltaFrames) {
Phil Burk882c5202018-04-23 10:32:45 -0700203 mDataQueue->advanceWriteIndex(deltaFrames);
Phil Burkc0c70e32017-02-09 13:18:38 -0800204}
205
Phil Burk87c9f642017-05-17 07:22:39 -0700206void AudioEndpoint::advanceReadIndex(int32_t deltaFrames) {
Phil Burk882c5202018-04-23 10:32:45 -0700207 mDataQueue->advanceReadIndex(deltaFrames);
Phil Burk204a1632017-01-03 17:23:43 -0800208}
209
Phil Burk5edc4ea2020-04-17 08:15:42 -0700210void AudioEndpoint::setDataReadCounter(fifo_counter_t framesRead) {
Phil Burk87c9f642017-05-17 07:22:39 -0700211 mDataQueue->setReadCounter(framesRead);
Phil Burk204a1632017-01-03 17:23:43 -0800212}
213
Phil Burk5edc4ea2020-04-17 08:15:42 -0700214fifo_counter_t AudioEndpoint::getDataReadCounter() const {
Phil Burk87c9f642017-05-17 07:22:39 -0700215 return mDataQueue->getReadCounter();
Phil Burk204a1632017-01-03 17:23:43 -0800216}
217
Phil Burk5edc4ea2020-04-17 08:15:42 -0700218void AudioEndpoint::setDataWriteCounter(fifo_counter_t framesRead) {
Phil Burk87c9f642017-05-17 07:22:39 -0700219 mDataQueue->setWriteCounter(framesRead);
220}
221
Phil Burk5edc4ea2020-04-17 08:15:42 -0700222fifo_counter_t AudioEndpoint::getDataWriteCounter() const {
Phil Burk87c9f642017-05-17 07:22:39 -0700223 return mDataQueue->getWriteCounter();
Phil Burk204a1632017-01-03 17:23:43 -0800224}
225
Phil Burk3316d5e2017-02-15 11:23:01 -0800226int32_t AudioEndpoint::setBufferSizeInFrames(int32_t requestedFrames,
Phil Burk5edc4ea2020-04-17 08:15:42 -0700227 int32_t *actualFrames) {
Phil Burk204a1632017-01-03 17:23:43 -0800228 if (requestedFrames < ENDPOINT_DATA_QUEUE_SIZE_MIN) {
229 requestedFrames = ENDPOINT_DATA_QUEUE_SIZE_MIN;
230 }
Phil Burk87c9f642017-05-17 07:22:39 -0700231 mDataQueue->setThreshold(requestedFrames);
232 *actualFrames = mDataQueue->getThreshold();
Phil Burk5ed503c2017-02-01 09:38:15 -0800233 return AAUDIO_OK;
Phil Burk204a1632017-01-03 17:23:43 -0800234}
235
Phil Burk5edc4ea2020-04-17 08:15:42 -0700236int32_t AudioEndpoint::getBufferSizeInFrames() const {
Phil Burk87c9f642017-05-17 07:22:39 -0700237 return mDataQueue->getThreshold();
Phil Burk204a1632017-01-03 17:23:43 -0800238}
239
Phil Burk5edc4ea2020-04-17 08:15:42 -0700240int32_t AudioEndpoint::getBufferCapacityInFrames() const {
Phil Burk87c9f642017-05-17 07:22:39 -0700241 return (int32_t)mDataQueue->getBufferCapacityInFrames();
Phil Burk204a1632017-01-03 17:23:43 -0800242}
243
Phil Burkec89b2e2017-06-20 15:05:06 -0700244void AudioEndpoint::dump() const {
Phil Burk5edc4ea2020-04-17 08:15:42 -0700245 ALOGD("data readCounter = %lld", (long long) getDataReadCounter());
246 ALOGD("data writeCounter = %lld", (long long) getDataWriteCounter());
Phil Burkec89b2e2017-06-20 15:05:06 -0700247}
Phil Burkea04d972017-08-07 12:30:44 -0700248
249void AudioEndpoint::eraseDataMemory() {
250 mDataQueue->eraseMemory();
251}