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/AAudio.h> 25 #include <aaudio/AAudioTesting.h> 26 27 #include "AudioClock.h" 28 #include "AudioStreamBuilder.h" 29 #include "AudioStream.h" 30 #include "binding/AAudioCommon.h" 31 #include "client/AudioStreamInternal.h" 32 33 using namespace aaudio; 34 35 // Macros for common code that includes a return. 36 // TODO Consider using do{}while(0) construct. I tried but it hung AndroidStudio 37 #define CONVERT_BUILDER_HANDLE_OR_RETURN() \ 38 convertAAudioBuilderToStreamBuilder(builder); 39 40 #define COMMON_GET_FROM_BUILDER_OR_RETURN(resultPtr) \ 41 CONVERT_BUILDER_HANDLE_OR_RETURN() \ 42 if ((resultPtr) == nullptr) { \ 43 return AAUDIO_ERROR_NULL; \ 44 } 45 46 #define AAUDIO_CASE_ENUM(name) case name: return #name 47 48 AAUDIO_API const char * AAudio_convertResultToText(aaudio_result_t returnCode) { 49 switch (returnCode) { 50 AAUDIO_CASE_ENUM(AAUDIO_OK); 51 AAUDIO_CASE_ENUM(AAUDIO_ERROR_DISCONNECTED); 52 AAUDIO_CASE_ENUM(AAUDIO_ERROR_ILLEGAL_ARGUMENT); 53 // reserved 54 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INTERNAL); 55 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_STATE); 56 // reserved 57 // reserved 58 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_HANDLE); 59 // reserved 60 AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNIMPLEMENTED); 61 AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNAVAILABLE); 62 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_FREE_HANDLES); 63 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_MEMORY); 64 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NULL); 65 AAUDIO_CASE_ENUM(AAUDIO_ERROR_TIMEOUT); 66 AAUDIO_CASE_ENUM(AAUDIO_ERROR_WOULD_BLOCK); 67 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_FORMAT); 68 AAUDIO_CASE_ENUM(AAUDIO_ERROR_OUT_OF_RANGE); 69 AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_SERVICE); 70 AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_RATE); 71 } 72 return "Unrecognized AAudio error."; 73 } 74 75 AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t state) { 76 switch (state) { 77 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNINITIALIZED); 78 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNKNOWN); 79 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_OPEN); 80 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTING); 81 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTED); 82 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSING); 83 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSED); 84 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHING); 85 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHED); 86 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPING); 87 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPED); 88 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_DISCONNECTED); 89 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSING); 90 AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSED); 91 } 92 return "Unrecognized AAudio state."; 93 } 94 95 #undef AAUDIO_CASE_ENUM 96 97 98 /****************************************** 99 * Static globals. 100 */ 101 static aaudio_policy_t s_MMapPolicy = AAUDIO_UNSPECIFIED; 102 103 static AudioStream *convertAAudioStreamToAudioStream(AAudioStream* stream) 104 { 105 return (AudioStream*) stream; 106 } 107 108 static AudioStreamBuilder *convertAAudioBuilderToStreamBuilder(AAudioStreamBuilder* builder) 109 { 110 return (AudioStreamBuilder*) builder; 111 } 112 113 AAUDIO_API aaudio_result_t AAudio_createStreamBuilder(AAudioStreamBuilder** builder) 114 { 115 AudioStreamBuilder *audioStreamBuilder = new(std::nothrow) AudioStreamBuilder(); 116 if (audioStreamBuilder == nullptr) { 117 return AAUDIO_ERROR_NO_MEMORY; 118 } 119 *builder = (AAudioStreamBuilder*) audioStreamBuilder; 120 return AAUDIO_OK; 121 } 122 123 AAUDIO_API void AAudioStreamBuilder_setPerformanceMode(AAudioStreamBuilder* builder, 124 aaudio_performance_mode_t mode) 125 { 126 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 127 streamBuilder->setPerformanceMode(mode); 128 } 129 130 AAUDIO_API void AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder* builder, 131 int32_t deviceId) 132 { 133 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 134 streamBuilder->setDeviceId(deviceId); 135 } 136 137 AAUDIO_API void AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder* builder, 138 int32_t sampleRate) 139 { 140 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 141 streamBuilder->setSampleRate(sampleRate); 142 } 143 144 AAUDIO_API void AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder* builder, 145 int32_t channelCount) 146 { 147 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 148 streamBuilder->setSamplesPerFrame(channelCount); 149 } 150 151 AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder, 152 int32_t channelCount) 153 { 154 AAudioStreamBuilder_setChannelCount(builder, channelCount); 155 } 156 157 AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* builder, 158 aaudio_direction_t direction) 159 { 160 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 161 streamBuilder->setDirection(direction); 162 } 163 164 AAUDIO_API void AAudioStreamBuilder_setFormat(AAudioStreamBuilder* builder, 165 aaudio_format_t format) 166 { 167 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 168 streamBuilder->setFormat(format); 169 } 170 171 AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* builder, 172 aaudio_sharing_mode_t sharingMode) 173 { 174 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 175 streamBuilder->setSharingMode(sharingMode); 176 } 177 178 AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder, 179 int32_t frames) 180 { 181 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 182 streamBuilder->setBufferCapacity(frames); 183 } 184 185 AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* builder, 186 AAudioStream_dataCallback callback, 187 void *userData) 188 { 189 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 190 streamBuilder->setDataCallbackProc(callback); 191 streamBuilder->setDataCallbackUserData(userData); 192 } 193 194 AAUDIO_API void AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder* builder, 195 AAudioStream_errorCallback callback, 196 void *userData) 197 { 198 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 199 streamBuilder->setErrorCallbackProc(callback); 200 streamBuilder->setErrorCallbackUserData(userData); 201 } 202 203 AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* builder, 204 int32_t frames) 205 { 206 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 207 streamBuilder->setFramesPerDataCallback(frames); 208 } 209 210 AAUDIO_API aaudio_result_t AAudioStreamBuilder_openStream(AAudioStreamBuilder* builder, 211 AAudioStream** streamPtr) 212 { 213 AudioStream *audioStream = nullptr; 214 // Please leave these logs because they are very helpful when debugging. 215 ALOGD("AAudioStreamBuilder_openStream() called ----------------------------------------"); 216 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(streamPtr); 217 aaudio_result_t result = streamBuilder->build(&audioStream); 218 ALOGD("AAudioStreamBuilder_openStream() returns %d = %s for (%p) ----------------", 219 result, AAudio_convertResultToText(result), audioStream); 220 if (result == AAUDIO_OK) { 221 audioStream->registerPlayerBase(); 222 *streamPtr = (AAudioStream*) audioStream; 223 } else { 224 *streamPtr = nullptr; 225 } 226 return result; 227 } 228 229 AAUDIO_API aaudio_result_t AAudioStreamBuilder_delete(AAudioStreamBuilder* builder) 230 { 231 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 232 if (streamBuilder != nullptr) { 233 delete streamBuilder; 234 return AAUDIO_OK; 235 } 236 return AAUDIO_ERROR_NULL; 237 } 238 239 AAUDIO_API aaudio_result_t AAudioStream_close(AAudioStream* stream) 240 { 241 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 242 ALOGD("AAudioStream_close(%p)", stream); 243 if (audioStream != nullptr) { 244 audioStream->close(); 245 audioStream->unregisterPlayerBase(); 246 delete audioStream; 247 return AAUDIO_OK; 248 } 249 return AAUDIO_ERROR_NULL; 250 } 251 252 AAUDIO_API aaudio_result_t AAudioStream_requestStart(AAudioStream* stream) 253 { 254 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 255 ALOGD("AAudioStream_requestStart(%p) called --------------", stream); 256 aaudio_result_t result = audioStream->systemStart(); 257 ALOGD("AAudioStream_requestStart(%p) returned %d ---------", stream, result); 258 return result; 259 } 260 261 AAUDIO_API aaudio_result_t AAudioStream_requestPause(AAudioStream* stream) 262 { 263 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 264 ALOGD("AAudioStream_requestPause(%p)", stream); 265 return audioStream->systemPause(); 266 } 267 268 AAUDIO_API aaudio_result_t AAudioStream_requestFlush(AAudioStream* stream) 269 { 270 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 271 ALOGD("AAudioStream_requestFlush(%p)", stream); 272 return audioStream->requestFlush(); 273 } 274 275 AAUDIO_API aaudio_result_t AAudioStream_requestStop(AAudioStream* stream) 276 { 277 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 278 ALOGD("AAudioStream_requestStop(%p)", stream); 279 return audioStream->systemStop(); 280 } 281 282 AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream, 283 aaudio_stream_state_t inputState, 284 aaudio_stream_state_t *nextState, 285 int64_t timeoutNanoseconds) 286 { 287 288 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 289 return audioStream->waitForStateChange(inputState, nextState, timeoutNanoseconds); 290 } 291 292 // ============================================================ 293 // Stream - non-blocking I/O 294 // ============================================================ 295 296 AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* stream, 297 void *buffer, 298 int32_t numFrames, 299 int64_t timeoutNanoseconds) 300 { 301 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 302 if (buffer == nullptr) { 303 return AAUDIO_ERROR_NULL; 304 } 305 if (numFrames < 0) { 306 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 307 } else if (numFrames == 0) { 308 return 0; 309 } 310 311 aaudio_result_t result = audioStream->read(buffer, numFrames, timeoutNanoseconds); 312 313 return result; 314 } 315 316 AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream, 317 const void *buffer, 318 int32_t numFrames, 319 int64_t timeoutNanoseconds) 320 { 321 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 322 if (buffer == nullptr) { 323 return AAUDIO_ERROR_NULL; 324 } 325 326 // Don't allow writes when playing with a callback. 327 if (audioStream->getDataCallbackProc() != nullptr && audioStream->isActive()) { 328 ALOGE("Cannot write to a callback stream when running."); 329 return AAUDIO_ERROR_INVALID_STATE; 330 } 331 332 if (numFrames < 0) { 333 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 334 } else if (numFrames == 0) { 335 return 0; 336 } 337 338 aaudio_result_t result = audioStream->write(buffer, numFrames, timeoutNanoseconds); 339 340 return result; 341 } 342 343 // ============================================================ 344 // Stream - queries 345 // ============================================================ 346 347 AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream) 348 { 349 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 350 return audioStream->getSampleRate(); 351 } 352 353 AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream) 354 { 355 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 356 return audioStream->getSamplesPerFrame(); 357 } 358 359 AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream) 360 { 361 return AAudioStream_getChannelCount(stream); 362 } 363 364 AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream) 365 { 366 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 367 return audioStream->getState(); 368 } 369 370 AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* stream) 371 { 372 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 373 return audioStream->getFormat(); 374 } 375 376 AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* stream, 377 int32_t requestedFrames) 378 { 379 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 380 return audioStream->setBufferSize(requestedFrames); 381 } 382 383 AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* stream) 384 { 385 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 386 return audioStream->getBufferSize(); 387 } 388 389 AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* stream) 390 { 391 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 392 return audioStream->getDirection(); 393 } 394 395 AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* stream) 396 { 397 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 398 return audioStream->getFramesPerBurst(); 399 } 400 401 AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream) 402 { 403 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 404 return audioStream->getFramesPerDataCallback(); 405 } 406 407 AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream) 408 { 409 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 410 return audioStream->getBufferCapacity(); 411 } 412 413 AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream) 414 { 415 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 416 return audioStream->getXRunCount(); 417 } 418 419 AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* stream) 420 { 421 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 422 return audioStream->getPerformanceMode(); 423 } 424 425 AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream) 426 { 427 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 428 return audioStream->getDeviceId(); 429 } 430 431 AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream) 432 { 433 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 434 return audioStream->getSharingMode(); 435 } 436 437 AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream) 438 { 439 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 440 return audioStream->getFramesWritten(); 441 } 442 443 AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream) 444 { 445 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 446 return audioStream->getFramesRead(); 447 } 448 449 AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* stream, 450 clockid_t clockid, 451 int64_t *framePosition, 452 int64_t *timeNanoseconds) 453 { 454 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 455 if (framePosition == nullptr) { 456 return AAUDIO_ERROR_NULL; 457 } else if (timeNanoseconds == nullptr) { 458 return AAUDIO_ERROR_NULL; 459 } else if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_BOOTTIME) { 460 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 461 } 462 463 return audioStream->getTimestamp(clockid, framePosition, timeNanoseconds); 464 } 465 466 AAUDIO_API aaudio_policy_t AAudio_getMMapPolicy() { 467 return s_MMapPolicy; 468 } 469 470 AAUDIO_API aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy) { 471 aaudio_result_t result = AAUDIO_OK; 472 switch(policy) { 473 case AAUDIO_UNSPECIFIED: 474 case AAUDIO_POLICY_NEVER: 475 case AAUDIO_POLICY_AUTO: 476 case AAUDIO_POLICY_ALWAYS: 477 s_MMapPolicy = policy; 478 break; 479 default: 480 result = AAUDIO_ERROR_ILLEGAL_ARGUMENT; 481 break; 482 } 483 return result; 484 } 485 486 AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream) 487 { 488 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 489 return audioStream->isMMap(); 490 } 491