blob: 9007b1004f28a2143528cd4ce8bf7e62caf2c23c [file] [log] [blame]
Phil Burk5ed503c2017-02-01 09:38:15 -08001/*
2 * Copyright 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
Phil Burkc8f69a02017-05-11 15:53:06 -070021#include <cutils/properties.h>
Phil Burk5ed503c2017-02-01 09:38:15 -080022#include <stdint.h>
23#include <sys/types.h>
24#include <utils/Errors.h>
25
Phil Burka4eb0d82017-04-12 15:44:06 -070026#include "aaudio/AAudio.h"
dimitry2d2f17c2019-07-17 13:55:16 +020027#include "core/AudioGlobal.h"
Phil Burkd04aeea2017-05-23 13:56:41 -070028#include <aaudio/AAudioTesting.h>
Phil Burkbba09002017-11-29 13:39:44 -080029#include <math.h>
Phil Burkd4ccc622017-12-20 15:32:44 -080030#include <system/audio-base.h>
Phil Burk41f19d82018-02-13 14:59:10 -080031#include <assert.h>
Phil Burkd04aeea2017-05-23 13:56:41 -070032
33#include "utility/AAudioUtilities.h"
Phil Burk5ed503c2017-02-01 09:38:15 -080034
35using namespace android;
36
Phil Burk5ed503c2017-02-01 09:38:15 -080037status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result) {
38 // This covers the case for AAUDIO_OK and for positive results.
39 if (result >= 0) {
40 return result;
41 }
42 status_t status;
43 switch (result) {
44 case AAUDIO_ERROR_DISCONNECTED:
Eric Laurenta2f296e2017-06-21 18:51:47 -070045 case AAUDIO_ERROR_NO_SERVICE:
Phil Burk5ed503c2017-02-01 09:38:15 -080046 status = DEAD_OBJECT;
47 break;
Eric Laurenta2f296e2017-06-21 18:51:47 -070048 case AAUDIO_ERROR_INVALID_HANDLE:
49 status = BAD_TYPE;
50 break;
Phil Burk5ed503c2017-02-01 09:38:15 -080051 case AAUDIO_ERROR_INVALID_STATE:
52 status = INVALID_OPERATION;
53 break;
Phil Burk71f35bb2017-04-13 16:05:07 -070054 case AAUDIO_ERROR_INVALID_RATE:
55 case AAUDIO_ERROR_INVALID_FORMAT:
Phil Burk5ed503c2017-02-01 09:38:15 -080056 case AAUDIO_ERROR_ILLEGAL_ARGUMENT:
Phil Burk5204d312017-05-04 17:16:13 -070057 case AAUDIO_ERROR_OUT_OF_RANGE:
Phil Burk5ed503c2017-02-01 09:38:15 -080058 status = BAD_VALUE;
59 break;
60 case AAUDIO_ERROR_WOULD_BLOCK:
61 status = WOULD_BLOCK;
62 break;
Phil Burk5204d312017-05-04 17:16:13 -070063 case AAUDIO_ERROR_NULL:
64 status = UNEXPECTED_NULL;
65 break;
Phil Burk940083c2017-07-17 17:00:02 -070066 case AAUDIO_ERROR_UNAVAILABLE:
67 status = NOT_ENOUGH_DATA;
68 break;
69
Phil Burk5204d312017-05-04 17:16:13 -070070 // TODO translate these result codes
Phil Burk5204d312017-05-04 17:16:13 -070071 case AAUDIO_ERROR_INTERNAL:
Phil Burk5204d312017-05-04 17:16:13 -070072 case AAUDIO_ERROR_UNIMPLEMENTED:
Phil Burk5204d312017-05-04 17:16:13 -070073 case AAUDIO_ERROR_NO_FREE_HANDLES:
74 case AAUDIO_ERROR_NO_MEMORY:
75 case AAUDIO_ERROR_TIMEOUT:
Phil Burk5ed503c2017-02-01 09:38:15 -080076 default:
77 status = UNKNOWN_ERROR;
78 break;
79 }
80 return status;
81}
82
83aaudio_result_t AAudioConvert_androidToAAudioResult(status_t status) {
84 // This covers the case for OK and for positive result.
85 if (status >= 0) {
86 return status;
87 }
88 aaudio_result_t result;
89 switch (status) {
90 case BAD_TYPE:
91 result = AAUDIO_ERROR_INVALID_HANDLE;
92 break;
93 case DEAD_OBJECT:
Phil Burk71f35bb2017-04-13 16:05:07 -070094 result = AAUDIO_ERROR_NO_SERVICE;
Phil Burk5ed503c2017-02-01 09:38:15 -080095 break;
96 case INVALID_OPERATION:
97 result = AAUDIO_ERROR_INVALID_STATE;
98 break;
Eric Laurenta2f296e2017-06-21 18:51:47 -070099 case UNEXPECTED_NULL:
100 result = AAUDIO_ERROR_NULL;
101 break;
102 case BAD_VALUE:
103 result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
104 break;
Phil Burk5ed503c2017-02-01 09:38:15 -0800105 case WOULD_BLOCK:
106 result = AAUDIO_ERROR_WOULD_BLOCK;
107 break;
Phil Burk940083c2017-07-17 17:00:02 -0700108 case NOT_ENOUGH_DATA:
109 result = AAUDIO_ERROR_UNAVAILABLE;
110 break;
Phil Burk5ed503c2017-02-01 09:38:15 -0800111 default:
112 result = AAUDIO_ERROR_INTERNAL;
113 break;
114 }
115 return result;
116}
117
Phil Burk4e1af9f2018-01-03 15:54:35 -0800118audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId) {
Phil Burk67fdd892018-01-23 15:28:55 -0800119 // If not a regular sessionId then convert to a safe value of AUDIO_SESSION_ALLOCATE.
120 return (sessionId == AAUDIO_SESSION_ID_ALLOCATE || sessionId == AAUDIO_SESSION_ID_NONE)
Phil Burk4e1af9f2018-01-03 15:54:35 -0800121 ? AUDIO_SESSION_ALLOCATE
122 : (audio_session_t) sessionId;
123}
124
Phil Burk9dca9822017-05-26 14:27:43 -0700125audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudioFormat) {
Phil Burk5ed503c2017-02-01 09:38:15 -0800126 audio_format_t androidFormat;
127 switch (aaudioFormat) {
Phil Burk0127c1b2018-03-29 13:48:06 -0700128 case AAUDIO_FORMAT_UNSPECIFIED:
129 androidFormat = AUDIO_FORMAT_DEFAULT;
130 break;
Phil Burk5ed503c2017-02-01 09:38:15 -0800131 case AAUDIO_FORMAT_PCM_I16:
132 androidFormat = AUDIO_FORMAT_PCM_16_BIT;
133 break;
134 case AAUDIO_FORMAT_PCM_FLOAT:
135 androidFormat = AUDIO_FORMAT_PCM_FLOAT;
136 break;
Phil Burk5ed503c2017-02-01 09:38:15 -0800137 default:
Phil Burk0127c1b2018-03-29 13:48:06 -0700138 androidFormat = AUDIO_FORMAT_INVALID;
139 ALOGE("%s() 0x%08X unrecognized", __func__, aaudioFormat);
Phil Burk5ed503c2017-02-01 09:38:15 -0800140 break;
141 }
142 return androidFormat;
143}
144
Phil Burk9dca9822017-05-26 14:27:43 -0700145aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat) {
Phil Burk0127c1b2018-03-29 13:48:06 -0700146 aaudio_format_t aaudioFormat;
Phil Burk5ed503c2017-02-01 09:38:15 -0800147 switch (androidFormat) {
Phil Burk0127c1b2018-03-29 13:48:06 -0700148 case AUDIO_FORMAT_DEFAULT:
149 aaudioFormat = AAUDIO_FORMAT_UNSPECIFIED;
150 break;
Phil Burk5ed503c2017-02-01 09:38:15 -0800151 case AUDIO_FORMAT_PCM_16_BIT:
152 aaudioFormat = AAUDIO_FORMAT_PCM_I16;
153 break;
154 case AUDIO_FORMAT_PCM_FLOAT:
155 aaudioFormat = AAUDIO_FORMAT_PCM_FLOAT;
156 break;
Phil Burk5ed503c2017-02-01 09:38:15 -0800157 default:
158 aaudioFormat = AAUDIO_FORMAT_INVALID;
Phil Burk0127c1b2018-03-29 13:48:06 -0700159 ALOGE("%s() 0x%08X unrecognized", __func__, androidFormat);
Phil Burk5ed503c2017-02-01 09:38:15 -0800160 break;
161 }
162 return aaudioFormat;
163}
164
Phil Burkd4ccc622017-12-20 15:32:44 -0800165// Make a message string from the condition.
166#define STATIC_ASSERT(condition) static_assert(condition, #condition)
167
168audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage) {
169 // The public aaudio_content_type_t constants are supposed to have the same
170 // values as the internal audio_content_type_t values.
171 STATIC_ASSERT(AAUDIO_USAGE_MEDIA == AUDIO_USAGE_MEDIA);
172 STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION == AUDIO_USAGE_VOICE_COMMUNICATION);
173 STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING
174 == AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING);
175 STATIC_ASSERT(AAUDIO_USAGE_ALARM == AUDIO_USAGE_ALARM);
176 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION == AUDIO_USAGE_NOTIFICATION);
177 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_RINGTONE
178 == AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE);
179 STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_EVENT == AUDIO_USAGE_NOTIFICATION_EVENT);
180 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY);
181 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE
182 == AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
183 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_SONIFICATION == AUDIO_USAGE_ASSISTANCE_SONIFICATION);
184 STATIC_ASSERT(AAUDIO_USAGE_GAME == AUDIO_USAGE_GAME);
185 STATIC_ASSERT(AAUDIO_USAGE_ASSISTANT == AUDIO_USAGE_ASSISTANT);
Hayden Gomes3e8bbb92020-01-10 13:37:05 -0800186 STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_EMERGENCY == AUDIO_USAGE_EMERGENCY);
187 STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_SAFETY == AUDIO_USAGE_SAFETY);
188 STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS == AUDIO_USAGE_VEHICLE_STATUS);
189 STATIC_ASSERT(AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT == AUDIO_USAGE_ANNOUNCEMENT);
Phil Burkd4ccc622017-12-20 15:32:44 -0800190 if (usage == AAUDIO_UNSPECIFIED) {
191 usage = AAUDIO_USAGE_MEDIA;
192 }
193 return (audio_usage_t) usage; // same value
194}
195
196audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType) {
197 // The public aaudio_content_type_t constants are supposed to have the same
198 // values as the internal audio_content_type_t values.
199 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MUSIC == AUDIO_CONTENT_TYPE_MUSIC);
200 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SPEECH == AUDIO_CONTENT_TYPE_SPEECH);
201 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SONIFICATION == AUDIO_CONTENT_TYPE_SONIFICATION);
202 STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MOVIE == AUDIO_CONTENT_TYPE_MOVIE);
203 if (contentType == AAUDIO_UNSPECIFIED) {
204 contentType = AAUDIO_CONTENT_TYPE_MUSIC;
205 }
206 return (audio_content_type_t) contentType; // same value
207}
208
209audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset) {
210 // The public aaudio_input_preset_t constants are supposed to have the same
211 // values as the internal audio_source_t values.
212 STATIC_ASSERT(AAUDIO_UNSPECIFIED == AUDIO_SOURCE_DEFAULT);
213 STATIC_ASSERT(AAUDIO_INPUT_PRESET_GENERIC == AUDIO_SOURCE_MIC);
214 STATIC_ASSERT(AAUDIO_INPUT_PRESET_CAMCORDER == AUDIO_SOURCE_CAMCORDER);
215 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_RECOGNITION == AUDIO_SOURCE_VOICE_RECOGNITION);
216 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION == AUDIO_SOURCE_VOICE_COMMUNICATION);
217 STATIC_ASSERT(AAUDIO_INPUT_PRESET_UNPROCESSED == AUDIO_SOURCE_UNPROCESSED);
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800218 STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE == AUDIO_SOURCE_VOICE_PERFORMANCE);
Phil Burkd4ccc622017-12-20 15:32:44 -0800219 if (preset == AAUDIO_UNSPECIFIED) {
Phil Burkeaef9b92018-01-18 09:09:42 -0800220 preset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
Phil Burkd4ccc622017-12-20 15:32:44 -0800221 }
222 return (audio_source_t) preset; // same value
223}
224
Kevin Rocard68646ba2019-03-20 13:26:49 -0700225audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
226 aaudio_allowed_capture_policy_t policy) {
227 switch (policy) {
228 case AAUDIO_UNSPECIFIED:
229 case AAUDIO_ALLOW_CAPTURE_BY_ALL:
230 return AUDIO_FLAG_NONE;
231 case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
232 return AUDIO_FLAG_NO_MEDIA_PROJECTION;
233 case AAUDIO_ALLOW_CAPTURE_BY_NONE:
234 return AUDIO_FLAG_NO_MEDIA_PROJECTION | AUDIO_FLAG_NO_SYSTEM_CAPTURE;
235 default:
236 ALOGE("%s() 0x%08X unrecognized", __func__, policy);
237 return AUDIO_FLAG_NONE; //
238 }
239}
240
Eric Laurentd17c8502019-10-24 15:58:35 -0700241audio_flags_mask_t AAudioConvert_privacySensitiveToAudioFlagsMask(
242 bool privacySensitive) {
243 return privacySensitive ? AUDIO_FLAG_CAPTURE_PRIVATE : AUDIO_FLAG_NONE;
244}
245
Phil Burk3316d5e2017-02-15 11:23:01 -0800246int32_t AAudioConvert_framesToBytes(int32_t numFrames,
Phil Burk7f680132018-03-12 14:48:06 -0700247 int32_t bytesPerFrame,
248 int32_t *sizeInBytes) {
249 *sizeInBytes = 0;
250
251 if (numFrames < 0 || bytesPerFrame < 0) {
252 ALOGE("negative size, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame);
253 return AAUDIO_ERROR_OUT_OF_RANGE;
254 }
255
256 // Prevent numeric overflow.
257 if (numFrames > (INT32_MAX / bytesPerFrame)) {
Yi Kong0f414de2017-12-15 13:48:50 -0800258 ALOGE("size overflow, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame);
Phil Burk5ed503c2017-02-01 09:38:15 -0800259 return AAUDIO_ERROR_OUT_OF_RANGE;
260 }
Phil Burk7f680132018-03-12 14:48:06 -0700261
Phil Burk5ed503c2017-02-01 09:38:15 -0800262 *sizeInBytes = numFrames * bytesPerFrame;
263 return AAUDIO_OK;
264}
Phil Burkc8f69a02017-05-11 15:53:06 -0700265
266static int32_t AAudioProperty_getMMapProperty(const char *propName,
267 int32_t defaultValue,
268 const char * caller) {
Phil Burk87c9f642017-05-17 07:22:39 -0700269 int32_t prop = property_get_int32(propName, defaultValue);
Phil Burkc8f69a02017-05-11 15:53:06 -0700270 switch (prop) {
Phil Burkd04aeea2017-05-23 13:56:41 -0700271 case AAUDIO_UNSPECIFIED:
272 case AAUDIO_POLICY_NEVER:
273 case AAUDIO_POLICY_ALWAYS:
274 case AAUDIO_POLICY_AUTO:
Phil Burkc8f69a02017-05-11 15:53:06 -0700275 break;
276 default:
277 ALOGE("%s: invalid = %d", caller, prop);
278 prop = defaultValue;
279 break;
280 }
281 return prop;
282}
283
Phil Burkd04aeea2017-05-23 13:56:41 -0700284int32_t AAudioProperty_getMMapPolicy() {
285 return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_POLICY,
286 AAUDIO_UNSPECIFIED, __func__);
Phil Burkc8f69a02017-05-11 15:53:06 -0700287}
288
Phil Burkd04aeea2017-05-23 13:56:41 -0700289int32_t AAudioProperty_getMMapExclusivePolicy() {
290 return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY,
291 AAUDIO_UNSPECIFIED, __func__);
Phil Burkc8f69a02017-05-11 15:53:06 -0700292}
293
294int32_t AAudioProperty_getMixerBursts() {
Phil Burk87c9f642017-05-17 07:22:39 -0700295 const int32_t defaultBursts = 2; // arbitrary, use 2 for double buffered
Phil Burkc8f69a02017-05-11 15:53:06 -0700296 const int32_t maxBursts = 1024; // arbitrary
Phil Burk87c9f642017-05-17 07:22:39 -0700297 int32_t prop = property_get_int32(AAUDIO_PROP_MIXER_BURSTS, defaultBursts);
Phil Burkc8f69a02017-05-11 15:53:06 -0700298 if (prop < 1 || prop > maxBursts) {
299 ALOGE("AAudioProperty_getMixerBursts: invalid = %d", prop);
300 prop = defaultBursts;
301 }
302 return prop;
303}
304
Phil Burkfd34a932017-07-19 07:03:52 -0700305int32_t AAudioProperty_getWakeupDelayMicros() {
306 const int32_t minMicros = 0; // arbitrary
307 const int32_t defaultMicros = 200; // arbitrary, based on some observed jitter
308 const int32_t maxMicros = 5000; // arbitrary, probably don't want more than 500
309 int32_t prop = property_get_int32(AAUDIO_PROP_WAKEUP_DELAY_USEC, defaultMicros);
310 if (prop < minMicros) {
311 ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, minMicros);
312 prop = minMicros;
313 } else if (prop > maxMicros) {
314 ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, maxMicros);
315 prop = maxMicros;
316 }
317 return prop;
318}
319
320int32_t AAudioProperty_getMinimumSleepMicros() {
321 const int32_t minMicros = 20; // arbitrary
322 const int32_t defaultMicros = 200; // arbitrary
323 const int32_t maxMicros = 2000; // arbitrary
324 int32_t prop = property_get_int32(AAUDIO_PROP_MINIMUM_SLEEP_USEC, defaultMicros);
325 if (prop < minMicros) {
326 ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, minMicros);
327 prop = minMicros;
328 } else if (prop > maxMicros) {
329 ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, maxMicros);
330 prop = maxMicros;
331 }
332 return prop;
333}
334
Phil Burkc8f69a02017-05-11 15:53:06 -0700335int32_t AAudioProperty_getHardwareBurstMinMicros() {
336 const int32_t defaultMicros = 1000; // arbitrary
337 const int32_t maxMicros = 1000 * 1000; // arbitrary
338 int32_t prop = property_get_int32(AAUDIO_PROP_HW_BURST_MIN_USEC, defaultMicros);
339 if (prop < 1 || prop > maxMicros) {
Phil Burkfd34a932017-07-19 07:03:52 -0700340 ALOGE("AAudioProperty_getHardwareBurstMinMicros: invalid = %d, use %d",
341 prop, defaultMicros);
Phil Burkc8f69a02017-05-11 15:53:06 -0700342 prop = defaultMicros;
343 }
344 return prop;
345}
Phil Burk5cc83c32017-11-28 15:43:18 -0800346
Phil Burkb31b66f2019-09-30 09:33:41 -0700347static int32_t AAudioProperty_getMMapOffsetMicros(const char *functionName,
348 const char *propertyName) {
349 const int32_t minMicros = -20000; // arbitrary
350 const int32_t defaultMicros = 0; // arbitrary
351 const int32_t maxMicros = 20000; // arbitrary
352 int32_t prop = property_get_int32(propertyName, defaultMicros);
353 if (prop < minMicros) {
354 ALOGW("%s: clipped %d to %d", functionName, prop, minMicros);
355 prop = minMicros;
356 } else if (prop > maxMicros) {
357 ALOGW("%s: clipped %d to %d", functionName, prop, minMicros);
358 prop = maxMicros;
359 }
360 return prop;
361}
362
363int32_t AAudioProperty_getInputMMapOffsetMicros() {
364 return AAudioProperty_getMMapOffsetMicros(__func__, AAUDIO_PROP_INPUT_MMAP_OFFSET_USEC);
365}
366
367int32_t AAudioProperty_getOutputMMapOffsetMicros() {
368 return AAudioProperty_getMMapOffsetMicros(__func__, AAUDIO_PROP_OUTPUT_MMAP_OFFSET_USEC);
369}
370
Phil Burkef34be52019-09-26 13:45:25 -0700371int32_t AAudioProperty_getLogMask() {
372 return property_get_int32(AAUDIO_PROP_LOG_MASK, 0);
373}
374
Phil Burk5cc83c32017-11-28 15:43:18 -0800375aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state) {
376 aaudio_result_t result = AAUDIO_OK;
377 switch (state) {
378// Proceed with flushing.
379 case AAUDIO_STREAM_STATE_OPEN:
380 case AAUDIO_STREAM_STATE_PAUSED:
381 case AAUDIO_STREAM_STATE_STOPPED:
382 case AAUDIO_STREAM_STATE_FLUSHED:
383 break;
384
385// Transition from one inactive state to another.
386 case AAUDIO_STREAM_STATE_STARTING:
387 case AAUDIO_STREAM_STATE_STARTED:
388 case AAUDIO_STREAM_STATE_STOPPING:
389 case AAUDIO_STREAM_STATE_PAUSING:
390 case AAUDIO_STREAM_STATE_FLUSHING:
391 case AAUDIO_STREAM_STATE_CLOSING:
392 case AAUDIO_STREAM_STATE_CLOSED:
393 case AAUDIO_STREAM_STATE_DISCONNECTED:
394 default:
395 ALOGE("can only flush stream when PAUSED, OPEN or STOPPED, state = %s",
dimitry2d2f17c2019-07-17 13:55:16 +0200396 aaudio::AudioGlobal_convertStreamStateToText(state));
Phil Burk5cc83c32017-11-28 15:43:18 -0800397 result = AAUDIO_ERROR_INVALID_STATE;
398 break;
399 }
400 return result;
401}