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 <time.h>
22#include <pthread.h>
23
24#include <aaudio/AAudio.h>
25#include <aaudio/AAudioTesting.h>
26
27#include "AudioStreamBuilder.h"
28#include "AudioStream.h"
29#include "AudioClock.h"
30#include "client/AudioStreamInternal.h"
31#include "HandleTracker.h"
32
33using namespace aaudio;
34
35
36// Macros for common code that includes a return.
37// TODO Consider using do{}while(0) construct. I tried but it hung AndroidStudio
38#define CONVERT_BUILDER_HANDLE_OR_RETURN() \
39    convertAAudioBuilderToStreamBuilder(builder);
40
41#define COMMON_GET_FROM_BUILDER_OR_RETURN(resultPtr) \
42    CONVERT_BUILDER_HANDLE_OR_RETURN() \
43    if ((resultPtr) == nullptr) { \
44        return AAUDIO_ERROR_NULL; \
45    }
46
47#define AAUDIO_CASE_ENUM(name) case name: return #name
48
49AAUDIO_API const char * AAudio_convertResultToText(aaudio_result_t returnCode) {
50    switch (returnCode) {
51        AAUDIO_CASE_ENUM(AAUDIO_OK);
52        AAUDIO_CASE_ENUM(AAUDIO_ERROR_DISCONNECTED);
53        AAUDIO_CASE_ENUM(AAUDIO_ERROR_ILLEGAL_ARGUMENT);
54        // reserved
55        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INTERNAL);
56        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_STATE);
57        // reserved
58        // reserved
59        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_HANDLE);
60         // reserved
61        AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNIMPLEMENTED);
62        AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNAVAILABLE);
63        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_FREE_HANDLES);
64        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_MEMORY);
65        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NULL);
66        AAUDIO_CASE_ENUM(AAUDIO_ERROR_TIMEOUT);
67        AAUDIO_CASE_ENUM(AAUDIO_ERROR_WOULD_BLOCK);
68        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_FORMAT);
69        AAUDIO_CASE_ENUM(AAUDIO_ERROR_OUT_OF_RANGE);
70        AAUDIO_CASE_ENUM(AAUDIO_ERROR_NO_SERVICE);
71        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_RATE);
72    }
73    return "Unrecognized AAudio error.";
74}
75
76AAUDIO_API const char * AAudio_convertStreamStateToText(aaudio_stream_state_t state) {
77    switch (state) {
78        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNINITIALIZED);
79        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_UNKNOWN);
80        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_OPEN);
81        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTING);
82        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STARTED);
83        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSING);
84        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_PAUSED);
85        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHING);
86        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_FLUSHED);
87        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPING);
88        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_STOPPED);
89        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_DISCONNECTED);
90        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSING);
91        AAUDIO_CASE_ENUM(AAUDIO_STREAM_STATE_CLOSED);
92    }
93    return "Unrecognized AAudio state.";
94}
95
96#undef AAUDIO_CASE_ENUM
97
98
99/******************************************
100 * Static globals.
101 */
102static aaudio_policy_t s_MMapPolicy = AAUDIO_UNSPECIFIED;
103
104
105static AudioStream *convertAAudioStreamToAudioStream(AAudioStream* stream)
106{
107    return (AudioStream*) stream;
108}
109
110static AudioStreamBuilder *convertAAudioBuilderToStreamBuilder(AAudioStreamBuilder* builder)
111{
112    return (AudioStreamBuilder*) builder;
113}
114
115AAUDIO_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
125AAUDIO_API void AAudioStreamBuilder_setPerformanceMode(AAudioStreamBuilder* builder,
126                                                       aaudio_performance_mode_t mode)
127{
128    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
129    streamBuilder->setPerformanceMode(mode);
130}
131
132AAUDIO_API void AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder* builder,
133                                                int32_t deviceId)
134{
135    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
136    streamBuilder->setDeviceId(deviceId);
137}
138
139AAUDIO_API void AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder* builder,
140                                              int32_t sampleRate)
141{
142    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
143    streamBuilder->setSampleRate(sampleRate);
144}
145
146AAUDIO_API void AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder* builder,
147                                                       int32_t channelCount)
148{
149    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
150    streamBuilder->setSamplesPerFrame(channelCount);
151}
152
153AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder,
154                                                       int32_t samplesPerFrame)
155{
156    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
157    streamBuilder->setSamplesPerFrame(samplesPerFrame);
158}
159
160AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* builder,
161                                             aaudio_direction_t direction)
162{
163    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
164    streamBuilder->setDirection(direction);
165}
166
167AAUDIO_API void AAudioStreamBuilder_setFormat(AAudioStreamBuilder* builder,
168                                                   aaudio_format_t format)
169{
170    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
171    streamBuilder->setFormat(format);
172}
173
174AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* builder,
175                                                        aaudio_sharing_mode_t sharingMode)
176{
177    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
178    streamBuilder->setSharingMode(sharingMode);
179}
180
181AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder,
182                                                        int32_t frames)
183{
184    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
185    streamBuilder->setBufferCapacity(frames);
186}
187
188AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* builder,
189                                                    AAudioStream_dataCallback callback,
190                                                    void *userData)
191{
192    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
193    streamBuilder->setDataCallbackProc(callback);
194    streamBuilder->setDataCallbackUserData(userData);
195}
196
197AAUDIO_API void AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder* builder,
198                                                 AAudioStream_errorCallback callback,
199                                                 void *userData)
200{
201    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
202    streamBuilder->setErrorCallbackProc(callback);
203    streamBuilder->setErrorCallbackUserData(userData);
204}
205
206AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* builder,
207                                                int32_t frames)
208{
209    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
210    streamBuilder->setFramesPerDataCallback(frames);
211}
212
213AAUDIO_API aaudio_result_t  AAudioStreamBuilder_openStream(AAudioStreamBuilder* builder,
214                                                     AAudioStream** streamPtr)
215{
216    AudioStream *audioStream = nullptr;
217    // Please leave these logs because they are very helpful when debugging.
218    ALOGD("AAudioStreamBuilder_openStream() called ----------------------------------------");
219    AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(streamPtr);
220    aaudio_result_t result = streamBuilder->build(&audioStream);
221    ALOGD("AAudioStreamBuilder_openStream() returns %d = %s for (%p) ----------------",
222          result, AAudio_convertResultToText(result), audioStream);
223    if (result == AAUDIO_OK) {
224        *streamPtr = (AAudioStream*) audioStream;
225    } else {
226        *streamPtr = nullptr;
227    }
228    return result;
229}
230
231AAUDIO_API aaudio_result_t  AAudioStreamBuilder_delete(AAudioStreamBuilder* builder)
232{
233    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
234    if (streamBuilder != nullptr) {
235        delete streamBuilder;
236        return AAUDIO_OK;
237    }
238    return AAUDIO_ERROR_NULL;
239}
240
241AAUDIO_API aaudio_result_t  AAudioStream_close(AAudioStream* stream)
242{
243    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
244    ALOGD("AAudioStream_close(%p)", stream);
245    if (audioStream != nullptr) {
246        audioStream->close();
247        delete audioStream;
248        return AAUDIO_OK;
249    }
250    return AAUDIO_ERROR_NULL;
251}
252
253AAUDIO_API aaudio_result_t  AAudioStream_requestStart(AAudioStream* stream)
254{
255    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
256    ALOGD("AAudioStream_requestStart(%p)", stream);
257    return audioStream->requestStart();
258}
259
260AAUDIO_API aaudio_result_t  AAudioStream_requestPause(AAudioStream* stream)
261{
262    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
263    ALOGD("AAudioStream_requestPause(%p)", stream);
264    return audioStream->requestPause();
265}
266
267AAUDIO_API aaudio_result_t  AAudioStream_requestFlush(AAudioStream* stream)
268{
269    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
270    ALOGD("AAudioStream_requestFlush(%p)", stream);
271    return audioStream->requestFlush();
272}
273
274AAUDIO_API aaudio_result_t  AAudioStream_requestStop(AAudioStream* stream)
275{
276    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
277    ALOGD("AAudioStream_requestStop(%p)", stream);
278    return audioStream->requestStop();
279}
280
281AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream,
282                                            aaudio_stream_state_t inputState,
283                                            aaudio_stream_state_t *nextState,
284                                            int64_t timeoutNanoseconds)
285{
286
287    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
288    return audioStream->waitForStateChange(inputState, nextState, timeoutNanoseconds);
289}
290
291// ============================================================
292// Stream - non-blocking I/O
293// ============================================================
294
295AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* stream,
296                               void *buffer,
297                               int32_t numFrames,
298                               int64_t timeoutNanoseconds)
299{
300    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
301    if (buffer == nullptr) {
302        return AAUDIO_ERROR_NULL;
303    }
304    if (numFrames < 0) {
305        return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
306    } else if (numFrames == 0) {
307        return 0;
308    }
309
310    aaudio_result_t result = audioStream->read(buffer, numFrames, timeoutNanoseconds);
311
312    return result;
313}
314
315AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream,
316                               const void *buffer,
317                               int32_t numFrames,
318                               int64_t timeoutNanoseconds)
319{
320    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
321    if (buffer == nullptr) {
322        return AAUDIO_ERROR_NULL;
323    }
324
325    // Don't allow writes when playing with a callback.
326    if (audioStream->getDataCallbackProc() != nullptr && audioStream->isActive()) {
327        ALOGE("Cannot write to a callback stream when running.");
328        return AAUDIO_ERROR_INVALID_STATE;
329    }
330
331    if (numFrames < 0) {
332        return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
333    } else if (numFrames == 0) {
334        return 0;
335    }
336
337    aaudio_result_t result = audioStream->write(buffer, numFrames, timeoutNanoseconds);
338
339    return result;
340}
341
342// ============================================================
343// Stream - queries
344// ============================================================
345
346AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream)
347{
348    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
349    return audioStream->getSampleRate();
350}
351
352AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream)
353{
354    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
355    return audioStream->getSamplesPerFrame();
356}
357
358AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream)
359{
360    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
361    return audioStream->getSamplesPerFrame();
362}
363
364AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream)
365{
366    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
367    return audioStream->getState();
368}
369
370AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* stream)
371{
372    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
373    return audioStream->getFormat();
374}
375
376AAUDIO_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
383AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* stream)
384{
385    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
386    return audioStream->getBufferSize();
387}
388
389AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* stream)
390{
391    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
392    return audioStream->getDirection();
393}
394
395AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* stream)
396{
397    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
398    return audioStream->getFramesPerBurst();
399}
400
401AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream)
402{
403    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
404    return audioStream->getFramesPerDataCallback();
405}
406
407AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream)
408{
409    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
410    return audioStream->getBufferCapacity();
411}
412
413AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream)
414{
415    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
416    return audioStream->getXRunCount();
417}
418
419AAUDIO_API aaudio_performance_mode_t AAudioStream_getPerformanceMode(AAudioStream* stream)
420{
421    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
422    return audioStream->getPerformanceMode();
423}
424
425AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream)
426{
427    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
428    return audioStream->getDeviceId();
429}
430
431AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream)
432{
433    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
434    return audioStream->getSharingMode();
435}
436
437AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream)
438{
439    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
440    return audioStream->getFramesWritten();
441}
442
443AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream)
444{
445    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
446    return audioStream->getFramesRead();
447}
448
449AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* stream,
450                                      clockid_t clockid,
451                                      int64_t *framePosition,
452                                      int64_t *timeNanoseconds)
453{
454    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
455    if (framePosition == nullptr) {
456        return AAUDIO_ERROR_NULL;
457    } else if (timeNanoseconds == nullptr) {
458        return AAUDIO_ERROR_NULL;
459    } else if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_BOOTTIME) {
460        return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
461    }
462
463    return audioStream->getTimestamp(clockid, framePosition, timeNanoseconds);
464}
465
466AAUDIO_API aaudio_policy_t AAudio_getMMapPolicy() {
467    return s_MMapPolicy;
468}
469
470AAUDIO_API aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy) {
471    aaudio_result_t result = AAUDIO_OK;
472    switch(policy) {
473        case AAUDIO_UNSPECIFIED:
474        case AAUDIO_POLICY_NEVER:
475        case AAUDIO_POLICY_AUTO:
476        case AAUDIO_POLICY_ALWAYS:
477            s_MMapPolicy = policy;
478            break;
479        default:
480            result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
481            break;
482    }
483    return result;
484}
485
486AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream)
487{
488    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
489    return audioStream->isMMap();
490}
491