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