AAudioAudio.cpp revision 17fff38dd9d467bc5fb6cd5b9a6b183951c7750d
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 26#include "AudioStreamBuilder.h" 27#include "AudioStream.h" 28#include "AudioClock.h" 29#include "client/AudioStreamInternal.h" 30#include "HandleTracker.h" 31 32using namespace aaudio; 33 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 48AAUDIO_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 75AAUDIO_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 97static AudioStream *convertAAudioStreamToAudioStream(AAudioStream* stream) 98{ 99 return (AudioStream*) stream; 100} 101 102static AudioStreamBuilder *convertAAudioBuilderToStreamBuilder(AAudioStreamBuilder* builder) 103{ 104 return (AudioStreamBuilder*) builder; 105} 106 107AAUDIO_API aaudio_result_t AAudio_createStreamBuilder(AAudioStreamBuilder** builder) 108{ 109 AudioStreamBuilder *audioStreamBuilder = new(std::nothrow) AudioStreamBuilder(); 110 if (audioStreamBuilder == nullptr) { 111 return AAUDIO_ERROR_NO_MEMORY; 112 } 113 *builder = (AAudioStreamBuilder*) audioStreamBuilder; 114 return AAUDIO_OK; 115} 116 117AAUDIO_API void AAudioStreamBuilder_setPerformanceMode(AAudioStreamBuilder* builder, 118 aaudio_performance_mode_t mode) 119{ 120 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 121 streamBuilder->setPerformanceMode(mode); 122} 123 124AAUDIO_API void AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder* builder, 125 int32_t deviceId) 126{ 127 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 128 streamBuilder->setDeviceId(deviceId); 129} 130 131AAUDIO_API void AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder* builder, 132 int32_t sampleRate) 133{ 134 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 135 streamBuilder->setSampleRate(sampleRate); 136} 137 138AAUDIO_API void AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder* builder, 139 int32_t channelCount) 140{ 141 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 142 streamBuilder->setSamplesPerFrame(channelCount); 143} 144 145AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder, 146 int32_t samplesPerFrame) 147{ 148 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 149 streamBuilder->setSamplesPerFrame(samplesPerFrame); 150} 151 152AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* builder, 153 aaudio_direction_t direction) 154{ 155 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 156 streamBuilder->setDirection(direction); 157} 158 159AAUDIO_API void AAudioStreamBuilder_setFormat(AAudioStreamBuilder* builder, 160 aaudio_audio_format_t format) 161{ 162 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 163 streamBuilder->setFormat(format); 164} 165 166AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* builder, 167 aaudio_sharing_mode_t sharingMode) 168{ 169 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 170 streamBuilder->setSharingMode(sharingMode); 171} 172 173AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder, 174 int32_t frames) 175{ 176 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 177 streamBuilder->setBufferCapacity(frames); 178} 179 180AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* builder, 181 AAudioStream_dataCallback callback, 182 void *userData) 183{ 184 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 185 streamBuilder->setDataCallbackProc(callback); 186 streamBuilder->setDataCallbackUserData(userData); 187} 188 189AAUDIO_API void AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder* builder, 190 AAudioStream_errorCallback callback, 191 void *userData) 192{ 193 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 194 streamBuilder->setErrorCallbackProc(callback); 195 streamBuilder->setErrorCallbackUserData(userData); 196} 197 198AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* builder, 199 int32_t frames) 200{ 201 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 202 streamBuilder->setFramesPerDataCallback(frames); 203} 204 205AAUDIO_API aaudio_result_t AAudioStreamBuilder_openStream(AAudioStreamBuilder* builder, 206 AAudioStream** streamPtr) 207{ 208 AudioStream *audioStream = nullptr; 209 ALOGD("AAudioStreamBuilder_openStream() ----------------------------------------------"); 210 AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(streamPtr); 211 aaudio_result_t result = streamBuilder->build(&audioStream); 212 ALOGD("AAudioStreamBuilder_openStream() returns %d -----------------------------------", 213 result); 214 if (result == AAUDIO_OK) { 215 *streamPtr = (AAudioStream*) audioStream; 216 } else { 217 *streamPtr = nullptr; 218 } 219 return result; 220} 221 222AAUDIO_API aaudio_result_t AAudioStreamBuilder_delete(AAudioStreamBuilder* builder) 223{ 224 AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder); 225 if (streamBuilder != nullptr) { 226 delete streamBuilder; 227 return AAUDIO_OK; 228 } 229 return AAUDIO_ERROR_NULL; 230} 231 232AAUDIO_API aaudio_result_t AAudioStream_close(AAudioStream* stream) 233{ 234 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 235 ALOGD("AAudioStream_close(%p)", stream); 236 if (audioStream != nullptr) { 237 audioStream->close(); 238 delete audioStream; 239 ALOGD("AAudioStream_close() ----------------------------------------------"); 240 return AAUDIO_OK; 241 } 242 return AAUDIO_ERROR_NULL; 243} 244 245AAUDIO_API aaudio_result_t AAudioStream_requestStart(AAudioStream* stream) 246{ 247 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 248 ALOGD("AAudioStream_requestStart(%p)", stream); 249 return audioStream->requestStart(); 250} 251 252AAUDIO_API aaudio_result_t AAudioStream_requestPause(AAudioStream* stream) 253{ 254 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 255 ALOGD("AAudioStream_requestPause(%p)", stream); 256 return audioStream->requestPause(); 257} 258 259AAUDIO_API aaudio_result_t AAudioStream_requestFlush(AAudioStream* stream) 260{ 261 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 262 ALOGD("AAudioStream_requestFlush(%p)", stream); 263 return audioStream->requestFlush(); 264} 265 266AAUDIO_API aaudio_result_t AAudioStream_requestStop(AAudioStream* stream) 267{ 268 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 269 ALOGD("AAudioStream_requestStop(%p)", stream); 270 return audioStream->requestStop(); 271} 272 273AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream, 274 aaudio_stream_state_t inputState, 275 aaudio_stream_state_t *nextState, 276 int64_t timeoutNanoseconds) 277{ 278 279 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 280 return audioStream->waitForStateChange(inputState, nextState, timeoutNanoseconds); 281} 282 283// ============================================================ 284// Stream - non-blocking I/O 285// ============================================================ 286 287AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* stream, 288 void *buffer, 289 int32_t numFrames, 290 int64_t timeoutNanoseconds) 291{ 292 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 293 if (buffer == nullptr) { 294 return AAUDIO_ERROR_NULL; 295 } 296 if (numFrames < 0) { 297 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 298 } else if (numFrames == 0) { 299 return 0; 300 } 301 302 aaudio_result_t result = audioStream->read(buffer, numFrames, timeoutNanoseconds); 303 // ALOGD("AAudioStream_read(): read returns %d", result); 304 305 return result; 306} 307 308AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream, 309 const void *buffer, 310 int32_t numFrames, 311 int64_t timeoutNanoseconds) 312{ 313 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 314 if (buffer == nullptr) { 315 return AAUDIO_ERROR_NULL; 316 } 317 318 // Don't allow writes when playing with a callback. 319 if (audioStream->getDataCallbackProc() != nullptr && audioStream->isActive()) { 320 ALOGE("Cannot write to a callback stream when running."); 321 return AAUDIO_ERROR_INVALID_STATE; 322 } 323 324 if (numFrames < 0) { 325 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 326 } else if (numFrames == 0) { 327 return 0; 328 } 329 330 aaudio_result_t result = audioStream->write(buffer, numFrames, timeoutNanoseconds); 331 // ALOGD("AAudioStream_write(): write returns %d", result); 332 333 return result; 334} 335 336// ============================================================ 337// Stream - queries 338// ============================================================ 339 340AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream) 341{ 342 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 343 return audioStream->getSampleRate(); 344} 345 346AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream) 347{ 348 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 349 return audioStream->getSamplesPerFrame(); 350} 351 352AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream) 353{ 354 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 355 return audioStream->getSamplesPerFrame(); 356} 357 358AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream) 359{ 360 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 361 return audioStream->getState(); 362} 363 364AAUDIO_API aaudio_audio_format_t AAudioStream_getFormat(AAudioStream* stream) 365{ 366 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 367 return audioStream->getFormat(); 368} 369 370AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* stream, 371 int32_t requestedFrames) 372{ 373 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 374 return audioStream->setBufferSize(requestedFrames); 375} 376 377AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* stream) 378{ 379 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 380 return audioStream->getBufferSize(); 381} 382 383AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* stream) 384{ 385 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 386 return audioStream->getDirection(); 387} 388 389AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* stream) 390{ 391 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 392 return audioStream->getFramesPerBurst(); 393} 394 395AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream) 396{ 397 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 398 return audioStream->getFramesPerDataCallback(); 399} 400 401AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream) 402{ 403 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 404 return audioStream->getBufferCapacity(); 405} 406 407AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream) 408{ 409 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 410 return audioStream->getXRunCount(); 411} 412 413AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* stream) 414{ 415 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 416 return audioStream->getPerformanceMode(); 417} 418 419AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream) 420{ 421 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 422 return audioStream->getDeviceId(); 423} 424 425AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream) 426{ 427 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 428 return audioStream->getSharingMode(); 429} 430 431AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream) 432{ 433 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 434 return audioStream->getFramesWritten(); 435} 436 437AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream) 438{ 439 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 440 return audioStream->getFramesRead(); 441} 442 443AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* stream, 444 clockid_t clockid, 445 int64_t *framePosition, 446 int64_t *timeNanoseconds) 447{ 448 AudioStream *audioStream = convertAAudioStreamToAudioStream(stream); 449 if (framePosition == nullptr) { 450 return AAUDIO_ERROR_NULL; 451 } else if (timeNanoseconds == nullptr) { 452 return AAUDIO_ERROR_NULL; 453 } else if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_BOOTTIME) { 454 return AAUDIO_ERROR_ILLEGAL_ARGUMENT; 455 } 456 457 return audioStream->getTimestamp(clockid, framePosition, timeNanoseconds); 458} 459