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