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