• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     AAudioStreamBuilder_setSamplesPerFrame(builder, channelCount);
150 }
151 
AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder * builder,int32_t samplesPerFrame)152 AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder,
153                                                        int32_t samplesPerFrame)
154 {
155     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
156     streamBuilder->setSamplesPerFrame(samplesPerFrame);
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     // Use audio_format_t everywhere internally.
171     const audio_format_t internalFormat = AAudioConvert_aaudioToAndroidDataFormat(format);
172     streamBuilder->setFormat(internalFormat);
173 }
174 
AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder * builder,aaudio_sharing_mode_t sharingMode)175 AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* builder,
176                                                         aaudio_sharing_mode_t sharingMode)
177 {
178     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
179     streamBuilder->setSharingMode(sharingMode);
180 }
181 
AAudioStreamBuilder_setUsage(AAudioStreamBuilder * builder,aaudio_usage_t usage)182 AAUDIO_API void AAudioStreamBuilder_setUsage(AAudioStreamBuilder* builder,
183                                              aaudio_usage_t usage) {
184     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
185     streamBuilder->setUsage(usage);
186 }
187 
AAudioStreamBuilder_setContentType(AAudioStreamBuilder * builder,aaudio_content_type_t contentType)188 AAUDIO_API void AAudioStreamBuilder_setContentType(AAudioStreamBuilder* builder,
189                                                    aaudio_content_type_t contentType) {
190     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
191     streamBuilder->setContentType(contentType);
192 }
193 
AAudioStreamBuilder_setInputPreset(AAudioStreamBuilder * builder,aaudio_input_preset_t inputPreset)194 AAUDIO_API void AAudioStreamBuilder_setInputPreset(AAudioStreamBuilder* builder,
195                                                    aaudio_input_preset_t inputPreset) {
196     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
197     streamBuilder->setInputPreset(inputPreset);
198 }
199 
AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder * builder,int32_t frames)200 AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder,
201                                                               int32_t frames)
202 {
203     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
204     streamBuilder->setBufferCapacity(frames);
205 }
206 
AAudioStreamBuilder_setAllowedCapturePolicy(AAudioStreamBuilder * builder,aaudio_allowed_capture_policy_t policy)207 AAUDIO_API void AAudioStreamBuilder_setAllowedCapturePolicy(
208         AAudioStreamBuilder* builder, aaudio_allowed_capture_policy_t policy) {
209     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
210     streamBuilder->setAllowedCapturePolicy(policy);
211 }
212 
AAudioStreamBuilder_setSessionId(AAudioStreamBuilder * builder,aaudio_session_id_t sessionId)213 AAUDIO_API void AAudioStreamBuilder_setSessionId(AAudioStreamBuilder* builder,
214                                                  aaudio_session_id_t sessionId)
215 {
216     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
217     streamBuilder->setSessionId(sessionId);
218 }
219 
AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder * builder,AAudioStream_dataCallback callback,void * userData)220 AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* builder,
221                                                     AAudioStream_dataCallback callback,
222                                                     void *userData)
223 {
224     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
225     streamBuilder->setDataCallbackProc(callback);
226     streamBuilder->setDataCallbackUserData(userData);
227 }
228 
AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder * builder,AAudioStream_errorCallback callback,void * userData)229 AAUDIO_API void AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder* builder,
230                                                  AAudioStream_errorCallback callback,
231                                                  void *userData)
232 {
233     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
234     streamBuilder->setErrorCallbackProc(callback);
235     streamBuilder->setErrorCallbackUserData(userData);
236 }
237 
AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder * builder,int32_t frames)238 AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* builder,
239                                                 int32_t frames)
240 {
241     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
242     streamBuilder->setFramesPerDataCallback(frames);
243 }
244 
AAudioStreamBuilder_openStream(AAudioStreamBuilder * builder,AAudioStream ** streamPtr)245 AAUDIO_API aaudio_result_t  AAudioStreamBuilder_openStream(AAudioStreamBuilder* builder,
246                                                      AAudioStream** streamPtr)
247 {
248     AudioStream *audioStream = nullptr;
249     aaudio_stream_id_t id = 0;
250     // Please leave these logs because they are very helpful when debugging.
251     ALOGI("%s() called ----------------------------------------", __func__);
252     AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(streamPtr);
253     aaudio_result_t result = streamBuilder->build(&audioStream);
254     if (result == AAUDIO_OK) {
255         audioStream->registerPlayerBase();
256         *streamPtr = (AAudioStream*) audioStream;
257         id = audioStream->getId();
258     } else {
259         *streamPtr = nullptr;
260     }
261     ALOGI("%s() returns %d = %s for s#%u ----------------",
262         __func__, result, AAudio_convertResultToText(result), id);
263     return result;
264 }
265 
AAudioStreamBuilder_delete(AAudioStreamBuilder * builder)266 AAUDIO_API aaudio_result_t  AAudioStreamBuilder_delete(AAudioStreamBuilder* builder)
267 {
268     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
269     if (streamBuilder != nullptr) {
270         delete streamBuilder;
271         return AAUDIO_OK;
272     }
273     return AAUDIO_ERROR_NULL;
274 }
275 
AAudioStream_close(AAudioStream * stream)276 AAUDIO_API aaudio_result_t  AAudioStream_close(AAudioStream* stream)
277 {
278     aaudio_result_t result = AAUDIO_ERROR_NULL;
279     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
280     if (audioStream != nullptr) {
281         aaudio_stream_id_t id = audioStream->getId();
282         ALOGD("%s(s#%u) called ---------------", __func__, id);
283         result = audioStream->safeClose();
284         // Close will only fail if called illegally, for example, from a callback.
285         // That would result in deleting an active stream, which would cause a crash.
286         if (result == AAUDIO_OK) {
287             audioStream->unregisterPlayerBase();
288             delete audioStream;
289         } else {
290             ALOGW("%s attempt to close failed. Close it from another thread.", __func__);
291         }
292         ALOGD("%s(s#%u) returned %d ---------", __func__, id, result);
293     }
294     return result;
295 }
296 
AAudioStream_requestStart(AAudioStream * stream)297 AAUDIO_API aaudio_result_t  AAudioStream_requestStart(AAudioStream* stream)
298 {
299     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
300     aaudio_stream_id_t id = audioStream->getId();
301     ALOGD("%s(s#%u) called --------------", __func__, id);
302     aaudio_result_t result = audioStream->systemStart();
303     ALOGD("%s(s#%u) returned %d ---------", __func__, id, result);
304     return result;
305 }
306 
AAudioStream_requestPause(AAudioStream * stream)307 AAUDIO_API aaudio_result_t  AAudioStream_requestPause(AAudioStream* stream)
308 {
309     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
310     ALOGD("%s(s#%u) called", __func__, audioStream->getId());
311     return audioStream->systemPause();
312 }
313 
AAudioStream_requestFlush(AAudioStream * stream)314 AAUDIO_API aaudio_result_t  AAudioStream_requestFlush(AAudioStream* stream)
315 {
316     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
317     ALOGD("%s(s#%u) called", __func__, audioStream->getId());
318     return audioStream->safeFlush();
319 }
320 
AAudioStream_requestStop(AAudioStream * stream)321 AAUDIO_API aaudio_result_t  AAudioStream_requestStop(AAudioStream* stream)
322 {
323     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
324     ALOGD("%s(s#%u) called", __func__, audioStream->getId());
325     return audioStream->systemStopFromApp();
326 }
327 
AAudioStream_waitForStateChange(AAudioStream * stream,aaudio_stream_state_t inputState,aaudio_stream_state_t * nextState,int64_t timeoutNanoseconds)328 AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream,
329                                             aaudio_stream_state_t inputState,
330                                             aaudio_stream_state_t *nextState,
331                                             int64_t timeoutNanoseconds)
332 {
333 
334     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
335     return audioStream->waitForStateChange(inputState, nextState, timeoutNanoseconds);
336 }
337 
338 // ============================================================
339 // Stream - non-blocking I/O
340 // ============================================================
341 
AAudioStream_read(AAudioStream * stream,void * buffer,int32_t numFrames,int64_t timeoutNanoseconds)342 AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* stream,
343                                void *buffer,
344                                int32_t numFrames,
345                                int64_t timeoutNanoseconds)
346 {
347     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
348     if (buffer == nullptr) {
349         return AAUDIO_ERROR_NULL;
350     }
351     if (numFrames < 0) {
352         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
353     } else if (numFrames == 0) {
354         return 0;
355     }
356 
357     aaudio_result_t result = audioStream->read(buffer, numFrames, timeoutNanoseconds);
358 
359     return result;
360 }
361 
AAudioStream_write(AAudioStream * stream,const void * buffer,int32_t numFrames,int64_t timeoutNanoseconds)362 AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream,
363                                const void *buffer,
364                                int32_t numFrames,
365                                int64_t timeoutNanoseconds)
366 {
367     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
368     if (buffer == nullptr) {
369         return AAUDIO_ERROR_NULL;
370     }
371 
372     // Don't allow writes when playing with a callback.
373     if (audioStream->isDataCallbackActive()) {
374         ALOGD("Cannot write to a callback stream when running.");
375         return AAUDIO_ERROR_INVALID_STATE;
376     }
377 
378     if (numFrames < 0) {
379         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
380     } else if (numFrames == 0) {
381         return 0;
382     }
383 
384     aaudio_result_t result = audioStream->write(buffer, numFrames, timeoutNanoseconds);
385 
386     return result;
387 }
388 
389 // ============================================================
390 // Stream - queries
391 // ============================================================
392 
AAudioStream_getSampleRate(AAudioStream * stream)393 AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream)
394 {
395     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
396     return audioStream->getSampleRate();
397 }
398 
AAudioStream_getChannelCount(AAudioStream * stream)399 AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream)
400 {
401     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
402     return audioStream->getSamplesPerFrame();
403 }
404 
AAudioStream_getSamplesPerFrame(AAudioStream * stream)405 AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream)
406 {
407     return AAudioStream_getChannelCount(stream);
408 }
409 
AAudioStream_getState(AAudioStream * stream)410 AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream)
411 {
412     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
413     return audioStream->getState();
414 }
415 
AAudioStream_getFormat(AAudioStream * stream)416 AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* stream)
417 {
418     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
419     // Use audio_format_t internally.
420     audio_format_t internalFormat = audioStream->getFormat();
421     return AAudioConvert_androidToAAudioDataFormat(internalFormat);
422 }
423 
AAudioStream_setBufferSizeInFrames(AAudioStream * stream,int32_t requestedFrames)424 AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* stream,
425                                                 int32_t requestedFrames)
426 {
427     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
428     return audioStream->setBufferSize(requestedFrames);
429 }
430 
AAudioStream_getBufferSizeInFrames(AAudioStream * stream)431 AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* stream)
432 {
433     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
434     return audioStream->getBufferSize();
435 }
436 
AAudioStream_getDirection(AAudioStream * stream)437 AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* stream)
438 {
439     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
440     return audioStream->getDirection();
441 }
442 
AAudioStream_getFramesPerBurst(AAudioStream * stream)443 AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* stream)
444 {
445     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
446     return audioStream->getFramesPerBurst();
447 }
448 
AAudioStream_getFramesPerDataCallback(AAudioStream * stream)449 AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream)
450 {
451     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
452     return audioStream->getFramesPerDataCallback();
453 }
454 
AAudioStream_getBufferCapacityInFrames(AAudioStream * stream)455 AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream)
456 {
457     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
458     return audioStream->getBufferCapacity();
459 }
460 
AAudioStream_getXRunCount(AAudioStream * stream)461 AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream)
462 {
463     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
464     return audioStream->getXRunCount();
465 }
466 
AAudioStream_getPerformanceMode(AAudioStream * stream)467 AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* stream)
468 {
469     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
470     return audioStream->getPerformanceMode();
471 }
472 
AAudioStream_getDeviceId(AAudioStream * stream)473 AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream)
474 {
475     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
476     return audioStream->getDeviceId();
477 }
478 
AAudioStream_getSharingMode(AAudioStream * stream)479 AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream)
480 {
481     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
482     return audioStream->getSharingMode();
483 }
484 
AAudioStream_getUsage(AAudioStream * stream)485 AAUDIO_API aaudio_usage_t AAudioStream_getUsage(AAudioStream* stream)
486 {
487     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
488     return audioStream->getUsage();
489 }
490 
AAudioStream_getContentType(AAudioStream * stream)491 AAUDIO_API aaudio_content_type_t AAudioStream_getContentType(AAudioStream* stream)
492 {
493     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
494     return audioStream->getContentType();
495 }
496 
AAudioStream_getInputPreset(AAudioStream * stream)497 AAUDIO_API aaudio_input_preset_t AAudioStream_getInputPreset(AAudioStream* stream)
498 {
499     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
500     return audioStream->getInputPreset();
501 }
502 
AAudioStream_getAllowedCapturePolicy(AAudioStream * stream)503 AAUDIO_API aaudio_allowed_capture_policy_t AAudioStream_getAllowedCapturePolicy(
504         AAudioStream* stream)
505 {
506     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
507     return audioStream->getAllowedCapturePolicy();
508 }
509 
AAudioStream_getSessionId(AAudioStream * stream)510 AAUDIO_API int32_t AAudioStream_getSessionId(AAudioStream* stream)
511 {
512     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
513     return audioStream->getSessionId();
514 }
515 
AAudioStream_getFramesWritten(AAudioStream * stream)516 AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream)
517 {
518     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
519     return audioStream->getFramesWritten();
520 }
521 
AAudioStream_getFramesRead(AAudioStream * stream)522 AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream)
523 {
524     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
525     return audioStream->getFramesRead();
526 }
527 
AAudioStream_getTimestamp(AAudioStream * stream,clockid_t clockid,int64_t * framePosition,int64_t * timeNanoseconds)528 AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* stream,
529                                       clockid_t clockid,
530                                       int64_t *framePosition,
531                                       int64_t *timeNanoseconds)
532 {
533     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
534     if (framePosition == nullptr) {
535         return AAUDIO_ERROR_NULL;
536     } else if (timeNanoseconds == nullptr) {
537         return AAUDIO_ERROR_NULL;
538     } else if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_BOOTTIME) {
539         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
540     }
541 
542     return audioStream->getTimestamp(clockid, framePosition, timeNanoseconds);
543 }
544 
AAudio_getMMapPolicy()545 AAUDIO_API aaudio_policy_t AAudio_getMMapPolicy() {
546     return s_MMapPolicy;
547 }
548 
AAudio_setMMapPolicy(aaudio_policy_t policy)549 AAUDIO_API aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy) {
550     aaudio_result_t result = AAUDIO_OK;
551     switch(policy) {
552         case AAUDIO_UNSPECIFIED:
553         case AAUDIO_POLICY_NEVER:
554         case AAUDIO_POLICY_AUTO:
555         case AAUDIO_POLICY_ALWAYS:
556             s_MMapPolicy = policy;
557             break;
558         default:
559             result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
560             break;
561     }
562     return result;
563 }
564 
AAudioStream_isMMapUsed(AAudioStream * stream)565 AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream)
566 {
567     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
568     return audioStream->isMMap();
569 }
570