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