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