• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
21 #include <cutils/properties.h>
22 #include <stdint.h>
23 #include <sys/types.h>
24 #include <utils/Errors.h>
25 
26 #include "aaudio/AAudio.h"
27 #include <aaudio/AAudioTesting.h>
28 #include <math.h>
29 #include <system/audio-base.h>
30 #include <assert.h>
31 
32 #include "utility/AAudioUtilities.h"
33 
34 using namespace android;
35 
AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result)36 status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result) {
37     // This covers the case for AAUDIO_OK and for positive results.
38     if (result >= 0) {
39         return result;
40     }
41     status_t status;
42     switch (result) {
43     case AAUDIO_ERROR_DISCONNECTED:
44     case AAUDIO_ERROR_NO_SERVICE:
45         status = DEAD_OBJECT;
46         break;
47     case AAUDIO_ERROR_INVALID_HANDLE:
48         status = BAD_TYPE;
49         break;
50     case AAUDIO_ERROR_INVALID_STATE:
51         status = INVALID_OPERATION;
52         break;
53     case AAUDIO_ERROR_INVALID_RATE:
54     case AAUDIO_ERROR_INVALID_FORMAT:
55     case AAUDIO_ERROR_ILLEGAL_ARGUMENT:
56     case AAUDIO_ERROR_OUT_OF_RANGE:
57         status = BAD_VALUE;
58         break;
59     case AAUDIO_ERROR_WOULD_BLOCK:
60         status = WOULD_BLOCK;
61         break;
62     case AAUDIO_ERROR_NULL:
63         status = UNEXPECTED_NULL;
64         break;
65     case AAUDIO_ERROR_UNAVAILABLE:
66         status = NOT_ENOUGH_DATA;
67         break;
68 
69     // TODO translate these result codes
70     case AAUDIO_ERROR_INTERNAL:
71     case AAUDIO_ERROR_UNIMPLEMENTED:
72     case AAUDIO_ERROR_NO_FREE_HANDLES:
73     case AAUDIO_ERROR_NO_MEMORY:
74     case AAUDIO_ERROR_TIMEOUT:
75     default:
76         status = UNKNOWN_ERROR;
77         break;
78     }
79     return status;
80 }
81 
AAudioConvert_androidToAAudioResult(status_t status)82 aaudio_result_t AAudioConvert_androidToAAudioResult(status_t status) {
83     // This covers the case for OK and for positive result.
84     if (status >= 0) {
85         return status;
86     }
87     aaudio_result_t result;
88     switch (status) {
89     case BAD_TYPE:
90         result = AAUDIO_ERROR_INVALID_HANDLE;
91         break;
92     case DEAD_OBJECT:
93         result = AAUDIO_ERROR_NO_SERVICE;
94         break;
95     case INVALID_OPERATION:
96         result = AAUDIO_ERROR_INVALID_STATE;
97         break;
98     case UNEXPECTED_NULL:
99         result = AAUDIO_ERROR_NULL;
100         break;
101     case BAD_VALUE:
102         result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
103         break;
104     case WOULD_BLOCK:
105         result = AAUDIO_ERROR_WOULD_BLOCK;
106         break;
107     case NOT_ENOUGH_DATA:
108         result = AAUDIO_ERROR_UNAVAILABLE;
109         break;
110     default:
111         result = AAUDIO_ERROR_INTERNAL;
112         break;
113     }
114     return result;
115 }
116 
AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId)117 audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId) {
118     // If not a regular sessionId then convert to a safe value of AUDIO_SESSION_ALLOCATE.
119     return (sessionId == AAUDIO_SESSION_ID_ALLOCATE || sessionId == AAUDIO_SESSION_ID_NONE)
120            ? AUDIO_SESSION_ALLOCATE
121            : (audio_session_t) sessionId;
122 }
123 
AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudioFormat)124 audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudioFormat) {
125     audio_format_t androidFormat;
126     switch (aaudioFormat) {
127     case AAUDIO_FORMAT_UNSPECIFIED:
128         androidFormat = AUDIO_FORMAT_DEFAULT;
129         break;
130     case AAUDIO_FORMAT_PCM_I16:
131         androidFormat = AUDIO_FORMAT_PCM_16_BIT;
132         break;
133     case AAUDIO_FORMAT_PCM_FLOAT:
134         androidFormat = AUDIO_FORMAT_PCM_FLOAT;
135         break;
136     default:
137         androidFormat = AUDIO_FORMAT_INVALID;
138         ALOGE("%s() 0x%08X unrecognized", __func__, aaudioFormat);
139         break;
140     }
141     return androidFormat;
142 }
143 
AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat)144 aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat) {
145     aaudio_format_t aaudioFormat;
146     switch (androidFormat) {
147     case AUDIO_FORMAT_DEFAULT:
148         aaudioFormat = AAUDIO_FORMAT_UNSPECIFIED;
149         break;
150     case AUDIO_FORMAT_PCM_16_BIT:
151         aaudioFormat = AAUDIO_FORMAT_PCM_I16;
152         break;
153     case AUDIO_FORMAT_PCM_FLOAT:
154         aaudioFormat = AAUDIO_FORMAT_PCM_FLOAT;
155         break;
156     default:
157         aaudioFormat = AAUDIO_FORMAT_INVALID;
158         ALOGE("%s() 0x%08X unrecognized", __func__, androidFormat);
159         break;
160     }
161     return aaudioFormat;
162 }
163 
164 // Make a message string from the condition.
165 #define STATIC_ASSERT(condition) static_assert(condition, #condition)
166 
AAudioConvert_usageToInternal(aaudio_usage_t usage)167 audio_usage_t AAudioConvert_usageToInternal(aaudio_usage_t usage) {
168     // The public aaudio_content_type_t constants are supposed to have the same
169     // values as the internal audio_content_type_t values.
170     STATIC_ASSERT(AAUDIO_USAGE_MEDIA == AUDIO_USAGE_MEDIA);
171     STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION == AUDIO_USAGE_VOICE_COMMUNICATION);
172     STATIC_ASSERT(AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING
173                   == AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING);
174     STATIC_ASSERT(AAUDIO_USAGE_ALARM == AUDIO_USAGE_ALARM);
175     STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION == AUDIO_USAGE_NOTIFICATION);
176     STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_RINGTONE
177                   == AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE);
178     STATIC_ASSERT(AAUDIO_USAGE_NOTIFICATION_EVENT == AUDIO_USAGE_NOTIFICATION_EVENT);
179     STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY);
180     STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE
181                   == AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
182     STATIC_ASSERT(AAUDIO_USAGE_ASSISTANCE_SONIFICATION == AUDIO_USAGE_ASSISTANCE_SONIFICATION);
183     STATIC_ASSERT(AAUDIO_USAGE_GAME == AUDIO_USAGE_GAME);
184     STATIC_ASSERT(AAUDIO_USAGE_ASSISTANT == AUDIO_USAGE_ASSISTANT);
185     if (usage == AAUDIO_UNSPECIFIED) {
186         usage = AAUDIO_USAGE_MEDIA;
187     }
188     return (audio_usage_t) usage; // same value
189 }
190 
AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType)191 audio_content_type_t AAudioConvert_contentTypeToInternal(aaudio_content_type_t contentType) {
192     // The public aaudio_content_type_t constants are supposed to have the same
193     // values as the internal audio_content_type_t values.
194     STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MUSIC == AUDIO_CONTENT_TYPE_MUSIC);
195     STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SPEECH == AUDIO_CONTENT_TYPE_SPEECH);
196     STATIC_ASSERT(AAUDIO_CONTENT_TYPE_SONIFICATION == AUDIO_CONTENT_TYPE_SONIFICATION);
197     STATIC_ASSERT(AAUDIO_CONTENT_TYPE_MOVIE == AUDIO_CONTENT_TYPE_MOVIE);
198     if (contentType == AAUDIO_UNSPECIFIED) {
199         contentType = AAUDIO_CONTENT_TYPE_MUSIC;
200     }
201     return (audio_content_type_t) contentType; // same value
202 }
203 
AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset)204 audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t preset) {
205     // The public aaudio_input_preset_t constants are supposed to have the same
206     // values as the internal audio_source_t values.
207     STATIC_ASSERT(AAUDIO_UNSPECIFIED == AUDIO_SOURCE_DEFAULT);
208     STATIC_ASSERT(AAUDIO_INPUT_PRESET_GENERIC == AUDIO_SOURCE_MIC);
209     STATIC_ASSERT(AAUDIO_INPUT_PRESET_CAMCORDER == AUDIO_SOURCE_CAMCORDER);
210     STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_RECOGNITION == AUDIO_SOURCE_VOICE_RECOGNITION);
211     STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION == AUDIO_SOURCE_VOICE_COMMUNICATION);
212     STATIC_ASSERT(AAUDIO_INPUT_PRESET_UNPROCESSED == AUDIO_SOURCE_UNPROCESSED);
213     STATIC_ASSERT(AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE == AUDIO_SOURCE_VOICE_PERFORMANCE);
214     if (preset == AAUDIO_UNSPECIFIED) {
215         preset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
216     }
217     return (audio_source_t) preset; // same value
218 }
219 
AAudioConvert_allowCapturePolicyToAudioFlagsMask(aaudio_allowed_capture_policy_t policy)220 audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
221         aaudio_allowed_capture_policy_t policy) {
222     switch (policy) {
223         case AAUDIO_UNSPECIFIED:
224         case AAUDIO_ALLOW_CAPTURE_BY_ALL:
225             return AUDIO_FLAG_NONE;
226         case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
227             return AUDIO_FLAG_NO_MEDIA_PROJECTION;
228         case AAUDIO_ALLOW_CAPTURE_BY_NONE:
229             return AUDIO_FLAG_NO_MEDIA_PROJECTION | AUDIO_FLAG_NO_SYSTEM_CAPTURE;
230         default:
231             ALOGE("%s() 0x%08X unrecognized", __func__, policy);
232             return AUDIO_FLAG_NONE; //
233     }
234 }
235 
AAudioConvert_framesToBytes(int32_t numFrames,int32_t bytesPerFrame,int32_t * sizeInBytes)236 int32_t AAudioConvert_framesToBytes(int32_t numFrames,
237                                     int32_t bytesPerFrame,
238                                     int32_t *sizeInBytes) {
239     *sizeInBytes = 0;
240 
241     if (numFrames < 0 || bytesPerFrame < 0) {
242         ALOGE("negative size, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame);
243         return AAUDIO_ERROR_OUT_OF_RANGE;
244     }
245 
246     // Prevent numeric overflow.
247     if (numFrames > (INT32_MAX / bytesPerFrame)) {
248         ALOGE("size overflow, numFrames = %d, frameSize = %d", numFrames, bytesPerFrame);
249         return AAUDIO_ERROR_OUT_OF_RANGE;
250     }
251 
252     *sizeInBytes = numFrames * bytesPerFrame;
253     return AAUDIO_OK;
254 }
255 
AAudioProperty_getMMapProperty(const char * propName,int32_t defaultValue,const char * caller)256 static int32_t AAudioProperty_getMMapProperty(const char *propName,
257                                               int32_t defaultValue,
258                                               const char * caller) {
259     int32_t prop = property_get_int32(propName, defaultValue);
260     switch (prop) {
261         case AAUDIO_UNSPECIFIED:
262         case AAUDIO_POLICY_NEVER:
263         case AAUDIO_POLICY_ALWAYS:
264         case AAUDIO_POLICY_AUTO:
265             break;
266         default:
267             ALOGE("%s: invalid = %d", caller, prop);
268             prop = defaultValue;
269             break;
270     }
271     return prop;
272 }
273 
AAudioProperty_getMMapPolicy()274 int32_t AAudioProperty_getMMapPolicy() {
275     return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_POLICY,
276                                           AAUDIO_UNSPECIFIED, __func__);
277 }
278 
AAudioProperty_getMMapExclusivePolicy()279 int32_t AAudioProperty_getMMapExclusivePolicy() {
280     return AAudioProperty_getMMapProperty(AAUDIO_PROP_MMAP_EXCLUSIVE_POLICY,
281                                           AAUDIO_UNSPECIFIED, __func__);
282 }
283 
AAudioProperty_getMixerBursts()284 int32_t AAudioProperty_getMixerBursts() {
285     const int32_t defaultBursts = 2; // arbitrary, use 2 for double buffered
286     const int32_t maxBursts = 1024; // arbitrary
287     int32_t prop = property_get_int32(AAUDIO_PROP_MIXER_BURSTS, defaultBursts);
288     if (prop < 1 || prop > maxBursts) {
289         ALOGE("AAudioProperty_getMixerBursts: invalid = %d", prop);
290         prop = defaultBursts;
291     }
292     return prop;
293 }
294 
AAudioProperty_getWakeupDelayMicros()295 int32_t AAudioProperty_getWakeupDelayMicros() {
296     const int32_t minMicros = 0; // arbitrary
297     const int32_t defaultMicros = 200; // arbitrary, based on some observed jitter
298     const int32_t maxMicros = 5000; // arbitrary, probably don't want more than 500
299     int32_t prop = property_get_int32(AAUDIO_PROP_WAKEUP_DELAY_USEC, defaultMicros);
300     if (prop < minMicros) {
301         ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, minMicros);
302         prop = minMicros;
303     } else if (prop > maxMicros) {
304         ALOGW("AAudioProperty_getWakeupDelayMicros: clipped %d to %d", prop, maxMicros);
305         prop = maxMicros;
306     }
307     return prop;
308 }
309 
AAudioProperty_getMinimumSleepMicros()310 int32_t AAudioProperty_getMinimumSleepMicros() {
311     const int32_t minMicros = 20; // arbitrary
312     const int32_t defaultMicros = 200; // arbitrary
313     const int32_t maxMicros = 2000; // arbitrary
314     int32_t prop = property_get_int32(AAUDIO_PROP_MINIMUM_SLEEP_USEC, defaultMicros);
315     if (prop < minMicros) {
316         ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, minMicros);
317         prop = minMicros;
318     } else if (prop > maxMicros) {
319         ALOGW("AAudioProperty_getMinimumSleepMicros: clipped %d to %d", prop, maxMicros);
320         prop = maxMicros;
321     }
322     return prop;
323 }
324 
AAudioProperty_getHardwareBurstMinMicros()325 int32_t AAudioProperty_getHardwareBurstMinMicros() {
326     const int32_t defaultMicros = 1000; // arbitrary
327     const int32_t maxMicros = 1000 * 1000; // arbitrary
328     int32_t prop = property_get_int32(AAUDIO_PROP_HW_BURST_MIN_USEC, defaultMicros);
329     if (prop < 1 || prop > maxMicros) {
330         ALOGE("AAudioProperty_getHardwareBurstMinMicros: invalid = %d, use %d",
331               prop, defaultMicros);
332         prop = defaultMicros;
333     }
334     return prop;
335 }
336 
AAudio_isFlushAllowed(aaudio_stream_state_t state)337 aaudio_result_t AAudio_isFlushAllowed(aaudio_stream_state_t state) {
338     aaudio_result_t result = AAUDIO_OK;
339     switch (state) {
340 // Proceed with flushing.
341         case AAUDIO_STREAM_STATE_OPEN:
342         case AAUDIO_STREAM_STATE_PAUSED:
343         case AAUDIO_STREAM_STATE_STOPPED:
344         case AAUDIO_STREAM_STATE_FLUSHED:
345             break;
346 
347 // Transition from one inactive state to another.
348         case AAUDIO_STREAM_STATE_STARTING:
349         case AAUDIO_STREAM_STATE_STARTED:
350         case AAUDIO_STREAM_STATE_STOPPING:
351         case AAUDIO_STREAM_STATE_PAUSING:
352         case AAUDIO_STREAM_STATE_FLUSHING:
353         case AAUDIO_STREAM_STATE_CLOSING:
354         case AAUDIO_STREAM_STATE_CLOSED:
355         case AAUDIO_STREAM_STATE_DISCONNECTED:
356         default:
357             ALOGE("can only flush stream when PAUSED, OPEN or STOPPED, state = %s",
358                   AAudio_convertStreamStateToText(state));
359             result =  AAUDIO_ERROR_INVALID_STATE;
360             break;
361     }
362     return result;
363 }
364