AAudioAudio.cpp revision 20523edbf2f597c53b90e76694331c807e559515
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        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INCOMPATIBLE);
54        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INTERNAL);
55        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_STATE);
56        AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNEXPECTED_STATE);
57        AAUDIO_CASE_ENUM(AAUDIO_ERROR_UNEXPECTED_VALUE);
58        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_HANDLE);
59        AAUDIO_CASE_ENUM(AAUDIO_ERROR_INVALID_QUERY);
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 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_setDeviceId(AAudioStreamBuilder* builder,
118                                                     int32_t deviceId)
119{
120    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
121    streamBuilder->setDeviceId(deviceId);
122}
123
124AAUDIO_API void AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder* builder,
125                                              int32_t sampleRate)
126{
127    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
128    streamBuilder->setSampleRate(sampleRate);
129}
130
131AAUDIO_API void AAudioStreamBuilder_setChannelCount(AAudioStreamBuilder* builder,
132                                                       int32_t channelCount)
133{
134    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
135    streamBuilder->setSamplesPerFrame(channelCount);
136}
137
138AAUDIO_API void AAudioStreamBuilder_setSamplesPerFrame(AAudioStreamBuilder* builder,
139                                                       int32_t samplesPerFrame)
140{
141    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
142    streamBuilder->setSamplesPerFrame(samplesPerFrame);
143}
144
145AAUDIO_API void AAudioStreamBuilder_setDirection(AAudioStreamBuilder* builder,
146                                             aaudio_direction_t direction)
147{
148    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
149    streamBuilder->setDirection(direction);
150}
151
152AAUDIO_API void AAudioStreamBuilder_setFormat(AAudioStreamBuilder* builder,
153                                                   aaudio_audio_format_t format)
154{
155    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
156    streamBuilder->setFormat(format);
157}
158
159AAUDIO_API void AAudioStreamBuilder_setSharingMode(AAudioStreamBuilder* builder,
160                                                        aaudio_sharing_mode_t sharingMode)
161{
162    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
163    streamBuilder->setSharingMode(sharingMode);
164}
165
166AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder,
167                                                        int32_t frames)
168{
169    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
170    streamBuilder->setBufferCapacity(frames);
171}
172
173AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* builder,
174                                                    AAudioStream_dataCallback callback,
175                                                    void *userData)
176{
177    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
178    streamBuilder->setDataCallbackProc(callback);
179    streamBuilder->setDataCallbackUserData(userData);
180}
181
182AAUDIO_API void AAudioStreamBuilder_setErrorCallback(AAudioStreamBuilder* builder,
183                                                 AAudioStream_errorCallback callback,
184                                                 void *userData)
185{
186    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
187    streamBuilder->setErrorCallbackProc(callback);
188    streamBuilder->setErrorCallbackUserData(userData);
189}
190
191AAUDIO_API void AAudioStreamBuilder_setFramesPerDataCallback(AAudioStreamBuilder* builder,
192                                                int32_t frames)
193{
194    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
195    streamBuilder->setFramesPerDataCallback(frames);
196}
197
198// TODO merge AAudioInternal_openStream into AAudioStreamBuilder_openStream
199static aaudio_result_t  AAudioInternal_openStream(AudioStreamBuilder *streamBuilder,
200                                              AAudioStream** streamPtr)
201{
202    AudioStream *audioStream = nullptr;
203    aaudio_result_t result = streamBuilder->build(&audioStream);
204    if (result != AAUDIO_OK) {
205        return result;
206    } else {
207        *streamPtr = (AAudioStream*) audioStream;
208        return AAUDIO_OK;
209    }
210}
211
212AAUDIO_API aaudio_result_t  AAudioStreamBuilder_openStream(AAudioStreamBuilder* builder,
213                                                     AAudioStream** streamPtr)
214{
215    ALOGD("AAudioStreamBuilder_openStream() ----------------------------------------------");
216    AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(streamPtr);
217    return AAudioInternal_openStream(streamBuilder, streamPtr);
218}
219
220AAUDIO_API aaudio_result_t  AAudioStreamBuilder_delete(AAudioStreamBuilder* builder)
221{
222    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
223    if (streamBuilder != nullptr) {
224        delete streamBuilder;
225        return AAUDIO_OK;
226    }
227    return AAUDIO_ERROR_INVALID_HANDLE;
228}
229
230AAUDIO_API aaudio_result_t  AAudioStream_close(AAudioStream* stream)
231{
232    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
233    ALOGD("AAudioStream_close(%p)", stream);
234    if (audioStream != nullptr) {
235        audioStream->close();
236        delete audioStream;
237        ALOGD("AAudioStream_close() ----------------------------------------------");
238        return AAUDIO_OK;
239    }
240    return AAUDIO_ERROR_INVALID_HANDLE;
241}
242
243AAUDIO_API aaudio_result_t  AAudioStream_requestStart(AAudioStream* stream)
244{
245    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
246    ALOGD("AAudioStream_requestStart(%p)", stream);
247    return audioStream->requestStart();
248}
249
250AAUDIO_API aaudio_result_t  AAudioStream_requestPause(AAudioStream* stream)
251{
252    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
253    ALOGD("AAudioStream_requestPause(%p)", stream);
254    return audioStream->requestPause();
255}
256
257AAUDIO_API aaudio_result_t  AAudioStream_requestFlush(AAudioStream* stream)
258{
259    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
260    ALOGD("AAudioStream_requestFlush(%p)", stream);
261    return audioStream->requestFlush();
262}
263
264AAUDIO_API aaudio_result_t  AAudioStream_requestStop(AAudioStream* stream)
265{
266    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
267    ALOGD("AAudioStream_requestStop(%p)", stream);
268    return audioStream->requestStop();
269}
270
271AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream,
272                                            aaudio_stream_state_t inputState,
273                                            aaudio_stream_state_t *nextState,
274                                            int64_t timeoutNanoseconds)
275{
276
277    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
278    return audioStream->waitForStateChange(inputState, nextState, timeoutNanoseconds);
279}
280
281// ============================================================
282// Stream - non-blocking I/O
283// ============================================================
284
285AAUDIO_API aaudio_result_t AAudioStream_read(AAudioStream* stream,
286                               void *buffer,
287                               int32_t numFrames,
288                               int64_t timeoutNanoseconds)
289{
290    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
291    if (buffer == nullptr) {
292        return AAUDIO_ERROR_NULL;
293    }
294    if (numFrames < 0) {
295        return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
296    } else if (numFrames == 0) {
297        return 0;
298    }
299
300    aaudio_result_t result = audioStream->read(buffer, numFrames, timeoutNanoseconds);
301    // ALOGD("AAudioStream_read(): read returns %d", result);
302
303    return result;
304}
305
306AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream,
307                               const void *buffer,
308                               int32_t numFrames,
309                               int64_t timeoutNanoseconds)
310{
311    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
312    if (buffer == nullptr) {
313        return AAUDIO_ERROR_NULL;
314    }
315
316    // Don't allow writes when playing with a callback.
317    if (audioStream->getDataCallbackProc() != nullptr && audioStream->isPlaying()) {
318        ALOGE("Cannot write to a callback stream when running.");
319        return AAUDIO_ERROR_INVALID_STATE;
320    }
321
322    if (numFrames < 0) {
323        return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
324    } else if (numFrames == 0) {
325        return 0;
326    }
327
328    aaudio_result_t result = audioStream->write(buffer, numFrames, timeoutNanoseconds);
329    // ALOGD("AAudioStream_write(): write returns %d", result);
330
331    return result;
332}
333
334// ============================================================
335// Stream - queries
336// ============================================================
337
338AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream)
339{
340    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
341    return audioStream->getSampleRate();
342}
343
344AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream)
345{
346    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
347    return audioStream->getSamplesPerFrame();
348}
349
350AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream)
351{
352    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
353    return audioStream->getSamplesPerFrame();
354}
355
356AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream)
357{
358    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
359    return audioStream->getState();
360}
361
362AAUDIO_API aaudio_audio_format_t AAudioStream_getFormat(AAudioStream* stream)
363{
364    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
365    return audioStream->getFormat();
366}
367
368AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* stream,
369                                                int32_t requestedFrames)
370{
371    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
372    return audioStream->setBufferSize(requestedFrames);
373}
374
375AAUDIO_API int32_t AAudioStream_getBufferSizeInFrames(AAudioStream* stream)
376{
377    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
378    return audioStream->getBufferSize();
379}
380
381AAUDIO_API aaudio_direction_t AAudioStream_getDirection(AAudioStream* stream)
382{
383    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
384    return audioStream->getDirection();
385}
386
387AAUDIO_API int32_t AAudioStream_getFramesPerBurst(AAudioStream* stream)
388{
389    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
390    return audioStream->getFramesPerBurst();
391}
392
393AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream)
394{
395    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
396    return audioStream->getFramesPerDataCallback();
397}
398
399AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream)
400{
401    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
402    return audioStream->getBufferCapacity();
403}
404
405AAUDIO_API int32_t AAudioStream_getXRunCount(AAudioStream* stream)
406{
407    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
408    return audioStream->getXRunCount();
409}
410
411AAUDIO_API int32_t AAudioStream_getDeviceId(AAudioStream* stream)
412{
413    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
414    return audioStream->getDeviceId();
415}
416
417AAUDIO_API aaudio_sharing_mode_t AAudioStream_getSharingMode(AAudioStream* stream)
418{
419    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
420    return audioStream->getSharingMode();
421}
422
423AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream)
424{
425    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
426    return audioStream->getFramesWritten();
427}
428
429AAUDIO_API int64_t AAudioStream_getFramesRead(AAudioStream* stream)
430{
431    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
432    return audioStream->getFramesRead();
433}
434
435AAUDIO_API aaudio_result_t AAudioStream_getTimestamp(AAudioStream* stream,
436                                      clockid_t clockid,
437                                      int64_t *framePosition,
438                                      int64_t *timeNanoseconds)
439{
440    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
441    if (framePosition == nullptr) {
442        return AAUDIO_ERROR_NULL;
443    } else if (timeNanoseconds == nullptr) {
444        return AAUDIO_ERROR_NULL;
445    } else if (clockid != CLOCK_MONOTONIC && clockid != CLOCK_BOOTTIME) {
446        return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
447    }
448
449    return audioStream->getTimestamp(clockid, framePosition, timeNanoseconds);
450}
451