blob: 5cd9782528017c7569ee18b4c7c541f0a2af445c [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 Burk5ed503c2017-02-01 09:38:15 -080022#include <aaudio/AAudioDefinitions.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
31AudioEndpoint::AudioEndpoint()
32 : mOutputFreeRunning(false)
33 , mDataReadCounter(0)
34 , mDataWriteCounter(0)
35{
36}
37
38AudioEndpoint::~AudioEndpoint()
39{
40}
41
42static void AudioEndpoint_validateQueueDescriptor(const char *type,
43 const RingBufferDescriptor *descriptor) {
44 assert(descriptor->capacityInFrames > 0);
45 assert(descriptor->bytesPerFrame > 1);
46 assert(descriptor->dataAddress != nullptr);
47 ALOGD("AudioEndpoint_validateQueueDescriptor %s, dataAddress at %p ====================",
48 type,
49 descriptor->dataAddress);
50 ALOGD("AudioEndpoint_validateQueueDescriptor readCounter at %p, writeCounter at %p",
51 descriptor->readCounterAddress,
52 descriptor->writeCounterAddress);
53
54 // Try to READ from the data area.
55 uint8_t value = descriptor->dataAddress[0];
56 ALOGD("AudioEndpoint_validateQueueDescriptor() dataAddress[0] = %d, then try to write",
57 (int) value);
58 // Try to WRITE to the data area.
59 descriptor->dataAddress[0] = value;
60 ALOGD("AudioEndpoint_validateQueueDescriptor() wrote successfully");
61
62 if (descriptor->readCounterAddress) {
63 fifo_counter_t counter = *descriptor->readCounterAddress;
64 ALOGD("AudioEndpoint_validateQueueDescriptor() *readCounterAddress = %d, now write",
65 (int) counter);
66 *descriptor->readCounterAddress = counter;
67 ALOGD("AudioEndpoint_validateQueueDescriptor() wrote readCounterAddress successfully");
68 }
69 if (descriptor->writeCounterAddress) {
70 fifo_counter_t counter = *descriptor->writeCounterAddress;
71 ALOGD("AudioEndpoint_validateQueueDescriptor() *writeCounterAddress = %d, now write",
72 (int) counter);
73 *descriptor->writeCounterAddress = counter;
74 ALOGD("AudioEndpoint_validateQueueDescriptor() wrote writeCounterAddress successfully");
75 }
76}
77
78void AudioEndpoint_validateDescriptor(const EndpointDescriptor *pEndpointDescriptor) {
79 AudioEndpoint_validateQueueDescriptor("msg", &pEndpointDescriptor->upMessageQueueDescriptor);
80 AudioEndpoint_validateQueueDescriptor("data", &pEndpointDescriptor->downDataQueueDescriptor);
81}
82
Phil Burk5ed503c2017-02-01 09:38:15 -080083aaudio_result_t AudioEndpoint::configure(const EndpointDescriptor *pEndpointDescriptor)
Phil Burk204a1632017-01-03 17:23:43 -080084{
Phil Burk5ed503c2017-02-01 09:38:15 -080085 aaudio_result_t result = AAUDIO_OK;
Phil Burk204a1632017-01-03 17:23:43 -080086 AudioEndpoint_validateDescriptor(pEndpointDescriptor); // FIXME remove after debugging
87
88 const RingBufferDescriptor *descriptor = &pEndpointDescriptor->upMessageQueueDescriptor;
Phil Burk5ed503c2017-02-01 09:38:15 -080089 assert(descriptor->bytesPerFrame == sizeof(AAudioServiceMessage));
Phil Burk204a1632017-01-03 17:23:43 -080090 assert(descriptor->readCounterAddress != nullptr);
91 assert(descriptor->writeCounterAddress != nullptr);
92 mUpCommandQueue = new FifoBuffer(
93 descriptor->bytesPerFrame,
94 descriptor->capacityInFrames,
95 descriptor->readCounterAddress,
96 descriptor->writeCounterAddress,
97 descriptor->dataAddress
98 );
99 /* TODO mDownCommandQueue
100 if (descriptor->capacityInFrames > 0) {
101 descriptor = &pEndpointDescriptor->downMessageQueueDescriptor;
102 mDownCommandQueue = new FifoBuffer(
103 descriptor->capacityInFrames,
104 descriptor->bytesPerFrame,
105 descriptor->readCounterAddress,
106 descriptor->writeCounterAddress,
107 descriptor->dataAddress
108 );
109 }
110 */
111 descriptor = &pEndpointDescriptor->downDataQueueDescriptor;
112 assert(descriptor->capacityInFrames > 0);
113 assert(descriptor->bytesPerFrame > 1);
114 assert(descriptor->bytesPerFrame < 4 * 16); // FIXME just for initial debugging
115 assert(descriptor->framesPerBurst > 0);
116 assert(descriptor->framesPerBurst < 8 * 1024); // FIXME just for initial debugging
117 assert(descriptor->dataAddress != nullptr);
118 ALOGD("AudioEndpoint::configure() data framesPerBurst = %d", descriptor->framesPerBurst);
119 ALOGD("AudioEndpoint::configure() data readCounterAddress = %p", descriptor->readCounterAddress);
120 mOutputFreeRunning = descriptor->readCounterAddress == nullptr;
121 ALOGD("AudioEndpoint::configure() mOutputFreeRunning = %d", mOutputFreeRunning ? 1 : 0);
122 int64_t *readCounterAddress = (descriptor->readCounterAddress == nullptr)
123 ? &mDataReadCounter
124 : descriptor->readCounterAddress;
125 int64_t *writeCounterAddress = (descriptor->writeCounterAddress == nullptr)
126 ? &mDataWriteCounter
127 : descriptor->writeCounterAddress;
128 mDownDataQueue = new FifoBuffer(
129 descriptor->bytesPerFrame,
130 descriptor->capacityInFrames,
131 readCounterAddress,
132 writeCounterAddress,
133 descriptor->dataAddress
134 );
135 uint32_t threshold = descriptor->capacityInFrames / 2;
136 mDownDataQueue->setThreshold(threshold);
137 return result;
138}
139
Phil Burk5ed503c2017-02-01 09:38:15 -0800140aaudio_result_t AudioEndpoint::readUpCommand(AAudioServiceMessage *commandPtr)
Phil Burk204a1632017-01-03 17:23:43 -0800141{
142 return mUpCommandQueue->read(commandPtr, 1);
143}
144
Phil Burk5ed503c2017-02-01 09:38:15 -0800145aaudio_result_t AudioEndpoint::writeDataNow(const void *buffer, int32_t numFrames)
Phil Burk204a1632017-01-03 17:23:43 -0800146{
147 return mDownDataQueue->write(buffer, numFrames);
148}
149
150void AudioEndpoint::setDownDataReadCounter(fifo_counter_t framesRead)
151{
152 mDownDataQueue->setReadCounter(framesRead);
153}
154
155fifo_counter_t AudioEndpoint::getDownDataReadCounter()
156{
157 return mDownDataQueue->getReadCounter();
158}
159
160void AudioEndpoint::setDownDataWriteCounter(fifo_counter_t framesRead)
161{
162 mDownDataQueue->setWriteCounter(framesRead);
163}
164
165fifo_counter_t AudioEndpoint::getDownDataWriteCounter()
166{
167 return mDownDataQueue->getWriteCounter();
168}
169
Phil Burk5ed503c2017-02-01 09:38:15 -0800170aaudio_size_frames_t AudioEndpoint::setBufferSizeInFrames(aaudio_size_frames_t requestedFrames,
171 aaudio_size_frames_t *actualFrames)
Phil Burk204a1632017-01-03 17:23:43 -0800172{
173 if (requestedFrames < ENDPOINT_DATA_QUEUE_SIZE_MIN) {
174 requestedFrames = ENDPOINT_DATA_QUEUE_SIZE_MIN;
175 }
176 mDownDataQueue->setThreshold(requestedFrames);
177 *actualFrames = mDownDataQueue->getThreshold();
Phil Burk5ed503c2017-02-01 09:38:15 -0800178 return AAUDIO_OK;
Phil Burk204a1632017-01-03 17:23:43 -0800179}
180
181int32_t AudioEndpoint::getBufferSizeInFrames() const
182{
183 return mDownDataQueue->getThreshold();
184}
185
186int32_t AudioEndpoint::getBufferCapacityInFrames() const
187{
188 return (int32_t)mDownDataQueue->getBufferCapacityInFrames();
189}
190
191int32_t AudioEndpoint::getFullFramesAvailable()
192{
193 return mDownDataQueue->getFifoControllerBase()->getFullFramesAvailable();
194}