xref: /aosp_15_r20/frameworks/av/media/libaaudio/src/core/AAudioAudio.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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 <inttypes.h>
22 #include <mutex>
23 #include <time.h>
24 #include <pthread.h>
25 
26 #include <aaudio/AAudio.h>
27 #include <aaudio/AAudioTesting.h>
28 #include <system/aaudio/AAudio.h>
29 #include <system/audio.h>
30 #include "AudioClock.h"
31 #include "AudioGlobal.h"
32 #include "AudioStreamBuilder.h"
33 #include "AudioStream.h"
34 #include "binding/AAudioCommon.h"
35 #include "client/AudioStreamInternal.h"
36 
37 using namespace aaudio;
38 
39 // Macros for common code that includes a return.
40 // TODO Consider using do{}while(0) construct. I tried but it hung AndroidStudio
41 #define CONVERT_BUILDER_HANDLE_OR_RETURN() \
42     convertAAudioBuilderToStreamBuilder(builder);
43 
44 #define COMMON_GET_FROM_BUILDER_OR_RETURN(resultPtr) \
45     CONVERT_BUILDER_HANDLE_OR_RETURN() \
46     if ((resultPtr) == nullptr) { \
47         return AAUDIO_ERROR_NULL; \
48     }
49 
AAudio_convertResultToText(aaudio_result_t returnCode)50 AAUDIO_API const char * AAudio_convertResultToText(aaudio_result_t returnCode) {
51     return AudioGlobal_convertResultToText(returnCode);
52 }
53 
AAudio_convertStreamStateToText(aaudio_stream_state_t state)54 AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t state) {
55     return AudioGlobal_convertStreamStateToText(state);
56 }
57 
AAudio_getPlatformMMapPolicy(AAudio_DeviceType device,aaudio_direction_t direction)58 AAUDIO_API aaudio_policy_t AAudio_getPlatformMMapPolicy(
59         AAudio_DeviceType device, aaudio_direction_t direction) {
60     return AudioGlobal_getPlatformMMapPolicy(device, direction);
61 }
62 
AAudio_getPlatformMMapExclusivePolicy(AAudio_DeviceType device,aaudio_direction_t direction)63 AAUDIO_API aaudio_policy_t AAudio_getPlatformMMapExclusivePolicy(
64         AAudio_DeviceType device, aaudio_direction_t direction) {
65     return AudioGlobal_getPlatformMMapExclusivePolicy(device, direction);
66 }
67 
convertAAudioStreamToAudioStream(AAudioStream * stream)68 static AudioStream *convertAAudioStreamToAudioStream(AAudioStream* stream)
69 {
70     return (AudioStream*) stream;
71 }
72 
convertAAudioBuilderToStreamBuilder(AAudioStreamBuilder * builder)73 static AudioStreamBuilder *convertAAudioBuilderToStreamBuilder(AAudioStreamBuilder* builder)
74 {
75     return (AudioStreamBuilder*) builder;
76 }
77 
AAudio_createStreamBuilder(AAudioStreamBuilder ** builder)78 AAUDIO_API aaudio_result_t AAudio_createStreamBuilder(AAudioStreamBuilder** builder)
79 {
80     AudioStreamBuilder *audioStreamBuilder =  new(std::nothrow) AudioStreamBuilder();
81     if (audioStreamBuilder == nullptr) {
82         return AAUDIO_ERROR_NO_MEMORY;
83     }
84     *builder = (AAudioStreamBuilder*) audioStreamBuilder;
85     return AAUDIO_OK;
86 }
87 
AAudioStreamBuilder_setPerformanceMode(AAudioStreamBuilder * builder,aaudio_performance_mode_t mode)88 AAUDIO_API void AAudioStreamBuilder_setPerformanceMode(AAudioStreamBuilder* builder,
89                                                        aaudio_performance_mode_t mode)
90 {
91     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
92     streamBuilder->setPerformanceMode(mode);
93 }
94 
AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder * builder,int32_t deviceId)95 AAUDIO_API void AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder* builder,
96                                                 int32_t deviceId)
97 {
98     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
99     android::DeviceIdVector deviceIds;
100     if (deviceId != AAUDIO_UNSPECIFIED) {
101         deviceIds.push_back(deviceId);
102     }
103     streamBuilder->setDeviceIds(deviceIds);
104 }
105 
AAudioStreamBuilder_setPackageName(AAudioStreamBuilder * builder,const char * packageName)106 AAUDIO_API void AAudioStreamBuilder_setPackageName(AAudioStreamBuilder* builder,
107                                                    const char* packageName)
108 {
109     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
110     std::optional<std::string> optionalPackageName;
111     if (packageName != nullptr) {
112       optionalPackageName = std::string(packageName);
113     }
114     // Only system apps can read the op package name. For regular apps the
115     // regular package name is a sufficient replacement
116     streamBuilder->setOpPackageName(optionalPackageName);
117 }
118 
AAudioStreamBuilder_setAttributionTag(AAudioStreamBuilder * builder,const char * attributionTag)119 AAUDIO_API void AAudioStreamBuilder_setAttributionTag(AAudioStreamBuilder* builder,
120                                                       const char* attributionTag)
121 {
122     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
123     std::optional<std::string> optionalAttrTag;
124     if (attributionTag != nullptr) {
125       optionalAttrTag = std::string(attributionTag);
126     }
127     streamBuilder->setAttributionTag(optionalAttrTag);
128 }
129 
AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder * builder,int32_t sampleRate)130 AAUDIO_API void AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder* builder,
131                                               int32_t sampleRate)
132 {
133     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
134     streamBuilder->setSampleRate(sampleRate);
135 }
136 
AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder * builder,int32_t channelCount)137 AAUDIO_API void AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder* builder,
138                                                     int32_t channelCount)
139 {
140     AAudioStreamBuilder_setSamplesPerFrame(builder, channelCount);
141 }
142 
AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder * builder,int32_t samplesPerFrame)143 AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder,
144                                                        int32_t samplesPerFrame)
145 {
146     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
147     const aaudio_channel_mask_t channelMask = AAudioConvert_channelCountToMask(samplesPerFrame);
148     streamBuilder->setChannelMask(channelMask);
149 }
150 
AAudioStreamBuilder_setDirection(AAudioStreamBuilder * builder,aaudio_direction_t direction)151 AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* builder,
152                                              aaudio_direction_t direction)
153 {
154     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
155     streamBuilder->setDirection(direction);
156 }
157 
AAudioStreamBuilder_setFormat(AAudioStreamBuilder * builder,aaudio_format_t format)158 AAUDIO_API void AAudioStreamBuilder_setFormat(AAudioStreamBuilder* builder,
159                                                    aaudio_format_t format)
160 {
161     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
162     // Use audio_format_t everywhere internally.
163     const audio_format_t internalFormat = AAudioConvert_aaudioToAndroidDataFormat(format);
164     streamBuilder->setFormat(internalFormat);
165 }
166 
AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder * builder,aaudio_sharing_mode_t sharingMode)167 AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* builder,
168                                                         aaudio_sharing_mode_t sharingMode)
169 {
170     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
171     streamBuilder->setSharingMode(sharingMode);
172 }
173 
AAudioStreamBuilder_setUsage(AAudioStreamBuilder * builder,aaudio_usage_t usage)174 AAUDIO_API void AAudioStreamBuilder_setUsage(AAudioStreamBuilder* builder,
175                                              aaudio_usage_t usage) {
176     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
177     streamBuilder->setUsage(usage);
178 }
179 
AAudioStreamBuilder_setContentType(AAudioStreamBuilder * builder,aaudio_content_type_t contentType)180 AAUDIO_API void AAudioStreamBuilder_setContentType(AAudioStreamBuilder* builder,
181                                                    aaudio_content_type_t contentType) {
182     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
183     streamBuilder->setContentType(contentType);
184 }
185 
AAudioStreamBuilder_addTag(AAudioStreamBuilder * builder,const char * tags)186 AAUDIO_API aaudio_result_t AAudioStreamBuilder_addTag(AAudioStreamBuilder* builder,
187                                                       const char* tags) {
188     if (tags == nullptr) {
189         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
190     }
191     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
192     return streamBuilder->addTag(tags);
193 }
194 
AAudioStreamBuilder_clearTags(AAudioStreamBuilder * builder)195 AAUDIO_API void AAudioStreamBuilder_clearTags(AAudioStreamBuilder* builder) {
196     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
197     streamBuilder->clearTags();
198 }
199 
AAudioStreamBuilder_setSpatializationBehavior(AAudioStreamBuilder * builder,aaudio_spatialization_behavior_t spatializationBehavior)200 AAUDIO_API void AAudioStreamBuilder_setSpatializationBehavior(AAudioStreamBuilder* builder,
201         aaudio_spatialization_behavior_t spatializationBehavior) {
202     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
203     streamBuilder->setSpatializationBehavior(spatializationBehavior);
204 }
205 
AAudioStreamBuilder_setIsContentSpatialized(AAudioStreamBuilder * builder,bool isSpatialized)206 AAUDIO_API void AAudioStreamBuilder_setIsContentSpatialized(AAudioStreamBuilder* builder,
207                                                             bool isSpatialized) {
208     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
209     streamBuilder->setIsContentSpatialized(isSpatialized);
210 }
211 
AAudioStreamBuilder_setInputPreset(AAudioStreamBuilder * builder,aaudio_input_preset_t inputPreset)212 AAUDIO_API void AAudioStreamBuilder_setInputPreset(AAudioStreamBuilder* builder,
213                                                    aaudio_input_preset_t inputPreset) {
214     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
215     streamBuilder->setInputPreset(inputPreset);
216 }
217 
AAudioStreamBuilder_setPrivacySensitive(AAudioStreamBuilder * builder,bool privacySensitive)218 AAUDIO_API void AAudioStreamBuilder_setPrivacySensitive(AAudioStreamBuilder* builder,
219                                                    bool privacySensitive) {
220     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
221     streamBuilder->setPrivacySensitiveRequest(privacySensitive);
222 }
223 
AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder * builder,int32_t frames)224 AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder,
225                                                               int32_t frames)
226 {
227     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
228     streamBuilder->setBufferCapacity(frames);
229 }
230 
AAudioStreamBuilder_setAllowedCapturePolicy(AAudioStreamBuilder * builder,aaudio_allowed_capture_policy_t policy)231 AAUDIO_API void AAudioStreamBuilder_setAllowedCapturePolicy(
232         AAudioStreamBuilder* builder, aaudio_allowed_capture_policy_t policy) {
233     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
234     streamBuilder->setAllowedCapturePolicy(policy);
235 }
236 
AAudioStreamBuilder_setSessionId(AAudioStreamBuilder * builder,aaudio_session_id_t sessionId)237 AAUDIO_API void AAudioStreamBuilder_setSessionId(AAudioStreamBuilder* builder,
238                                                  aaudio_session_id_t sessionId)
239 {
240     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
241     streamBuilder->setSessionId(sessionId);
242 }
243 
AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder * builder,AAudioStream_dataCallback callback,void * userData)244 AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* builder,
245                                                     AAudioStream_dataCallback callback,
246                                                     void *userData)
247 {
248     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
249     streamBuilder->setDataCallbackProc(callback);
250     streamBuilder->setDataCallbackUserData(userData);
251 }
252 
AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder * builder,AAudioStream_errorCallback callback,void * userData)253 AAUDIO_API void AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder* builder,
254                                                  AAudioStream_errorCallback callback,
255                                                  void *userData)
256 {
257     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
258     streamBuilder->setErrorCallbackProc(callback);
259     streamBuilder->setErrorCallbackUserData(userData);
260 }
261 
AAudioStreamBuilder_setPresentationEndCallback(AAudioStreamBuilder * builder,AAudioStream_presentationEndCallback callback,void * userData)262 AAUDIO_API void AAudioStreamBuilder_setPresentationEndCallback(AAudioStreamBuilder* builder,
263         AAudioStream_presentationEndCallback callback, void* userData) {
264     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
265     if (streamBuilder == nullptr) {
266         return;
267     }
268     streamBuilder->setPresentationEndCallbackProc(callback)
269                  ->setPresentationEndCallbackUserData(userData);
270 }
271 
AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder * builder,int32_t frames)272 AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* builder,
273                                                 int32_t frames)
274 {
275     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
276     streamBuilder->setFramesPerDataCallback(frames);
277 }
278 
AAudioStreamBuilder_setChannelMask(AAudioStreamBuilder * builder,aaudio_channel_mask_t channelMask)279 AAUDIO_API void AAudioStreamBuilder_setChannelMask(AAudioStreamBuilder* builder,
280                                                    aaudio_channel_mask_t channelMask)
281 {
282     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
283     streamBuilder->setChannelMask(channelMask);
284 }
285 
AAudioStreamBuilder_openStream(AAudioStreamBuilder * builder,AAudioStream ** streamPtr)286 AAUDIO_API aaudio_result_t  AAudioStreamBuilder_openStream(AAudioStreamBuilder* builder,
287                                                      AAudioStream** streamPtr)
288 {
289     AudioStream *audioStream = nullptr;
290     aaudio_stream_id_t id = 0;
291     // Please leave these logs because they are very helpful when debugging.
292     ALOGI("%s() called ----------------------------------------", __func__);
293     AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(streamPtr);
294     aaudio_result_t result = streamBuilder->build(&audioStream);
295     if (result == AAUDIO_OK) {
296         *streamPtr = (AAudioStream*) audioStream;
297         id = audioStream->getId();
298     } else {
299         *streamPtr = nullptr;
300     }
301     ALOGI("%s() returns %d = %s for s#%u ----------------",
302         __func__, result, AAudio_convertResultToText(result), id);
303     return result;
304 }
305 
AAudioStreamBuilder_delete(AAudioStreamBuilder * builder)306 AAUDIO_API aaudio_result_t  AAudioStreamBuilder_delete(AAudioStreamBuilder* builder)
307 {
308     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
309     if (streamBuilder != nullptr) {
310         delete streamBuilder;
311         return AAUDIO_OK;
312     }
313     return AAUDIO_ERROR_NULL;
314 }
315 
AAudioStream_release(AAudioStream * stream)316 AAUDIO_API aaudio_result_t  AAudioStream_release(AAudioStream* stream) {
317     aaudio_result_t result = AAUDIO_ERROR_NULL;
318     AudioStream* audioStream = convertAAudioStreamToAudioStream(stream);
319     if (audioStream != nullptr) {
320         aaudio_stream_id_t id = audioStream->getId();
321         ALOGD("%s(s#%u) called ---------------", __func__, id);
322         result = audioStream->safeRelease();
323         // safeRelease() will only fail if called illegally, for example, from a callback.
324         // That would result in the release of an active stream, which would cause a crash.
325         if (result != AAUDIO_OK) {
326             ALOGW("%s(s#%u) failed. Release it from another thread.",
327                   __func__, id);
328         }
329         ALOGD("%s(s#%u) returned %d %s ---------", __func__,
330                 id, result, AAudio_convertResultToText(result));
331     }
332     return result;
333 }
334 
AAudioStream_close(AAudioStream * stream)335 AAUDIO_API aaudio_result_t  AAudioStream_close(AAudioStream* stream) {
336     aaudio_result_t result = AAUDIO_ERROR_NULL;
337     AudioStream* audioStream = convertAAudioStreamToAudioStream(stream);
338     if (audioStream != nullptr) {
339         aaudio_stream_id_t id = audioStream->getId();
340         ALOGD("%s(s#%u) called ---------------", __func__, id);
341         result = audioStream->safeReleaseClose();
342         // safeReleaseClose will only fail if called illegally, for example, from a callback.
343         // That would result in deleting an active stream, which would cause a crash.
344         if (result != AAUDIO_OK) {
345             ALOGW("%s(s#%u) failed. Close it from another thread.",
346                   __func__, id);
347         } else {
348             audioStream->unregisterPlayerBase();
349             // Allow the stream to be deleted.
350             AudioStreamBuilder::stopUsingStream(audioStream);
351         }
352         ALOGD("%s(s#%u) returned %d ---------", __func__, id, result);
353     }
354     return result;
355 }
356 
AAudioStream_requestStart(AAudioStream * stream)357 AAUDIO_API aaudio_result_t  AAudioStream_requestStart(AAudioStream* stream)
358 {
359     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
360     aaudio_stream_id_t id = audioStream->getId();
361     ALOGD("%s(s#%u) called --------------", __func__, id);
362     aaudio_result_t result = audioStream->systemStart();
363     ALOGD("%s(s#%u) returned %d ---------", __func__, id, result);
364     return result;
365 }
366 
AAudioStream_requestPause(AAudioStream * stream)367 AAUDIO_API aaudio_result_t  AAudioStream_requestPause(AAudioStream* stream)
368 {
369     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
370     ALOGD("%s(s#%u) called", __func__, audioStream->getId());
371     return audioStream->systemPause();
372 }
373 
AAudioStream_requestFlush(AAudioStream * stream)374 AAUDIO_API aaudio_result_t  AAudioStream_requestFlush(AAudioStream* stream)
375 {
376     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
377     ALOGD("%s(s#%u) called", __func__, audioStream->getId());
378     return audioStream->safeFlush();
379 }
380 
AAudioStream_requestStop(AAudioStream * stream)381 AAUDIO_API aaudio_result_t  AAudioStream_requestStop(AAudioStream* stream)
382 {
383     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
384     ALOGD("%s(s#%u) called", __func__, audioStream->getId());
385     return audioStream->systemStopFromApp();
386 }
387 
AAudioStream_waitForStateChange(AAudioStream * stream,aaudio_stream_state_t inputState,aaudio_stream_state_t * nextState,int64_t timeoutNanoseconds)388 AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream,
389                                             aaudio_stream_state_t inputState,
390                                             aaudio_stream_state_t *nextState,
391                                             int64_t timeoutNanoseconds)
392 {
393 
394     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
395     android::sp<AudioStream> spAudioStream(audioStream);
396     return spAudioStream->waitForStateChange(inputState, nextState, timeoutNanoseconds);
397 }
398 
399 // ============================================================
400 // Stream - non-blocking I/O
401 // ============================================================
402 
AAudioStream_read(AAudioStream * stream,void * buffer,int32_t numFrames,int64_t timeoutNanoseconds)403 AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* stream,
404                                void *buffer,
405                                int32_t numFrames,
406                                int64_t timeoutNanoseconds)
407 {
408     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
409     if (buffer == nullptr) {
410         return AAUDIO_ERROR_NULL;
411     }
412     if (numFrames < 0) {
413         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
414     } else if (numFrames == 0) {
415         return 0;
416     }
417 
418     aaudio_result_t result = audioStream->read(buffer, numFrames, timeoutNanoseconds);
419 
420     return result;
421 }
422 
AAudioStream_write(AAudioStream * stream,const void * buffer,int32_t numFrames,int64_t timeoutNanoseconds)423 AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream,
424                                const void *buffer,
425                                int32_t numFrames,
426                                int64_t timeoutNanoseconds)
427 {
428     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
429     if (buffer == nullptr) {
430         return AAUDIO_ERROR_NULL;
431     }
432 
433     // Don't allow writes when playing with a callback.
434     if (audioStream->isDataCallbackActive()) {
435         // A developer requested this warning because it would have saved lots of debugging.
436         ALOGW("%s() - Cannot write to a callback stream when running.", __func__);
437         return AAUDIO_ERROR_INVALID_STATE;
438     }
439 
440     if (numFrames < 0) {
441         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
442     } else if (numFrames == 0) {
443         return 0;
444     }
445 
446     aaudio_result_t result = audioStream->write(buffer, numFrames, timeoutNanoseconds);
447 
448     return result;
449 }
450 
451 // ============================================================
452 // Stream - queries
453 // ============================================================
454 
AAudioStream_getSampleRate(AAudioStream * stream)455 AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream)
456 {
457     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
458     return audioStream->getSampleRate();
459 }
460 
AAudioStream_getHardwareSampleRate(AAudioStream * stream)461 AAUDIO_API int32_t AAudioStream_getHardwareSampleRate(AAudioStream* stream)
462 {
463     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
464     return audioStream->getHardwareSampleRate();
465 }
466 
AAudioStream_getChannelCount(AAudioStream * stream)467 AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream)
468 {
469     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
470     return audioStream->getSamplesPerFrame();
471 }
472 
AAudioStream_getHardwareChannelCount(AAudioStream * stream)473 AAUDIO_API int32_t AAudioStream_getHardwareChannelCount(AAudioStream* stream)
474 {
475     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
476     return audioStream->getHardwareSamplesPerFrame();
477 }
478 
AAudioStream_getSamplesPerFrame(AAudioStream * stream)479 AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream)
480 {
481     return AAudioStream_getChannelCount(stream);
482 }
483 
AAudioStream_getState(AAudioStream * stream)484 AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream)
485 {
486     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
487     return audioStream->getStateExternal();
488 }
489 
AAudioStream_getFormat(AAudioStream * stream)490 AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* stream)
491 {
492     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
493     // Use audio_format_t internally.
494     audio_format_t internalFormat = audioStream->getFormat();
495     return AAudioConvert_androidToAAudioDataFormat(internalFormat);
496 }
497 
AAudioStream_getHardwareFormat(AAudioStream * stream)498 AAUDIO_API aaudio_format_t AAudioStream_getHardwareFormat(AAudioStream* stream)
499 {
500     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
501     // Use audio_format_t internally.
502     audio_format_t internalFormat = audioStream->getHardwareFormat();
503     return AAudioConvert_androidToNearestAAudioDataFormat(internalFormat);
504 }
505 
AAudioStream_setBufferSizeInFrames(AAudioStream * stream,int32_t requestedFrames)506 AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* stream,
507                                                 int32_t requestedFrames)
508 {
509     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
510     return audioStream->setBufferSize(requestedFrames);
511 }
512 
AAudioStream_getBufferSizeInFrames(AAudioStream * stream)513 AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* stream)
514 {
515     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
516     return audioStream->getBufferSize();
517 }
518 
AAudioStream_getDirection(AAudioStream * stream)519 AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* stream)
520 {
521     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
522     return audioStream->getDirection();
523 }
524 
AAudioStream_getFramesPerBurst(AAudioStream * stream)525 AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* stream)
526 {
527     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
528     return audioStream->getFramesPerBurst();
529 }
530 
AAudioStream_getFramesPerDataCallback(AAudioStream * stream)531 AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream)
532 {
533     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
534     return audioStream->getFramesPerDataCallback();
535 }
536 
AAudioStream_getBufferCapacityInFrames(AAudioStream * stream)537 AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream)
538 {
539     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
540     return audioStream->getBufferCapacity();
541 }
542 
AAudioStream_getXRunCount(AAudioStream * stream)543 AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream)
544 {
545     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
546     return audioStream->getXRunCount();
547 }
548 
AAudioStream_getPerformanceMode(AAudioStream * stream)549 AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* stream)
550 {
551     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
552     return audioStream->getPerformanceMode();
553 }
554 
AAudioStream_getDeviceId(AAudioStream * stream)555 AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream)
556 {
557     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
558     auto deviceIds = audioStream->getDeviceIds();
559     if (deviceIds.empty()) {
560         return AAUDIO_UNSPECIFIED;
561     }
562     return deviceIds[0];
563 }
564 
AAudioStream_getDeviceIds(AAudioStream * stream,int32_t * ids,int32_t * numIds)565 AAUDIO_API aaudio_result_t AAudioStream_getDeviceIds(AAudioStream* stream, int32_t* ids,
566                                                      int32_t* numIds)
567 {
568     if (numIds == nullptr) {
569         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
570     }
571     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
572     auto deviceIds = audioStream->getDeviceIds();
573     if (*numIds < deviceIds.size()) {
574         *numIds = deviceIds.size();
575         return AAUDIO_ERROR_OUT_OF_RANGE;
576     }
577     if (ids == nullptr) {
578         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
579     }
580     for (int i = 0; i < deviceIds.size(); i++) {
581         ids[i] = deviceIds[i];
582     }
583     *numIds = deviceIds.size();
584     return AAUDIO_OK;
585 }
586 
AAudioStream_getSharingMode(AAudioStream * stream)587 AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream)
588 {
589     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
590     return audioStream->getSharingMode();
591 }
592 
AAudioStream_getUsage(AAudioStream * stream)593 AAUDIO_API aaudio_usage_t AAudioStream_getUsage(AAudioStream* stream)
594 {
595     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
596     return audioStream->getUsage();
597 }
598 
AAudioStream_getContentType(AAudioStream * stream)599 AAUDIO_API aaudio_content_type_t AAudioStream_getContentType(AAudioStream* stream)
600 {
601     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
602     return audioStream->getContentType();
603 }
604 
AAudioStream_obtainTags(AAudioStream * stream,char *** tags)605 AAUDIO_API int32_t AAudioStream_obtainTags(AAudioStream* stream, char*** tags)
606 {
607     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
608     auto aaTags = audioStream->getTags();
609     if (aaTags.empty()) {
610         *tags = nullptr;
611         return 0;
612     }
613     *tags = new char*[aaTags.size()];
614     if (*tags == nullptr) {
615         return AAUDIO_ERROR_NO_MEMORY;
616     }
617     auto it = aaTags.begin();
618     for (int i = 0; it != aaTags.end(); i++, it++) {
619         (*tags)[i] = new char[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE];
620         if ((*tags)[i] == nullptr) {
621             for (int j = 0; j < i; ++j) {
622                 delete[] (*tags)[i];
623             }
624             delete[] (*tags);
625             return AAUDIO_ERROR_NO_MEMORY;
626         }
627         strcpy((*tags)[i], it->c_str());
628     }
629     return aaTags.size();
630 }
631 
AAudioStream_releaseTags(AAudioStream * stream,char ** tags)632 AAUDIO_API void AAudioStream_releaseTags(AAudioStream* stream, char** tags) {
633     if (tags == nullptr) {
634         return;
635     }
636     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
637     const int tagsNum = audioStream->getTags().size();
638     for (int i = 0; i < tagsNum; ++i) {
639         delete[] tags[i];
640     }
641     delete[] tags;
642 }
643 
AAudioStream_getSpatializationBehavior(AAudioStream * stream)644 AAUDIO_API aaudio_spatialization_behavior_t AAudioStream_getSpatializationBehavior(
645         AAudioStream* stream)
646 {
647     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
648     return audioStream->getSpatializationBehavior();
649 }
650 
AAudioStream_isContentSpatialized(AAudioStream * stream)651 AAUDIO_API bool AAudioStream_isContentSpatialized(AAudioStream* stream)
652 {
653     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
654     return audioStream->isContentSpatialized();
655 }
656 
AAudioStream_getInputPreset(AAudioStream * stream)657 AAUDIO_API aaudio_input_preset_t AAudioStream_getInputPreset(AAudioStream* stream)
658 {
659     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
660     return audioStream->getInputPreset();
661 }
662 
AAudioStream_getAllowedCapturePolicy(AAudioStream * stream)663 AAUDIO_API aaudio_allowed_capture_policy_t AAudioStream_getAllowedCapturePolicy(
664         AAudioStream* stream)
665 {
666     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
667     return audioStream->getAllowedCapturePolicy();
668 }
669 
AAudioStream_getSessionId(AAudioStream * stream)670 AAUDIO_API int32_t AAudioStream_getSessionId(AAudioStream* stream)
671 {
672     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
673     return audioStream->getSessionId();
674 }
675 
AAudioStream_getFramesWritten(AAudioStream * stream)676 AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream)
677 {
678     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
679     return audioStream->getFramesWritten() * audioStream->getSampleRate() /
680             audioStream->getDeviceSampleRate();
681 }
682 
AAudioStream_getFramesRead(AAudioStream * stream)683 AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream)
684 {
685     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
686     return audioStream->getFramesRead() * audioStream->getSampleRate() /
687             audioStream->getDeviceSampleRate();
688 }
689 
AAudioStream_getTimestamp(AAudioStream * stream,clockid_t clockid,int64_t * framePosition,int64_t * timeNanoseconds)690 AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* stream,
691                                       clockid_t clockid,
692                                       int64_t *framePosition,
693                                       int64_t *timeNanoseconds)
694 {
695     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
696     if (framePosition == nullptr || timeNanoseconds == nullptr) {
697         return AAUDIO_ERROR_NULL;
698     } else if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_BOOTTIME) {
699         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
700     }
701 
702     return audioStream->getTimestamp(clockid, framePosition, timeNanoseconds);
703 }
704 
AAudio_getMMapPolicy()705 AAUDIO_API aaudio_policy_t AAudio_getMMapPolicy() {
706     return AudioGlobal_getMMapPolicy();
707 }
708 
AAudio_setMMapPolicy(aaudio_policy_t policy)709 AAUDIO_API aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy) {
710     ALOGD("%s(%d)", __func__, policy);
711     return AudioGlobal_setMMapPolicy(policy);
712 }
713 
AAudioStream_isMMapUsed(AAudioStream * stream)714 AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream)
715 {
716     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
717     return audioStream->isMMap();
718 }
719 
AAudioStream_isPrivacySensitive(AAudioStream * stream)720 AAUDIO_API bool AAudioStream_isPrivacySensitive(AAudioStream* stream)
721 {
722     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
723     return audioStream->isPrivacySensitive();
724 }
725 
AAudioStream_getChannelMask(AAudioStream * stream)726 AAUDIO_API aaudio_channel_mask_t AAudioStream_getChannelMask(AAudioStream* stream)
727 {
728     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
729     const aaudio_channel_mask_t channelMask = audioStream->getChannelMask();
730     // Do not return channel index masks as they are not public.
731     return AAudio_isChannelIndexMask(channelMask) ? AAUDIO_UNSPECIFIED : channelMask;
732 }
733 
AAudioStream_setOffloadDelayPadding(AAudioStream * stream,int32_t delayInFrames,int32_t paddingInFrames)734 AAUDIO_API aaudio_result_t AAudioStream_setOffloadDelayPadding(
735         AAudioStream* stream, int32_t delayInFrames, int32_t paddingInFrames) {
736     if (delayInFrames < 0 || paddingInFrames < 0) {
737         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
738     }
739     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
740     return audioStream->setOffloadDelayPadding(delayInFrames, paddingInFrames);
741 }
742 
AAudioStream_getOffloadDelay(AAudioStream * stream)743 AAUDIO_API int32_t AAudioStream_getOffloadDelay(AAudioStream* stream) {
744     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
745     return audioStream->getOffloadDelay();
746 }
747 
AAudioStream_getOffloadPadding(AAudioStream * stream)748 AAUDIO_API int32_t AAudioStream_getOffloadPadding(AAudioStream* stream) {
749     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
750     return audioStream->getOffloadPadding();
751 }
752 
AAudioStream_setOffloadEndOfStream(AAudioStream * stream)753 AAUDIO_API aaudio_result_t AAudioStream_setOffloadEndOfStream(AAudioStream* stream) {
754     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
755     return audioStream->setOffloadEndOfStream();
756 }
757