AudioStreamInternal.cpp revision 3316d5e6d375a4f09c681205e9094d30a0bfc4a2
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 <stdint.h> 22#include <assert.h> 23 24#include <binder/IServiceManager.h> 25#include <utils/Mutex.h> 26 27#include <aaudio/AAudio.h> 28 29#include "AudioClock.h" 30#include "AudioEndpointParcelable.h" 31#include "binding/AAudioStreamRequest.h" 32#include "binding/AAudioStreamConfiguration.h" 33#include "binding/IAAudioService.h" 34#include "binding/AAudioServiceMessage.h" 35 36#include "core/AudioStreamBuilder.h" 37#include "AudioStreamInternal.h" 38 39#define LOG_TIMESTAMPS 0 40 41using android::String16; 42using android::IServiceManager; 43using android::defaultServiceManager; 44using android::interface_cast; 45using android::Mutex; 46 47using namespace aaudio; 48 49static android::Mutex gServiceLock; 50static sp<IAAudioService> gAAudioService; 51 52#define AAUDIO_SERVICE_NAME "AAudioService" 53 54// Helper function to get access to the "AAudioService" service. 55// This code was modeled after frameworks/av/media/libaudioclient/AudioSystem.cpp 56static const sp<IAAudioService> getAAudioService() { 57 sp<IBinder> binder; 58 Mutex::Autolock _l(gServiceLock); 59 if (gAAudioService == 0) { 60 sp<IServiceManager> sm = defaultServiceManager(); 61 // Try several times to get the service. 62 int retries = 4; 63 do { 64 binder = sm->getService(String16(AAUDIO_SERVICE_NAME)); // This will wait a while. 65 if (binder != 0) { 66 break; 67 } 68 } while (retries-- > 0); 69 70 if (binder != 0) { 71 // TODO Add linkToDeath() like in frameworks/av/media/libaudioclient/AudioSystem.cpp 72 // TODO Create a DeathRecipient that disconnects all active streams. 73 gAAudioService = interface_cast<IAAudioService>(binder); 74 } else { 75 ALOGE("AudioStreamInternal could not get %s", AAUDIO_SERVICE_NAME); 76 } 77 } 78 return gAAudioService; 79} 80 81AudioStreamInternal::AudioStreamInternal() 82 : AudioStream() 83 , mClockModel() 84 , mAudioEndpoint() 85 , mServiceStreamHandle(AAUDIO_HANDLE_INVALID) 86 , mFramesPerBurst(16) 87{ 88} 89 90AudioStreamInternal::~AudioStreamInternal() { 91} 92 93aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) { 94 95 const sp<IAAudioService>& service = getAAudioService(); 96 if (service == 0) return AAUDIO_ERROR_NO_SERVICE; 97 98 aaudio_result_t result = AAUDIO_OK; 99 AAudioStreamRequest request; 100 AAudioStreamConfiguration configuration; 101 102 result = AudioStream::open(builder); 103 if (result < 0) { 104 return result; 105 } 106 107 // Build the request to send to the server. 108 request.setUserId(getuid()); 109 request.setProcessId(getpid()); 110 request.getConfiguration().setDeviceId(getDeviceId()); 111 request.getConfiguration().setSampleRate(getSampleRate()); 112 request.getConfiguration().setSamplesPerFrame(getSamplesPerFrame()); 113 request.getConfiguration().setAudioFormat(getFormat()); 114 request.getConfiguration().setBufferCapacity(builder.getBufferCapacity()); 115 request.dump(); 116 117 mServiceStreamHandle = service->openStream(request, configuration); 118 ALOGD("AudioStreamInternal.open(): openStream returned mServiceStreamHandle = 0x%08X", 119 (unsigned int)mServiceStreamHandle); 120 if (mServiceStreamHandle < 0) { 121 result = mServiceStreamHandle; 122 ALOGE("AudioStreamInternal.open(): acquireRealtimeStream aaudio_result_t = 0x%08X", result); 123 } else { 124 result = configuration.validate(); 125 if (result != AAUDIO_OK) { 126 close(); 127 return result; 128 } 129 // Save results of the open. 130 setSampleRate(configuration.getSampleRate()); 131 setSamplesPerFrame(configuration.getSamplesPerFrame()); 132 setFormat(configuration.getAudioFormat()); 133 134 aaudio::AudioEndpointParcelable parcelable; 135 result = service->getStreamDescription(mServiceStreamHandle, parcelable); 136 if (result != AAUDIO_OK) { 137 ALOGE("AudioStreamInternal.open(): getStreamDescriptor returns %d", result); 138 service->closeStream(mServiceStreamHandle); 139 return result; 140 } 141 // resolve parcelable into a descriptor 142 parcelable.resolve(&mEndpointDescriptor); 143 144 // Configure endpoint based on descriptor. 145 mAudioEndpoint.configure(&mEndpointDescriptor); 146 147 mFramesPerBurst = mEndpointDescriptor.downDataQueueDescriptor.framesPerBurst; 148 assert(mFramesPerBurst >= 16); 149 assert(mEndpointDescriptor.downDataQueueDescriptor.capacityInFrames < 10 * 1024); 150 151 mClockModel.setSampleRate(getSampleRate()); 152 mClockModel.setFramesPerBurst(mFramesPerBurst); 153 154 setState(AAUDIO_STREAM_STATE_OPEN); 155 } 156 return result; 157} 158 159aaudio_result_t AudioStreamInternal::close() { 160 ALOGD("AudioStreamInternal.close(): mServiceStreamHandle = 0x%08X", mServiceStreamHandle); 161 if (mServiceStreamHandle != AAUDIO_HANDLE_INVALID) { 162 aaudio_handle_t serviceStreamHandle = mServiceStreamHandle; 163 mServiceStreamHandle = AAUDIO_HANDLE_INVALID; 164 const sp<IAAudioService>& aaudioService = getAAudioService(); 165 if (aaudioService == 0) return AAUDIO_ERROR_NO_SERVICE; 166 aaudioService->closeStream(serviceStreamHandle); 167 return AAUDIO_OK; 168 } else { 169 return AAUDIO_ERROR_INVALID_HANDLE; 170 } 171} 172 173aaudio_result_t AudioStreamInternal::requestStart() 174{ 175 int64_t startTime; 176 ALOGD("AudioStreamInternal(): start()"); 177 if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { 178 return AAUDIO_ERROR_INVALID_STATE; 179 } 180 const sp<IAAudioService>& aaudioService = getAAudioService(); 181 if (aaudioService == 0) return AAUDIO_ERROR_NO_SERVICE; 182 startTime = AudioClock::getNanoseconds(); 183 mClockModel.start(startTime); 184 processTimestamp(0, startTime); 185 setState(AAUDIO_STREAM_STATE_STARTING); 186 return aaudioService->startStream(mServiceStreamHandle); 187} 188 189aaudio_result_t AudioStreamInternal::requestPause() 190{ 191 ALOGD("AudioStreamInternal(): pause()"); 192 if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { 193 return AAUDIO_ERROR_INVALID_STATE; 194 } 195 const sp<IAAudioService>& aaudioService = getAAudioService(); 196 if (aaudioService == 0) return AAUDIO_ERROR_NO_SERVICE; 197 mClockModel.stop(AudioClock::getNanoseconds()); 198 setState(AAUDIO_STREAM_STATE_PAUSING); 199 return aaudioService->pauseStream(mServiceStreamHandle); 200} 201 202aaudio_result_t AudioStreamInternal::requestFlush() { 203 ALOGD("AudioStreamInternal(): flush()"); 204 if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { 205 return AAUDIO_ERROR_INVALID_STATE; 206 } 207 const sp<IAAudioService>& aaudioService = getAAudioService(); 208 if (aaudioService == 0) return AAUDIO_ERROR_NO_SERVICE; 209setState(AAUDIO_STREAM_STATE_FLUSHING); 210 return aaudioService->flushStream(mServiceStreamHandle); 211} 212 213void AudioStreamInternal::onFlushFromServer() { 214 ALOGD("AudioStreamInternal(): onFlushFromServer()"); 215 int64_t readCounter = mAudioEndpoint.getDownDataReadCounter(); 216 int64_t writeCounter = mAudioEndpoint.getDownDataWriteCounter(); 217 // Bump offset so caller does not see the retrograde motion in getFramesRead(). 218 int64_t framesFlushed = writeCounter - readCounter; 219 mFramesOffsetFromService += framesFlushed; 220 // Flush written frames by forcing writeCounter to readCounter. 221 // This is because we cannot move the read counter in the hardware. 222 mAudioEndpoint.setDownDataWriteCounter(readCounter); 223} 224 225aaudio_result_t AudioStreamInternal::requestStop() 226{ 227 // TODO better implementation of requestStop() 228 aaudio_result_t result = requestPause(); 229 if (result == AAUDIO_OK) { 230 aaudio_stream_state_t state; 231 result = waitForStateChange(AAUDIO_STREAM_STATE_PAUSING, 232 &state, 233 500 * AAUDIO_NANOS_PER_MILLISECOND);// TODO temporary code 234 if (result == AAUDIO_OK) { 235 result = requestFlush(); 236 } 237 } 238 return result; 239} 240 241aaudio_result_t AudioStreamInternal::registerThread() { 242 ALOGD("AudioStreamInternal(): registerThread()"); 243 if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { 244 return AAUDIO_ERROR_INVALID_STATE; 245 } 246 const sp<IAAudioService>& aaudioService = getAAudioService(); 247 if (aaudioService == 0) return AAUDIO_ERROR_NO_SERVICE; 248 return aaudioService->registerAudioThread(mServiceStreamHandle, 249 gettid(), 250 getPeriodNanoseconds()); 251} 252 253aaudio_result_t AudioStreamInternal::unregisterThread() { 254 ALOGD("AudioStreamInternal(): unregisterThread()"); 255 if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { 256 return AAUDIO_ERROR_INVALID_STATE; 257 } 258 const sp<IAAudioService>& aaudioService = getAAudioService(); 259 if (aaudioService == 0) return AAUDIO_ERROR_NO_SERVICE; 260 return aaudioService->unregisterAudioThread(mServiceStreamHandle, gettid()); 261} 262 263// TODO use aaudio_clockid_t all the way down to AudioClock 264aaudio_result_t AudioStreamInternal::getTimestamp(clockid_t clockId, 265 int64_t *framePosition, 266 int64_t *timeNanoseconds) { 267// TODO implement using real HAL 268 int64_t time = AudioClock::getNanoseconds(); 269 *framePosition = mClockModel.convertTimeToPosition(time); 270 *timeNanoseconds = time + (10 * AAUDIO_NANOS_PER_MILLISECOND); // Fake hardware delay 271 return AAUDIO_OK; 272} 273 274aaudio_result_t AudioStreamInternal::updateState() { 275 return processCommands(); 276} 277 278#if LOG_TIMESTAMPS 279static void AudioStreamInternal_LogTimestamp(AAudioServiceMessage &command) { 280 static int64_t oldPosition = 0; 281 static int64_t oldTime = 0; 282 int64_t framePosition = command.timestamp.position; 283 int64_t nanoTime = command.timestamp.timestamp; 284 ALOGD("AudioStreamInternal() timestamp says framePosition = %08lld at nanoTime %llu", 285 (long long) framePosition, 286 (long long) nanoTime); 287 int64_t nanosDelta = nanoTime - oldTime; 288 if (nanosDelta > 0 && oldTime > 0) { 289 int64_t framesDelta = framePosition - oldPosition; 290 int64_t rate = (framesDelta * AAUDIO_NANOS_PER_SECOND) / nanosDelta; 291 ALOGD("AudioStreamInternal() - framesDelta = %08lld", (long long) framesDelta); 292 ALOGD("AudioStreamInternal() - nanosDelta = %08lld", (long long) nanosDelta); 293 ALOGD("AudioStreamInternal() - measured rate = %llu", (unsigned long long) rate); 294 } 295 oldPosition = framePosition; 296 oldTime = nanoTime; 297} 298#endif 299 300aaudio_result_t AudioStreamInternal::onTimestampFromServer(AAudioServiceMessage *message) { 301 int64_t framePosition = 0; 302#if LOG_TIMESTAMPS 303 AudioStreamInternal_LogTimestamp(command); 304#endif 305 framePosition = message->timestamp.position; 306 processTimestamp(framePosition, message->timestamp.timestamp); 307 return AAUDIO_OK; 308} 309 310aaudio_result_t AudioStreamInternal::onEventFromServer(AAudioServiceMessage *message) { 311 aaudio_result_t result = AAUDIO_OK; 312 ALOGD("processCommands() got event %d", message->event.event); 313 switch (message->event.event) { 314 case AAUDIO_SERVICE_EVENT_STARTED: 315 ALOGD("processCommands() got AAUDIO_SERVICE_EVENT_STARTED"); 316 setState(AAUDIO_STREAM_STATE_STARTED); 317 break; 318 case AAUDIO_SERVICE_EVENT_PAUSED: 319 ALOGD("processCommands() got AAUDIO_SERVICE_EVENT_PAUSED"); 320 setState(AAUDIO_STREAM_STATE_PAUSED); 321 break; 322 case AAUDIO_SERVICE_EVENT_FLUSHED: 323 ALOGD("processCommands() got AAUDIO_SERVICE_EVENT_FLUSHED"); 324 setState(AAUDIO_STREAM_STATE_FLUSHED); 325 onFlushFromServer(); 326 break; 327 case AAUDIO_SERVICE_EVENT_CLOSED: 328 ALOGD("processCommands() got AAUDIO_SERVICE_EVENT_CLOSED"); 329 setState(AAUDIO_STREAM_STATE_CLOSED); 330 break; 331 case AAUDIO_SERVICE_EVENT_DISCONNECTED: 332 result = AAUDIO_ERROR_DISCONNECTED; 333 ALOGW("WARNING - processCommands() AAUDIO_SERVICE_EVENT_DISCONNECTED"); 334 break; 335 default: 336 ALOGW("WARNING - processCommands() Unrecognized event = %d", 337 (int) message->event.event); 338 break; 339 } 340 return result; 341} 342 343// Process all the commands coming from the server. 344aaudio_result_t AudioStreamInternal::processCommands() { 345 aaudio_result_t result = AAUDIO_OK; 346 347 while (result == AAUDIO_OK) { 348 AAudioServiceMessage message; 349 if (mAudioEndpoint.readUpCommand(&message) != 1) { 350 break; // no command this time, no problem 351 } 352 switch (message.what) { 353 case AAudioServiceMessage::code::TIMESTAMP: 354 result = onTimestampFromServer(&message); 355 break; 356 357 case AAudioServiceMessage::code::EVENT: 358 result = onEventFromServer(&message); 359 break; 360 361 default: 362 ALOGW("WARNING - AudioStreamInternal::processCommands() Unrecognized what = %d", 363 (int) message.what); 364 result = AAUDIO_ERROR_UNEXPECTED_VALUE; 365 break; 366 } 367 } 368 return result; 369} 370 371// Write the data, block if needed and timeoutMillis > 0 372aaudio_result_t AudioStreamInternal::write(const void *buffer, int32_t numFrames, 373 int64_t timeoutNanoseconds) 374{ 375 aaudio_result_t result = AAUDIO_OK; 376 uint8_t* source = (uint8_t*)buffer; 377 int64_t currentTimeNanos = AudioClock::getNanoseconds(); 378 int64_t deadlineNanos = currentTimeNanos + timeoutNanoseconds; 379 int32_t framesLeft = numFrames; 380// ALOGD("AudioStreamInternal::write(%p, %d) at time %08llu , mState = %d ------------------", 381// buffer, numFrames, (unsigned long long) currentTimeNanos, mState); 382 383 // Write until all the data has been written or until a timeout occurs. 384 while (framesLeft > 0) { 385 // The call to writeNow() will not block. It will just write as much as it can. 386 int64_t wakeTimeNanos = 0; 387 aaudio_result_t framesWritten = writeNow(source, framesLeft, 388 currentTimeNanos, &wakeTimeNanos); 389// ALOGD("AudioStreamInternal::write() writeNow() framesLeft = %d --> framesWritten = %d", framesLeft, framesWritten); 390 if (framesWritten < 0) { 391 result = framesWritten; 392 break; 393 } 394 framesLeft -= (int32_t) framesWritten; 395 source += framesWritten * getBytesPerFrame(); 396 397 // Should we block? 398 if (timeoutNanoseconds == 0) { 399 break; // don't block 400 } else if (framesLeft > 0) { 401 //ALOGD("AudioStreamInternal:: original wakeTimeNanos %lld", (long long) wakeTimeNanos); 402 // clip the wake time to something reasonable 403 if (wakeTimeNanos < currentTimeNanos) { 404 wakeTimeNanos = currentTimeNanos; 405 } 406 if (wakeTimeNanos > deadlineNanos) { 407 // If we time out, just return the framesWritten so far. 408 ALOGE("AudioStreamInternal::write(): timed out after %lld nanos", (long long) timeoutNanoseconds); 409 break; 410 } 411 412 //ALOGD("AudioStreamInternal:: sleep until %lld, dur = %lld", (long long) wakeTimeNanos, 413 // (long long) (wakeTimeNanos - currentTimeNanos)); 414 AudioClock::sleepForNanos(wakeTimeNanos - currentTimeNanos); 415 currentTimeNanos = AudioClock::getNanoseconds(); 416 } 417 } 418 419 // return error or framesWritten 420 return (result < 0) ? result : numFrames - framesLeft; 421} 422 423// Write as much data as we can without blocking. 424aaudio_result_t AudioStreamInternal::writeNow(const void *buffer, int32_t numFrames, 425 int64_t currentNanoTime, int64_t *wakeTimePtr) { 426 { 427 aaudio_result_t result = processCommands(); 428 if (result != AAUDIO_OK) { 429 return result; 430 } 431 } 432 433 if (mAudioEndpoint.isOutputFreeRunning()) { 434 // Update data queue based on the timing model. 435 int64_t estimatedReadCounter = mClockModel.convertTimeToPosition(currentNanoTime); 436 mAudioEndpoint.setDownDataReadCounter(estimatedReadCounter); 437 // If the read index passed the write index then consider it an underrun. 438 if (mAudioEndpoint.getFullFramesAvailable() < 0) { 439 mXRunCount++; 440 } 441 } 442 // TODO else query from endpoint cuz set by actual reader, maybe 443 444 // Write some data to the buffer. 445 int32_t framesWritten = mAudioEndpoint.writeDataNow(buffer, numFrames); 446 if (framesWritten > 0) { 447 incrementFramesWritten(framesWritten); 448 } 449 //ALOGD("AudioStreamInternal::writeNow() - tried to write %d frames, wrote %d", 450 // numFrames, framesWritten); 451 452 // Calculate an ideal time to wake up. 453 if (wakeTimePtr != nullptr && framesWritten >= 0) { 454 // By default wake up a few milliseconds from now. // TODO review 455 int64_t wakeTime = currentNanoTime + (2 * AAUDIO_NANOS_PER_MILLISECOND); 456 switch (getState()) { 457 case AAUDIO_STREAM_STATE_OPEN: 458 case AAUDIO_STREAM_STATE_STARTING: 459 if (framesWritten != 0) { 460 // Don't wait to write more data. Just prime the buffer. 461 wakeTime = currentNanoTime; 462 } 463 break; 464 case AAUDIO_STREAM_STATE_STARTED: // When do we expect the next read burst to occur? 465 { 466 uint32_t burstSize = mFramesPerBurst; 467 if (burstSize < 32) { 468 burstSize = 32; // TODO review 469 } 470 471 uint64_t nextReadPosition = mAudioEndpoint.getDownDataReadCounter() + burstSize; 472 wakeTime = mClockModel.convertPositionToTime(nextReadPosition); 473 } 474 break; 475 default: 476 break; 477 } 478 *wakeTimePtr = wakeTime; 479 480 } 481// ALOGD("AudioStreamInternal::writeNow finished: now = %llu, read# = %llu, wrote# = %llu", 482// (unsigned long long)currentNanoTime, 483// (unsigned long long)mAudioEndpoint.getDownDataReadCounter(), 484// (unsigned long long)mAudioEndpoint.getDownDataWriteCounter()); 485 return framesWritten; 486} 487 488aaudio_result_t AudioStreamInternal::waitForStateChange(aaudio_stream_state_t currentState, 489 aaudio_stream_state_t *nextState, 490 int64_t timeoutNanoseconds) 491 492{ 493 aaudio_result_t result = processCommands(); 494// ALOGD("AudioStreamInternal::waitForStateChange() - processCommands() returned %d", result); 495 if (result != AAUDIO_OK) { 496 return result; 497 } 498 // TODO replace this polling with a timed sleep on a futex on the message queue 499 int32_t durationNanos = 5 * AAUDIO_NANOS_PER_MILLISECOND; 500 aaudio_stream_state_t state = getState(); 501// ALOGD("AudioStreamInternal::waitForStateChange() - state = %d", state); 502 while (state == currentState && timeoutNanoseconds > 0) { 503 // TODO use futex from service message queue 504 if (durationNanos > timeoutNanoseconds) { 505 durationNanos = timeoutNanoseconds; 506 } 507 AudioClock::sleepForNanos(durationNanos); 508 timeoutNanoseconds -= durationNanos; 509 510 result = processCommands(); 511 if (result != AAUDIO_OK) { 512 return result; 513 } 514 515 state = getState(); 516// ALOGD("AudioStreamInternal::waitForStateChange() - state = %d", state); 517 } 518 if (nextState != nullptr) { 519 *nextState = state; 520 } 521 return (state == currentState) ? AAUDIO_ERROR_TIMEOUT : AAUDIO_OK; 522} 523 524 525void AudioStreamInternal::processTimestamp(uint64_t position, int64_t time) { 526 mClockModel.processTimestamp( position, time); 527} 528 529aaudio_result_t AudioStreamInternal::setBufferSize(int32_t requestedFrames) { 530 int32_t actualFrames = 0; 531 aaudio_result_t result = mAudioEndpoint.setBufferSizeInFrames(requestedFrames, &actualFrames); 532 if (result < 0) { 533 return result; 534 } else { 535 return (aaudio_result_t) actualFrames; 536 } 537} 538 539int32_t AudioStreamInternal::getBufferSize() const 540{ 541 return mAudioEndpoint.getBufferSizeInFrames(); 542} 543 544int32_t AudioStreamInternal::getBufferCapacity() const 545{ 546 return mAudioEndpoint.getBufferCapacityInFrames(); 547} 548 549int32_t AudioStreamInternal::getFramesPerBurst() const 550{ 551 return mEndpointDescriptor.downDataQueueDescriptor.framesPerBurst; 552} 553 554int64_t AudioStreamInternal::getFramesRead() 555{ 556 int64_t framesRead = 557 mClockModel.convertTimeToPosition(AudioClock::getNanoseconds()) 558 + mFramesOffsetFromService; 559 // Prevent retrograde motion. 560 if (framesRead < mLastFramesRead) { 561 framesRead = mLastFramesRead; 562 } else { 563 mLastFramesRead = framesRead; 564 } 565 ALOGD("AudioStreamInternal::getFramesRead() returns %lld", (long long)framesRead); 566 return framesRead; 567} 568 569// TODO implement getTimestamp 570