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 // This file is used in both client and server processes. 18 // This is needed to make sense of the logs more easily. 19 #define LOG_TAG (mInService ? "AudioStreamInternal_Service" : "AudioStreamInternal_Client") 20 //#define LOG_NDEBUG 0 21 #include <utils/Log.h> 22 23 #define ATRACE_TAG ATRACE_TAG_AUDIO 24 25 #include <stdint.h> 26 27 #include <binder/IServiceManager.h> 28 29 #include <aaudio/AAudio.h> 30 #include <cutils/properties.h> 31 #include <utils/String16.h> 32 #include <utils/Trace.h> 33 34 #include "AudioEndpointParcelable.h" 35 #include "binding/AAudioStreamRequest.h" 36 #include "binding/AAudioStreamConfiguration.h" 37 #include "binding/IAAudioService.h" 38 #include "binding/AAudioServiceMessage.h" 39 #include "core/AudioStreamBuilder.h" 40 #include "fifo/FifoBuffer.h" 41 #include "utility/AudioClock.h" 42 #include "utility/LinearRamp.h" 43 44 #include "AudioStreamInternal.h" 45 46 using android::String16; 47 using android::Mutex; 48 using android::WrappingBuffer; 49 50 using namespace aaudio; 51 52 #define MIN_TIMEOUT_NANOS (1000 * AAUDIO_NANOS_PER_MILLISECOND) 53 54 // Wait at least this many times longer than the operation should take. 55 #define MIN_TIMEOUT_OPERATIONS 4 56 57 #define LOG_TIMESTAMPS 0 58 59 AudioStreamInternal::AudioStreamInternal(AAudioServiceInterface &serviceInterface, bool inService) 60 : AudioStream() 61 , mClockModel() 62 , mAudioEndpoint() 63 , mServiceStreamHandle(AAUDIO_HANDLE_INVALID) 64 , mInService(inService) 65 , mServiceInterface(serviceInterface) 66 , mAtomicTimestamp() 67 , mWakeupDelayNanos(AAudioProperty_getWakeupDelayMicros() * AAUDIO_NANOS_PER_MICROSECOND) 68 , mMinimumSleepNanos(AAudioProperty_getMinimumSleepMicros() * AAUDIO_NANOS_PER_MICROSECOND) 69 { 70 } 71 72 AudioStreamInternal::~AudioStreamInternal() { 73 } 74 75 aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) { 76 77 aaudio_result_t result = AAUDIO_OK; 78 int32_t capacity; 79 int32_t framesPerBurst; 80 AAudioStreamRequest request; 81 AAudioStreamConfiguration configurationOutput; 82 83 if (getState() != AAUDIO_STREAM_STATE_UNINITIALIZED) { 84 ALOGE("%s - already open! state = %d", __func__, getState()); 85 return AAUDIO_ERROR_INVALID_STATE; 86 } 87 88 // Copy requested parameters to the stream. 89 result = AudioStream::open(builder); 90 if (result < 0) { 91 return result; 92 } 93 94 // We have to do volume scaling. So we prefer FLOAT format. 95 if (getFormat() == AAUDIO_FORMAT_UNSPECIFIED) { 96 setFormat(AAUDIO_FORMAT_PCM_FLOAT); 97 } 98 // Request FLOAT for the shared mixer. 99 request.getConfiguration().setFormat(AAUDIO_FORMAT_PCM_FLOAT); 100 101 // Build the request to send to the server. 102 request.setUserId(getuid()); 103 request.setProcessId(getpid()); 104 request.setSharingModeMatchRequired(isSharingModeMatchRequired()); 105 request.setInService(isInService()); 106 107 request.getConfiguration().setDeviceId(getDeviceId()); 108 request.getConfiguration().setSampleRate(getSampleRate()); 109 request.getConfiguration().setSamplesPerFrame(getSamplesPerFrame()); 110 request.getConfiguration().setDirection(getDirection()); 111 request.getConfiguration().setSharingMode(getSharingMode()); 112 113 request.getConfiguration().setUsage(getUsage()); 114 request.getConfiguration().setContentType(getContentType()); 115 request.getConfiguration().setInputPreset(getInputPreset()); 116 117 request.getConfiguration().setBufferCapacity(builder.getBufferCapacity()); 118 119 mDeviceChannelCount = getSamplesPerFrame(); // Assume it will be the same. Update if not. 120 121 mServiceStreamHandle = mServiceInterface.openStream(request, configurationOutput); 122 if (mServiceStreamHandle < 0 123 && request.getConfiguration().getSamplesPerFrame() == 1 // mono? 124 && getDirection() == AAUDIO_DIRECTION_OUTPUT 125 && !isInService()) { 126 // if that failed then try switching from mono to stereo if OUTPUT. 127 // Only do this in the client. Otherwise we end up with a mono mixer in the service 128 // that writes to a stereo MMAP stream. 129 ALOGD("%s - openStream() returned %d, try switching from MONO to STEREO", 130 __func__, mServiceStreamHandle); 131 request.getConfiguration().setSamplesPerFrame(2); // stereo 132 mServiceStreamHandle = mServiceInterface.openStream(request, configurationOutput); 133 } 134 if (mServiceStreamHandle < 0) { 135 ALOGE("%s - openStream() returned %d", __func__, mServiceStreamHandle); 136 return mServiceStreamHandle; 137 } 138 139 result = configurationOutput.validate(); 140 if (result != AAUDIO_OK) { 141 goto error; 142 } 143 // Save results of the open. 144 if (getSamplesPerFrame() == AAUDIO_UNSPECIFIED) { 145 setSamplesPerFrame(configurationOutput.getSamplesPerFrame()); 146 } 147 mDeviceChannelCount = configurationOutput.getSamplesPerFrame(); 148 149 setSampleRate(configurationOutput.getSampleRate()); 150 setDeviceId(configurationOutput.getDeviceId()); 151 setSessionId(configurationOutput.getSessionId()); 152 setSharingMode(configurationOutput.getSharingMode()); 153 154 setUsage(configurationOutput.getUsage()); 155 setContentType(configurationOutput.getContentType()); 156 setInputPreset(configurationOutput.getInputPreset()); 157 158 // Save device format so we can do format conversion and volume scaling together. 159 setDeviceFormat(configurationOutput.getFormat()); 160 161 result = mServiceInterface.getStreamDescription(mServiceStreamHandle, mEndPointParcelable); 162 if (result != AAUDIO_OK) { 163 goto error; 164 } 165 166 // Resolve parcelable into a descriptor. 167 result = mEndPointParcelable.resolve(&mEndpointDescriptor); 168 if (result != AAUDIO_OK) { 169 goto error; 170 } 171 172 // Configure endpoint based on descriptor. 173 result = mAudioEndpoint.configure(&mEndpointDescriptor, getDirection()); 174 if (result != AAUDIO_OK) { 175 goto error; 176 } 177 178 // Validate result from server. 179 framesPerBurst = mEndpointDescriptor.dataQueueDescriptor.framesPerBurst; 180 if (framesPerBurst < MIN_FRAMES_PER_BURST || framesPerBurst > MAX_FRAMES_PER_BURST) { 181 ALOGE("%s - framesPerBurst out of range = %d", __func__, framesPerBurst); 182 result = AAUDIO_ERROR_OUT_OF_RANGE; 183 goto error; 184 } 185 mFramesPerBurst = framesPerBurst; // only save good value 186 187 capacity = mEndpointDescriptor.dataQueueDescriptor.capacityInFrames; 188 if (capacity < mFramesPerBurst || capacity > MAX_BUFFER_CAPACITY_IN_FRAMES) { 189 ALOGE("%s - bufferCapacity out of range = %d", __func__, capacity); 190 result = AAUDIO_ERROR_OUT_OF_RANGE; 191 goto error; 192 } 193 194 mClockModel.setSampleRate(getSampleRate()); 195 mClockModel.setFramesPerBurst(mFramesPerBurst); 196 197 if (isDataCallbackSet()) { 198 mCallbackFrames = builder.getFramesPerDataCallback(); 199 if (mCallbackFrames > getBufferCapacity() / 2) { 200 ALOGE("%s - framesPerCallback too big = %d, capacity = %d", 201 __func__, mCallbackFrames, getBufferCapacity()); 202 result = AAUDIO_ERROR_OUT_OF_RANGE; 203 goto error; 204 205 } else if (mCallbackFrames < 0) { 206 ALOGE("%s - framesPerCallback negative", __func__); 207 result = AAUDIO_ERROR_OUT_OF_RANGE; 208 goto error; 209 210 } 211 if (mCallbackFrames == AAUDIO_UNSPECIFIED) { 212 mCallbackFrames = mFramesPerBurst; 213 } 214 215 int32_t bytesPerFrame = getSamplesPerFrame() 216 * AAudioConvert_formatToSizeInBytes(getFormat()); 217 int32_t callbackBufferSize = mCallbackFrames * bytesPerFrame; 218 mCallbackBuffer = new uint8_t[callbackBufferSize]; 219 } 220 221 setState(AAUDIO_STREAM_STATE_OPEN); 222 223 return result; 224 225 error: 226 close(); 227 return result; 228 } 229 230 aaudio_result_t AudioStreamInternal::close() { 231 aaudio_result_t result = AAUDIO_OK; 232 ALOGD("%s(): mServiceStreamHandle = 0x%08X", __func__, mServiceStreamHandle); 233 if (mServiceStreamHandle != AAUDIO_HANDLE_INVALID) { 234 // Don't close a stream while it is running. 235 aaudio_stream_state_t currentState = getState(); 236 if (isActive()) { 237 requestStop(); 238 aaudio_stream_state_t nextState; 239 int64_t timeoutNanoseconds = MIN_TIMEOUT_NANOS; 240 result = waitForStateChange(currentState, &nextState, 241 timeoutNanoseconds); 242 if (result != AAUDIO_OK) { 243 ALOGE("%s() waitForStateChange() returned %d %s", 244 __func__, result, AAudio_convertResultToText(result)); 245 } 246 } 247 setState(AAUDIO_STREAM_STATE_CLOSING); 248 aaudio_handle_t serviceStreamHandle = mServiceStreamHandle; 249 mServiceStreamHandle = AAUDIO_HANDLE_INVALID; 250 251 mServiceInterface.closeStream(serviceStreamHandle); 252 delete[] mCallbackBuffer; 253 mCallbackBuffer = nullptr; 254 255 setState(AAUDIO_STREAM_STATE_CLOSED); 256 result = mEndPointParcelable.close(); 257 aaudio_result_t result2 = AudioStream::close(); 258 return (result != AAUDIO_OK) ? result : result2; 259 } else { 260 return AAUDIO_ERROR_INVALID_HANDLE; 261 } 262 } 263 264 static void *aaudio_callback_thread_proc(void *context) 265 { 266 AudioStreamInternal *stream = (AudioStreamInternal *)context; 267 //LOGD("oboe_callback_thread, stream = %p", stream); 268 if (stream != NULL) { 269 return stream->callbackLoop(); 270 } else { 271 return NULL; 272 } 273 } 274 275 /* 276 * It normally takes about 20-30 msec to start a stream on the server. 277 * But the first time can take as much as 200-300 msec. The HW 278 * starts right away so by the time the client gets a chance to write into 279 * the buffer, it is already in a deep underflow state. That can cause the 280 * XRunCount to be non-zero, which could lead an app to tune its latency higher. 281 * To avoid this problem, we set a request for the processing code to start the 282 * client stream at the same position as the server stream. 283 * The processing code will then save the current offset 284 * between client and server and apply that to any position given to the app. 285 */ 286 aaudio_result_t AudioStreamInternal::requestStart() 287 { 288 int64_t startTime; 289 if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { 290 ALOGE("requestStart() mServiceStreamHandle invalid"); 291 return AAUDIO_ERROR_INVALID_STATE; 292 } 293 if (isActive()) { 294 ALOGE("requestStart() already active"); 295 return AAUDIO_ERROR_INVALID_STATE; 296 } 297 298 aaudio_stream_state_t originalState = getState(); 299 if (originalState == AAUDIO_STREAM_STATE_DISCONNECTED) { 300 ALOGE("requestStart() but DISCONNECTED"); 301 return AAUDIO_ERROR_DISCONNECTED; 302 } 303 setState(AAUDIO_STREAM_STATE_STARTING); 304 305 // Clear any stale timestamps from the previous run. 306 drainTimestampsFromService(); 307 308 aaudio_result_t result = mServiceInterface.startStream(mServiceStreamHandle); 309 310 startTime = AudioClock::getNanoseconds(); 311 mClockModel.start(startTime); 312 mNeedCatchUp.request(); // Ask data processing code to catch up when first timestamp received. 313 314 // Start data callback thread. 315 if (result == AAUDIO_OK && isDataCallbackSet()) { 316 // Launch the callback loop thread. 317 int64_t periodNanos = mCallbackFrames 318 * AAUDIO_NANOS_PER_SECOND 319 / getSampleRate(); 320 mCallbackEnabled.store(true); 321 result = createThread(periodNanos, aaudio_callback_thread_proc, this); 322 } 323 if (result != AAUDIO_OK) { 324 setState(originalState); 325 } 326 return result; 327 } 328 329 int64_t AudioStreamInternal::calculateReasonableTimeout(int32_t framesPerOperation) { 330 331 // Wait for at least a second or some number of callbacks to join the thread. 332 int64_t timeoutNanoseconds = (MIN_TIMEOUT_OPERATIONS 333 * framesPerOperation 334 * AAUDIO_NANOS_PER_SECOND) 335 / getSampleRate(); 336 if (timeoutNanoseconds < MIN_TIMEOUT_NANOS) { // arbitrary number of seconds 337 timeoutNanoseconds = MIN_TIMEOUT_NANOS; 338 } 339 return timeoutNanoseconds; 340 } 341 342 int64_t AudioStreamInternal::calculateReasonableTimeout() { 343 return calculateReasonableTimeout(getFramesPerBurst()); 344 } 345 346 aaudio_result_t AudioStreamInternal::stopCallback() 347 { 348 if (isDataCallbackActive()) { 349 mCallbackEnabled.store(false); 350 return joinThread(NULL); 351 } else { 352 return AAUDIO_OK; 353 } 354 } 355 356 aaudio_result_t AudioStreamInternal::requestStop() 357 { 358 aaudio_result_t result = stopCallback(); 359 if (result != AAUDIO_OK) { 360 return result; 361 } 362 363 if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { 364 ALOGE("requestStopInternal() mServiceStreamHandle invalid = 0x%08X", 365 mServiceStreamHandle); 366 return AAUDIO_ERROR_INVALID_STATE; 367 } 368 369 mClockModel.stop(AudioClock::getNanoseconds()); 370 setState(AAUDIO_STREAM_STATE_STOPPING); 371 mAtomicTimestamp.clear(); 372 373 return mServiceInterface.stopStream(mServiceStreamHandle); 374 } 375 376 aaudio_result_t AudioStreamInternal::registerThread() { 377 if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { 378 ALOGE("registerThread() mServiceStreamHandle invalid"); 379 return AAUDIO_ERROR_INVALID_STATE; 380 } 381 return mServiceInterface.registerAudioThread(mServiceStreamHandle, 382 gettid(), 383 getPeriodNanoseconds()); 384 } 385 386 aaudio_result_t AudioStreamInternal::unregisterThread() { 387 if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { 388 ALOGE("unregisterThread() mServiceStreamHandle invalid"); 389 return AAUDIO_ERROR_INVALID_STATE; 390 } 391 return mServiceInterface.unregisterAudioThread(mServiceStreamHandle, gettid()); 392 } 393 394 aaudio_result_t AudioStreamInternal::startClient(const android::AudioClient& client, 395 audio_port_handle_t *portHandle) { 396 ALOGV("%s() called", __func__); 397 if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { 398 return AAUDIO_ERROR_INVALID_STATE; 399 } 400 aaudio_result_t result = mServiceInterface.startClient(mServiceStreamHandle, 401 client, portHandle); 402 ALOGV("%s(%d) returning %d", __func__, *portHandle, result); 403 return result; 404 } 405 406 aaudio_result_t AudioStreamInternal::stopClient(audio_port_handle_t portHandle) { 407 ALOGV("%s(%d) called", __func__, portHandle); 408 if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { 409 return AAUDIO_ERROR_INVALID_STATE; 410 } 411 aaudio_result_t result = mServiceInterface.stopClient(mServiceStreamHandle, portHandle); 412 ALOGV("%s(%d) returning %d", __func__, portHandle, result); 413 return result; 414 } 415 416 aaudio_result_t AudioStreamInternal::getTimestamp(clockid_t clockId, 417 int64_t *framePosition, 418 int64_t *timeNanoseconds) { 419 // Generated in server and passed to client. Return latest. 420 if (mAtomicTimestamp.isValid()) { 421 Timestamp timestamp = mAtomicTimestamp.read(); 422 int64_t position = timestamp.getPosition() + mFramesOffsetFromService; 423 if (position >= 0) { 424 *framePosition = position; 425 *timeNanoseconds = timestamp.getNanoseconds(); 426 return AAUDIO_OK; 427 } 428 } 429 return AAUDIO_ERROR_INVALID_STATE; 430 } 431 432 aaudio_result_t AudioStreamInternal::updateStateMachine() { 433 if (isDataCallbackActive()) { 434 return AAUDIO_OK; // state is getting updated by the callback thread read/write call 435 } 436 return processCommands(); 437 } 438 439 void AudioStreamInternal::logTimestamp(AAudioServiceMessage &command) { 440 static int64_t oldPosition = 0; 441 static int64_t oldTime = 0; 442 int64_t framePosition = command.timestamp.position; 443 int64_t nanoTime = command.timestamp.timestamp; 444 ALOGD("logTimestamp: timestamp says framePosition = %8lld at nanoTime %lld", 445 (long long) framePosition, 446 (long long) nanoTime); 447 int64_t nanosDelta = nanoTime - oldTime; 448 if (nanosDelta > 0 && oldTime > 0) { 449 int64_t framesDelta = framePosition - oldPosition; 450 int64_t rate = (framesDelta * AAUDIO_NANOS_PER_SECOND) / nanosDelta; 451 ALOGD("logTimestamp: framesDelta = %8lld, nanosDelta = %8lld, rate = %lld", 452 (long long) framesDelta, (long long) nanosDelta, (long long) rate); 453 } 454 oldPosition = framePosition; 455 oldTime = nanoTime; 456 } 457 458 aaudio_result_t AudioStreamInternal::onTimestampService(AAudioServiceMessage *message) { 459 #if LOG_TIMESTAMPS 460 logTimestamp(*message); 461 #endif 462 processTimestamp(message->timestamp.position, message->timestamp.timestamp); 463 return AAUDIO_OK; 464 } 465 466 aaudio_result_t AudioStreamInternal::onTimestampHardware(AAudioServiceMessage *message) { 467 Timestamp timestamp(message->timestamp.position, message->timestamp.timestamp); 468 mAtomicTimestamp.write(timestamp); 469 return AAUDIO_OK; 470 } 471 472 aaudio_result_t AudioStreamInternal::onEventFromServer(AAudioServiceMessage *message) { 473 aaudio_result_t result = AAUDIO_OK; 474 switch (message->event.event) { 475 case AAUDIO_SERVICE_EVENT_STARTED: 476 ALOGD("%s - got AAUDIO_SERVICE_EVENT_STARTED", __func__); 477 if (getState() == AAUDIO_STREAM_STATE_STARTING) { 478 setState(AAUDIO_STREAM_STATE_STARTED); 479 } 480 break; 481 case AAUDIO_SERVICE_EVENT_PAUSED: 482 ALOGD("%s - got AAUDIO_SERVICE_EVENT_PAUSED", __func__); 483 if (getState() == AAUDIO_STREAM_STATE_PAUSING) { 484 setState(AAUDIO_STREAM_STATE_PAUSED); 485 } 486 break; 487 case AAUDIO_SERVICE_EVENT_STOPPED: 488 ALOGD("%s - got AAUDIO_SERVICE_EVENT_STOPPED", __func__); 489 if (getState() == AAUDIO_STREAM_STATE_STOPPING) { 490 setState(AAUDIO_STREAM_STATE_STOPPED); 491 } 492 break; 493 case AAUDIO_SERVICE_EVENT_FLUSHED: 494 ALOGD("%s - got AAUDIO_SERVICE_EVENT_FLUSHED", __func__); 495 if (getState() == AAUDIO_STREAM_STATE_FLUSHING) { 496 setState(AAUDIO_STREAM_STATE_FLUSHED); 497 onFlushFromServer(); 498 } 499 break; 500 case AAUDIO_SERVICE_EVENT_DISCONNECTED: 501 // Prevent hardware from looping on old data and making buzzing sounds. 502 if (getDirection() == AAUDIO_DIRECTION_OUTPUT) { 503 mAudioEndpoint.eraseDataMemory(); 504 } 505 result = AAUDIO_ERROR_DISCONNECTED; 506 setState(AAUDIO_STREAM_STATE_DISCONNECTED); 507 ALOGW("%s - AAUDIO_SERVICE_EVENT_DISCONNECTED - FIFO cleared", __func__); 508 break; 509 case AAUDIO_SERVICE_EVENT_VOLUME: 510 ALOGD("%s - AAUDIO_SERVICE_EVENT_VOLUME %lf", __func__, message->event.dataDouble); 511 mStreamVolume = (float)message->event.dataDouble; 512 doSetVolume(); 513 break; 514 case AAUDIO_SERVICE_EVENT_XRUN: 515 mXRunCount = static_cast<int32_t>(message->event.dataLong); 516 break; 517 default: 518 ALOGE("%s - Unrecognized event = %d", __func__, (int) message->event.event); 519 break; 520 } 521 return result; 522 } 523 524 aaudio_result_t AudioStreamInternal::drainTimestampsFromService() { 525 aaudio_result_t result = AAUDIO_OK; 526 527 while (result == AAUDIO_OK) { 528 AAudioServiceMessage message; 529 if (mAudioEndpoint.readUpCommand(&message) != 1) { 530 break; // no command this time, no problem 531 } 532 switch (message.what) { 533 // ignore most messages 534 case AAudioServiceMessage::code::TIMESTAMP_SERVICE: 535 case AAudioServiceMessage::code::TIMESTAMP_HARDWARE: 536 break; 537 538 case AAudioServiceMessage::code::EVENT: 539 result = onEventFromServer(&message); 540 break; 541 542 default: 543 ALOGE("%s - unrecognized message.what = %d", __func__, (int) message.what); 544 result = AAUDIO_ERROR_INTERNAL; 545 break; 546 } 547 } 548 return result; 549 } 550 551 // Process all the commands coming from the server. 552 aaudio_result_t AudioStreamInternal::processCommands() { 553 aaudio_result_t result = AAUDIO_OK; 554 555 while (result == AAUDIO_OK) { 556 AAudioServiceMessage message; 557 if (mAudioEndpoint.readUpCommand(&message) != 1) { 558 break; // no command this time, no problem 559 } 560 switch (message.what) { 561 case AAudioServiceMessage::code::TIMESTAMP_SERVICE: 562 result = onTimestampService(&message); 563 break; 564 565 case AAudioServiceMessage::code::TIMESTAMP_HARDWARE: 566 result = onTimestampHardware(&message); 567 break; 568 569 case AAudioServiceMessage::code::EVENT: 570 result = onEventFromServer(&message); 571 break; 572 573 default: 574 ALOGE("%s - unrecognized message.what = %d", __func__, (int) message.what); 575 result = AAUDIO_ERROR_INTERNAL; 576 break; 577 } 578 } 579 return result; 580 } 581 582 // Read or write the data, block if needed and timeoutMillis > 0 583 aaudio_result_t AudioStreamInternal::processData(void *buffer, int32_t numFrames, 584 int64_t timeoutNanoseconds) 585 { 586 const char * traceName = "aaProc"; 587 const char * fifoName = "aaRdy"; 588 ATRACE_BEGIN(traceName); 589 if (ATRACE_ENABLED()) { 590 int32_t fullFrames = mAudioEndpoint.getFullFramesAvailable(); 591 ATRACE_INT(fifoName, fullFrames); 592 } 593 594 aaudio_result_t result = AAUDIO_OK; 595 int32_t loopCount = 0; 596 uint8_t* audioData = (uint8_t*)buffer; 597 int64_t currentTimeNanos = AudioClock::getNanoseconds(); 598 const int64_t entryTimeNanos = currentTimeNanos; 599 const int64_t deadlineNanos = currentTimeNanos + timeoutNanoseconds; 600 int32_t framesLeft = numFrames; 601 602 // Loop until all the data has been processed or until a timeout occurs. 603 while (framesLeft > 0) { 604 // The call to processDataNow() will not block. It will just process as much as it can. 605 int64_t wakeTimeNanos = 0; 606 aaudio_result_t framesProcessed = processDataNow(audioData, framesLeft, 607 currentTimeNanos, &wakeTimeNanos); 608 if (framesProcessed < 0) { 609 result = framesProcessed; 610 break; 611 } 612 framesLeft -= (int32_t) framesProcessed; 613 audioData += framesProcessed * getBytesPerFrame(); 614 615 // Should we block? 616 if (timeoutNanoseconds == 0) { 617 break; // don't block 618 } else if (framesLeft > 0) { 619 if (!mAudioEndpoint.isFreeRunning()) { 620 // If there is software on the other end of the FIFO then it may get delayed. 621 // So wake up just a little after we expect it to be ready. 622 wakeTimeNanos += mWakeupDelayNanos; 623 } 624 625 currentTimeNanos = AudioClock::getNanoseconds(); 626 int64_t earliestWakeTime = currentTimeNanos + mMinimumSleepNanos; 627 // Guarantee a minimum sleep time. 628 if (wakeTimeNanos < earliestWakeTime) { 629 wakeTimeNanos = earliestWakeTime; 630 } 631 632 if (wakeTimeNanos > deadlineNanos) { 633 // If we time out, just return the framesWritten so far. 634 // TODO remove after we fix the deadline bug 635 ALOGW("processData(): entered at %lld nanos, currently %lld", 636 (long long) entryTimeNanos, (long long) currentTimeNanos); 637 ALOGW("processData(): TIMEOUT after %lld nanos", 638 (long long) timeoutNanoseconds); 639 ALOGW("processData(): wakeTime = %lld, deadline = %lld nanos", 640 (long long) wakeTimeNanos, (long long) deadlineNanos); 641 ALOGW("processData(): past deadline by %d micros", 642 (int)((wakeTimeNanos - deadlineNanos) / AAUDIO_NANOS_PER_MICROSECOND)); 643 mClockModel.dump(); 644 mAudioEndpoint.dump(); 645 break; 646 } 647 648 if (ATRACE_ENABLED()) { 649 int32_t fullFrames = mAudioEndpoint.getFullFramesAvailable(); 650 ATRACE_INT(fifoName, fullFrames); 651 int64_t sleepForNanos = wakeTimeNanos - currentTimeNanos; 652 ATRACE_INT("aaSlpNs", (int32_t)sleepForNanos); 653 } 654 655 AudioClock::sleepUntilNanoTime(wakeTimeNanos); 656 currentTimeNanos = AudioClock::getNanoseconds(); 657 } 658 } 659 660 if (ATRACE_ENABLED()) { 661 int32_t fullFrames = mAudioEndpoint.getFullFramesAvailable(); 662 ATRACE_INT(fifoName, fullFrames); 663 } 664 665 // return error or framesProcessed 666 (void) loopCount; 667 ATRACE_END(); 668 return (result < 0) ? result : numFrames - framesLeft; 669 } 670 671 void AudioStreamInternal::processTimestamp(uint64_t position, int64_t time) { 672 mClockModel.processTimestamp(position, time); 673 } 674 675 aaudio_result_t AudioStreamInternal::setBufferSize(int32_t requestedFrames) { 676 int32_t adjustedFrames = requestedFrames; 677 int32_t actualFrames = 0; 678 int32_t maximumSize = getBufferCapacity(); 679 680 // Clip to minimum size so that rounding up will work better. 681 if (adjustedFrames < 1) { 682 adjustedFrames = 1; 683 } 684 685 if (adjustedFrames > maximumSize) { 686 // Clip to maximum size. 687 adjustedFrames = maximumSize; 688 } else { 689 // Round to the next highest burst size. 690 int32_t numBursts = (adjustedFrames + mFramesPerBurst - 1) / mFramesPerBurst; 691 adjustedFrames = numBursts * mFramesPerBurst; 692 // Rounding may have gone above maximum. 693 if (adjustedFrames > maximumSize) { 694 adjustedFrames = maximumSize; 695 } 696 } 697 698 aaudio_result_t result = mAudioEndpoint.setBufferSizeInFrames(adjustedFrames, &actualFrames); 699 ALOGD("setBufferSize() req = %d => %d", requestedFrames, actualFrames); 700 if (result < 0) { 701 return result; 702 } else { 703 return (aaudio_result_t) actualFrames; 704 } 705 } 706 707 int32_t AudioStreamInternal::getBufferSize() const { 708 return mAudioEndpoint.getBufferSizeInFrames(); 709 } 710 711 int32_t AudioStreamInternal::getBufferCapacity() const { 712 return mAudioEndpoint.getBufferCapacityInFrames(); 713 } 714 715 int32_t AudioStreamInternal::getFramesPerBurst() const { 716 return mFramesPerBurst; 717 } 718 719 aaudio_result_t AudioStreamInternal::joinThread(void** returnArg) { 720 return AudioStream::joinThread(returnArg, calculateReasonableTimeout(getFramesPerBurst())); 721 } 722