AAudioAudio.cpp revision f53e613b3dedab3ecada2c93d8846233c442d129
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 <time.h> 22#include <pthread.h> 23 24#include <aaudio/AAudioDefinitions.h> 25#include <aaudio/AAudio.h> 26 27#include "AudioStreamBuilder.h" 28#include "AudioStream.h" 29#include "AudioClock.h" 30#include "client/AudioStreamInternal.h" 31#include "HandleTracker.h" 32 33using namespace aaudio; 34 35// This is not the maximum theoretic possible number of handles that the HandlerTracker 36// class could support; instead it is the maximum number of handles that we are configuring 37// for our HandleTracker instance (sHandleTracker). 38#define AAUDIO_MAX_HANDLES 64 39 40// Macros for common code that includes a return. 41// TODO Consider using do{}while(0) construct. I tried but it hung AndroidStudio 42#define CONVERT_BUILDER_HANDLE_OR_RETURN() \ 43 convertAAudioBuilderToStreamBuilder(builder); \ 44 if (streamBuilder == nullptr) { \ 45 return AAUDIO_ERROR_INVALID_HANDLE; \ 46 } 47 48#define COMMON_GET_FROM_BUILDER_OR_RETURN(resultPtr) \ 49 CONVERT_BUILDER_HANDLE_OR_RETURN() \ 50 if ((resultPtr) == nullptr) { \ 51 return AAUDIO_ERROR_NULL; \ 52 } 53 54#define CONVERT_STREAM_HANDLE_OR_RETURN() \ 55 convertAAudioStreamToAudioStream(stream); \ 56 if (audioStream == nullptr) { \ 57 return AAUDIO_ERROR_INVALID_HANDLE; \ 58 } 59 60#define COMMON_GET_FROM_STREAM_OR_RETURN(resultPtr) \ 61 CONVERT_STREAM_HANDLE_OR_RETURN(); \ 62 if ((resultPtr) == nullptr) { \ 63 return AAUDIO_ERROR_NULL; \ 64 } 65 66// Static data. 67// TODO static constructors are discouraged, alternatives? 68static HandleTracker sHandleTracker(AAUDIO_MAX_HANDLES); 69 70typedef enum 71{ 72 AAUDIO_HANDLE_TYPE_STREAM, 73 AAUDIO_HANDLE_TYPE_STREAM_BUILDER, 74 AAUDIO_HANDLE_TYPE_COUNT 75} aaudio_handle_type_t; 76static_assert(AAUDIO_HANDLE_TYPE_COUNT <= HANDLE_TRACKER_MAX_TYPES, "Too many handle types."); 77 78 79#define AAUDIO_CASE_ENUM(name) case name: return #name 80 81AAUDIO_API const char * AAudio_convertResultToText(aaudio_result_t returnCode) { 82 switch (returnCode) { 83 AAUDIO_CASE_ENUM(AAUDIO_OK); 84 AAUDIO_CASE_ENUM(AAUDIO_ERROR_ILLEGAL_ARGUMENT); 85 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INCOMPATIBLE); 86 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INTERNAL); 87 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_STATE); 88 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_HANDLE); 89 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_QUERY); 90 AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNIMPLEMENTED); 91 AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNAVAILABLE); 92 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_FREE_HANDLES); 93 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_MEMORY); 94 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NULL); 95 AAUDIO_CASE_ENUM(AAUDIO_ERROR_TIMEOUT); 96 AAUDIO_CASE_ENUM(AAUDIO_ERROR_WOULD_BLOCK); 97 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_ORDER); 98 AAUDIO_CASE_ENUM(AAUDIO_ERROR_OUT_OF_RANGE); 99 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_SERVICE); 100 } 101 return "Unrecognized AAudio error."; 102} 103 104AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t state) { 105 switch (state) { 106 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNINITIALIZED); 107 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_OPEN); 108 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTING); 109 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTED); 110 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSING); 111 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSED); 112 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHING); 113 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHED); 114 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPING); 115 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPED); 116 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSING); 117 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSED); 118 } 119 return "Unrecognized AAudio state."; 120} 121 122#undef AAUDIO_CASE_ENUM 123 124static AudioStream *convertAAudioStreamToAudioStream(AAudioStream stream) 125{ 126 return (AudioStream *) sHandleTracker.get(AAUDIO_HANDLE_TYPE_STREAM, 127 (aaudio_handle_t) stream); 128} 129 130static AudioStreamBuilder *convertAAudioBuilderToStreamBuilder(AAudioStreamBuilder builder) 131{ 132 return (AudioStreamBuilder *) sHandleTracker.get(AAUDIO_HANDLE_TYPE_STREAM_BUILDER, 133 (aaudio_handle_t) builder); 134} 135 136AAUDIO_API aaudio_result_t AAudio_createStreamBuilder(AAudioStreamBuilder *builder) 137{ 138 ALOGD("AAudio_createStreamBuilder(): check sHandleTracker.isInitialized ()"); 139 if (!sHandleTracker.isInitialized()) { 140 return AAUDIO_ERROR_NO_MEMORY; 141 } 142 AudioStreamBuilder *audioStreamBuilder = new AudioStreamBuilder(); 143 if (audioStreamBuilder == nullptr) { 144 return AAUDIO_ERROR_NO_MEMORY; 145 } 146 ALOGD("AAudio_createStreamBuilder(): created AudioStreamBuilder = %p", audioStreamBuilder); 147 // TODO protect the put() with a Mutex 148 AAudioStreamBuilder handle = sHandleTracker.put(AAUDIO_HANDLE_TYPE_STREAM_BUILDER, 149 audioStreamBuilder); 150 if (handle < 0) { 151 delete audioStreamBuilder; 152 return static_cast<aaudio_result_t>(handle); 153 } else { 154 *builder = handle; 155 } 156 return AAUDIO_OK; 157} 158 159AAUDIO_API aaudio_result_t AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder builder, 160 aaudio_device_id_t deviceId) 161{ 162 AudioStreamBuilder *streamBuilder = CONVERT_BUILDER_HANDLE_OR_RETURN(); 163 streamBuilder->setDeviceId(deviceId); 164 return AAUDIO_OK; 165} 166 167AAUDIO_API aaudio_result_t AAudioStreamBuilder_getDeviceId(AAudioStreamBuilder builder, 168 aaudio_device_id_t *deviceId) 169{ 170 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(deviceId); 171 *deviceId = streamBuilder->getDeviceId(); 172 return AAUDIO_OK; 173} 174 175AAUDIO_API aaudio_result_t AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder builder, 176 aaudio_sample_rate_t sampleRate) 177{ 178 AudioStreamBuilder *streamBuilder = CONVERT_BUILDER_HANDLE_OR_RETURN(); 179 streamBuilder->setSampleRate(sampleRate); 180 return AAUDIO_OK; 181} 182 183AAUDIO_API aaudio_result_t AAudioStreamBuilder_getSampleRate(AAudioStreamBuilder builder, 184 aaudio_sample_rate_t *sampleRate) 185{ 186 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(sampleRate); 187 *sampleRate = streamBuilder->getSampleRate(); 188 return AAUDIO_OK; 189} 190 191AAUDIO_API aaudio_result_t AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder builder, 192 int32_t samplesPerFrame) 193{ 194 AudioStreamBuilder *streamBuilder = CONVERT_BUILDER_HANDLE_OR_RETURN(); 195 streamBuilder->setSamplesPerFrame(samplesPerFrame); 196 return AAUDIO_OK; 197} 198 199AAUDIO_API aaudio_result_t AAudioStreamBuilder_getSamplesPerFrame(AAudioStreamBuilder builder, 200 int32_t *samplesPerFrame) 201{ 202 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(samplesPerFrame); 203 *samplesPerFrame = streamBuilder->getSamplesPerFrame(); 204 return AAUDIO_OK; 205} 206 207AAUDIO_API aaudio_result_t AAudioStreamBuilder_setDirection(AAudioStreamBuilder builder, 208 aaudio_direction_t direction) 209{ 210 AudioStreamBuilder *streamBuilder = CONVERT_BUILDER_HANDLE_OR_RETURN(); 211 streamBuilder->setDirection(direction); 212 return AAUDIO_OK; 213} 214 215AAUDIO_API aaudio_result_t AAudioStreamBuilder_getDirection(AAudioStreamBuilder builder, 216 aaudio_direction_t *direction) 217{ 218 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(direction); 219 *direction = streamBuilder->getDirection(); 220 return AAUDIO_OK; 221} 222 223AAUDIO_API aaudio_result_t AAudioStreamBuilder_setFormat(AAudioStreamBuilder builder, 224 aaudio_audio_format_t format) 225{ 226 AudioStreamBuilder *streamBuilder = CONVERT_BUILDER_HANDLE_OR_RETURN(); 227 streamBuilder->setFormat(format); 228 return AAUDIO_OK; 229} 230 231AAUDIO_API aaudio_result_t AAudioStreamBuilder_getFormat(AAudioStreamBuilder builder, 232 aaudio_audio_format_t *format) 233{ 234 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(format); 235 *format = streamBuilder->getFormat(); 236 return AAUDIO_OK; 237} 238 239AAUDIO_API aaudio_result_t AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder builder, 240 aaudio_sharing_mode_t sharingMode) 241{ 242 AudioStreamBuilder *streamBuilder = CONVERT_BUILDER_HANDLE_OR_RETURN(); 243 if ((sharingMode < 0) || (sharingMode >= AAUDIO_SHARING_MODE_COUNT)) { 244 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 245 } else { 246 streamBuilder->setSharingMode(sharingMode); 247 return AAUDIO_OK; 248 } 249} 250 251AAUDIO_API aaudio_result_t AAudioStreamBuilder_getSharingMode(AAudioStreamBuilder builder, 252 aaudio_sharing_mode_t *sharingMode) 253{ 254 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(sharingMode); 255 *sharingMode = streamBuilder->getSharingMode(); 256 return AAUDIO_OK; 257} 258 259AAUDIO_API aaudio_result_t AAudioStreamBuilder_setBufferCapacity(AAudioStreamBuilder builder, 260 aaudio_size_frames_t frames) 261{ 262 AudioStreamBuilder *streamBuilder = CONVERT_BUILDER_HANDLE_OR_RETURN(); 263 if (frames < 0) { 264 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 265 } else { 266 streamBuilder->setBufferCapacity(frames); 267 return AAUDIO_OK; 268 } 269} 270 271AAUDIO_API aaudio_result_t AAudioStreamBuilder_getBufferCapacity(AAudioStreamBuilder builder, 272 aaudio_size_frames_t *frames) 273{ 274 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(frames); 275 *frames = streamBuilder->getBufferCapacity(); 276 return AAUDIO_OK; 277} 278 279static aaudio_result_t AAudioInternal_openStream(AudioStreamBuilder *streamBuilder, 280 AAudioStream *streamPtr) 281{ 282 AudioStream *audioStream = nullptr; 283 aaudio_result_t result = streamBuilder->build(&audioStream); 284 if (result != AAUDIO_OK) { 285 return result; 286 } else { 287 // Create a handle for referencing the object. 288 // TODO protect the put() with a Mutex 289 AAudioStream handle = sHandleTracker.put(AAUDIO_HANDLE_TYPE_STREAM, audioStream); 290 if (handle < 0) { 291 delete audioStream; 292 return static_cast<aaudio_result_t>(handle); 293 } 294 *streamPtr = handle; 295 return AAUDIO_OK; 296 } 297} 298 299AAUDIO_API aaudio_result_t AAudioStreamBuilder_openStream(AAudioStreamBuilder builder, 300 AAudioStream *streamPtr) 301{ 302 ALOGD("AAudioStreamBuilder_openStream(): builder = 0x%08X", builder); 303 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(streamPtr); 304 return AAudioInternal_openStream(streamBuilder, streamPtr); 305} 306 307AAUDIO_API aaudio_result_t AAudioStreamBuilder_delete(AAudioStreamBuilder builder) 308{ 309 AudioStreamBuilder *streamBuilder = (AudioStreamBuilder *) 310 sHandleTracker.remove(AAUDIO_HANDLE_TYPE_STREAM_BUILDER, builder); 311 if (streamBuilder != nullptr) { 312 delete streamBuilder; 313 return AAUDIO_OK; 314 } 315 return AAUDIO_ERROR_INVALID_HANDLE; 316} 317 318AAUDIO_API aaudio_result_t AAudioStream_close(AAudioStream stream) 319{ 320 AudioStream *audioStream = (AudioStream *) 321 sHandleTracker.remove(AAUDIO_HANDLE_TYPE_STREAM, (aaudio_handle_t)stream); 322 ALOGD("AAudioStream_close(0x%08X), audioStream = %p", stream, audioStream); 323 if (audioStream != nullptr) { 324 audioStream->close(); 325 delete audioStream; 326 return AAUDIO_OK; 327 } 328 return AAUDIO_ERROR_INVALID_HANDLE; 329} 330 331AAUDIO_API aaudio_result_t AAudioStream_requestStart(AAudioStream stream) 332{ 333 AudioStream *audioStream = CONVERT_STREAM_HANDLE_OR_RETURN(); 334 ALOGD("AAudioStream_requestStart(0x%08X), audioStream = %p", stream, audioStream); 335 return audioStream->requestStart(); 336} 337 338AAUDIO_API aaudio_result_t AAudioStream_requestPause(AAudioStream stream) 339{ 340 AudioStream *audioStream = CONVERT_STREAM_HANDLE_OR_RETURN(); 341 ALOGD("AAudioStream_requestPause(0x%08X), audioStream = %p", stream, audioStream); 342 return audioStream->requestPause(); 343} 344 345AAUDIO_API aaudio_result_t AAudioStream_requestFlush(AAudioStream stream) 346{ 347 AudioStream *audioStream = CONVERT_STREAM_HANDLE_OR_RETURN(); 348 ALOGD("AAudioStream_requestFlush(0x%08X), audioStream = %p", stream, audioStream); 349 return audioStream->requestFlush(); 350} 351 352AAUDIO_API aaudio_result_t AAudioStream_requestStop(AAudioStream stream) 353{ 354 AudioStream *audioStream = CONVERT_STREAM_HANDLE_OR_RETURN(); 355 ALOGD("AAudioStream_requestStop(0x%08X), audioStream = %p", stream, audioStream); 356 return audioStream->requestStop(); 357} 358 359AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream stream, 360 aaudio_stream_state_t inputState, 361 aaudio_stream_state_t *nextState, 362 aaudio_nanoseconds_t timeoutNanoseconds) 363{ 364 365 AudioStream *audioStream = CONVERT_STREAM_HANDLE_OR_RETURN(); 366 return audioStream->waitForStateChange(inputState, nextState, timeoutNanoseconds); 367} 368 369// ============================================================ 370// Stream - non-blocking I/O 371// ============================================================ 372 373AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream stream, 374 void *buffer, 375 aaudio_size_frames_t numFrames, 376 aaudio_nanoseconds_t timeoutNanoseconds) 377{ 378 AudioStream *audioStream = CONVERT_STREAM_HANDLE_OR_RETURN(); 379 if (buffer == nullptr) { 380 return AAUDIO_ERROR_NULL; 381 } 382 if (numFrames < 0) { 383 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 384 } else if (numFrames == 0) { 385 return 0; 386 } 387 388 aaudio_result_t result = audioStream->read(buffer, numFrames, timeoutNanoseconds); 389 // ALOGD("AAudioStream_read(): read returns %d", result); 390 391 return result; 392} 393 394AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream stream, 395 const void *buffer, 396 aaudio_size_frames_t numFrames, 397 aaudio_nanoseconds_t timeoutNanoseconds) 398{ 399 AudioStream *audioStream = CONVERT_STREAM_HANDLE_OR_RETURN(); 400 if (buffer == nullptr) { 401 return AAUDIO_ERROR_NULL; 402 } 403 if (numFrames < 0) { 404 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 405 } else if (numFrames == 0) { 406 return 0; 407 } 408 409 aaudio_result_t result = audioStream->write(buffer, numFrames, timeoutNanoseconds); 410 // ALOGD("AAudioStream_write(): write returns %d", result); 411 412 return result; 413} 414 415// ============================================================ 416// Miscellaneous 417// ============================================================ 418 419AAUDIO_API aaudio_result_t AAudioStream_createThread(AAudioStream stream, 420 aaudio_nanoseconds_t periodNanoseconds, 421 aaudio_audio_thread_proc_t *threadProc, void *arg) 422{ 423 AudioStream *audioStream = CONVERT_STREAM_HANDLE_OR_RETURN(); 424 return audioStream->createThread(periodNanoseconds, threadProc, arg); 425} 426 427AAUDIO_API aaudio_result_t AAudioStream_joinThread(AAudioStream stream, 428 void **returnArg, 429 aaudio_nanoseconds_t timeoutNanoseconds) 430{ 431 AudioStream *audioStream = CONVERT_STREAM_HANDLE_OR_RETURN(); 432 return audioStream->joinThread(returnArg, timeoutNanoseconds); 433} 434 435// ============================================================ 436// Stream - queries 437// ============================================================ 438 439// TODO Use aaudio_clockid_t all the way down through the C++ streams. 440static clockid_t AAudioConvert_fromAAudioClockId(aaudio_clockid_t clockid) 441{ 442 clockid_t hostClockId; 443 switch (clockid) { 444 case AAUDIO_CLOCK_MONOTONIC: 445 hostClockId = CLOCK_MONOTONIC; 446 break; 447 case AAUDIO_CLOCK_BOOTTIME: 448 hostClockId = CLOCK_BOOTTIME; 449 break; 450 default: 451 hostClockId = 0; // TODO review 452 } 453 return hostClockId; 454} 455 456aaudio_nanoseconds_t AAudio_getNanoseconds(aaudio_clockid_t clockid) 457{ 458 clockid_t hostClockId = AAudioConvert_fromAAudioClockId(clockid); 459 return AudioClock::getNanoseconds(hostClockId); 460} 461 462AAUDIO_API aaudio_result_t AAudioStream_getSampleRate(AAudioStream stream, aaudio_sample_rate_t *sampleRate) 463{ 464 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(sampleRate); 465 *sampleRate = audioStream->getSampleRate(); 466 return AAUDIO_OK; 467} 468 469AAUDIO_API aaudio_result_t AAudioStream_getSamplesPerFrame(AAudioStream stream, int32_t *samplesPerFrame) 470{ 471 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(samplesPerFrame); 472 *samplesPerFrame = audioStream->getSamplesPerFrame(); 473 return AAUDIO_OK; 474} 475 476AAUDIO_API aaudio_result_t AAudioStream_getState(AAudioStream stream, aaudio_stream_state_t *state) 477{ 478 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(state); 479 *state = audioStream->getState(); 480 return AAUDIO_OK; 481} 482 483AAUDIO_API aaudio_result_t AAudioStream_getFormat(AAudioStream stream, aaudio_audio_format_t *format) 484{ 485 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(format); 486 *format = audioStream->getFormat(); 487 return AAUDIO_OK; 488} 489 490AAUDIO_API aaudio_result_t AAudioStream_setBufferSize(AAudioStream stream, 491 aaudio_size_frames_t requestedFrames, 492 aaudio_size_frames_t *actualFrames) 493{ 494 AudioStream *audioStream = CONVERT_STREAM_HANDLE_OR_RETURN(); 495 return audioStream->setBufferSize(requestedFrames, actualFrames); 496} 497 498AAUDIO_API aaudio_result_t AAudioStream_getBufferSize(AAudioStream stream, aaudio_size_frames_t *frames) 499{ 500 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(frames); 501 *frames = audioStream->getBufferSize(); 502 return AAUDIO_OK; 503} 504 505AAUDIO_API aaudio_result_t AAudioStream_getDirection(AAudioStream stream, int32_t *direction) 506{ 507 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(direction); 508 *direction = audioStream->getDirection(); 509 return AAUDIO_OK; 510} 511 512AAUDIO_API aaudio_result_t AAudioStream_getFramesPerBurst(AAudioStream stream, 513 aaudio_size_frames_t *framesPerBurst) 514{ 515 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(framesPerBurst); 516 *framesPerBurst = audioStream->getFramesPerBurst(); 517 return AAUDIO_OK; 518} 519 520AAUDIO_API aaudio_result_t AAudioStream_getBufferCapacity(AAudioStream stream, 521 aaudio_size_frames_t *capacity) 522{ 523 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(capacity); 524 *capacity = audioStream->getBufferCapacity(); 525 return AAUDIO_OK; 526} 527 528AAUDIO_API aaudio_result_t AAudioStream_getXRunCount(AAudioStream stream, int32_t *xRunCount) 529{ 530 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(xRunCount); 531 *xRunCount = audioStream->getXRunCount(); 532 return AAUDIO_OK; 533} 534 535AAUDIO_API aaudio_result_t AAudioStream_getDeviceId(AAudioStream stream, 536 aaudio_device_id_t *deviceId) 537{ 538 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(deviceId); 539 *deviceId = audioStream->getDeviceId(); 540 return AAUDIO_OK; 541} 542 543AAUDIO_API aaudio_result_t AAudioStream_getSharingMode(AAudioStream stream, 544 aaudio_sharing_mode_t *sharingMode) 545{ 546 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(sharingMode); 547 *sharingMode = audioStream->getSharingMode(); 548 return AAUDIO_OK; 549} 550 551AAUDIO_API aaudio_result_t AAudioStream_getFramesWritten(AAudioStream stream, 552 aaudio_position_frames_t *frames) 553{ 554 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(frames); 555 *frames = audioStream->getFramesWritten(); 556 return AAUDIO_OK; 557} 558 559AAUDIO_API aaudio_result_t AAudioStream_getFramesRead(AAudioStream stream, aaudio_position_frames_t *frames) 560{ 561 AudioStream *audioStream = COMMON_GET_FROM_STREAM_OR_RETURN(frames); 562 *frames = audioStream->getFramesRead(); 563 return AAUDIO_OK; 564} 565 566AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream stream, 567 aaudio_clockid_t clockid, 568 aaudio_position_frames_t *framePosition, 569 aaudio_nanoseconds_t *timeNanoseconds) 570{ 571 AudioStream *audioStream = CONVERT_STREAM_HANDLE_OR_RETURN(); 572 if (framePosition == nullptr) { 573 return AAUDIO_ERROR_NULL; 574 } else if (timeNanoseconds == nullptr) { 575 return AAUDIO_ERROR_NULL; 576 } else if (clockid != AAUDIO_CLOCK_MONOTONIC && clockid != AAUDIO_CLOCK_BOOTTIME) { 577 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 578 } 579 580 clockid_t hostClockId = AAudioConvert_fromAAudioClockId(clockid); 581 return audioStream->getTimestamp(hostClockId, framePosition, timeNanoseconds); 582} 583