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