xref: /aosp_15_r20/frameworks/av/media/libaaudio/src/core/AAudioStreamParameters.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright 2017 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 
18 #define LOG_TAG "AAudioStreamParameters"
19 
20 #include <android-base/strings.h>
21 #include <utils/Log.h>
22 #include <system/audio.h>
23 #include <system/aaudio/AAudio.h>
24 
25 #include "AAudioStreamParameters.h"
26 
27 using namespace aaudio;
28 
copyFrom(const AAudioStreamParameters & other)29 void AAudioStreamParameters::copyFrom(const AAudioStreamParameters &other) {
30     mSamplesPerFrame      = other.mSamplesPerFrame;
31     mSampleRate           = other.mSampleRate;
32     mDeviceIds            = other.mDeviceIds;
33     mSessionId            = other.mSessionId;
34     mSharingMode          = other.mSharingMode;
35     mAudioFormat          = other.mAudioFormat;
36     mDirection            = other.mDirection;
37     mBufferCapacity       = other.mBufferCapacity;
38     mUsage                = other.mUsage;
39     mContentType          = other.mContentType;
40     mTags                 = other.mTags;
41     mSpatializationBehavior = other.mSpatializationBehavior;
42     mIsContentSpatialized = other.mIsContentSpatialized;
43     mInputPreset          = other.mInputPreset;
44     mAllowedCapturePolicy = other.mAllowedCapturePolicy;
45     mIsPrivacySensitive   = other.mIsPrivacySensitive;
46     mOpPackageName        = other.mOpPackageName;
47     mAttributionTag       = other.mAttributionTag;
48     mChannelMask          = other.mChannelMask;
49     mHardwareSamplesPerFrame = other.mHardwareSamplesPerFrame;
50     mHardwareSampleRate   = other.mHardwareSampleRate;
51     mHardwareAudioFormat  = other.mHardwareAudioFormat;
52 }
53 
isFormatValid(audio_format_t format)54 static aaudio_result_t isFormatValid(audio_format_t format) {
55     switch (format) {
56         case AUDIO_FORMAT_DEFAULT:
57         case AUDIO_FORMAT_PCM_16_BIT:
58         case AUDIO_FORMAT_PCM_32_BIT:
59         case AUDIO_FORMAT_PCM_FLOAT:
60         case AUDIO_FORMAT_PCM_24_BIT_PACKED:
61         case AUDIO_FORMAT_PCM_8_24_BIT:
62         case AUDIO_FORMAT_IEC61937:
63         case AUDIO_FORMAT_MP3:
64         case AUDIO_FORMAT_AAC_LC:
65         case AUDIO_FORMAT_AAC_HE_V1:
66         case AUDIO_FORMAT_AAC_HE_V2:
67         case AUDIO_FORMAT_AAC_ELD:
68         case AUDIO_FORMAT_AAC_XHE:
69         case AUDIO_FORMAT_OPUS:
70             break; // valid
71         default:
72             ALOGD("audioFormat not valid, audio_format_t = 0x%08x", format);
73             return AAUDIO_ERROR_INVALID_FORMAT;
74             // break;
75     }
76     return AAUDIO_OK;
77 }
78 
validate() const79 aaudio_result_t AAudioStreamParameters::validate() const {
80     if (mSamplesPerFrame != AAUDIO_UNSPECIFIED && (mSamplesPerFrame < CHANNEL_COUNT_MIN_AAUDIO ||
81                                                    mSamplesPerFrame > CHANNEL_COUNT_MAX_AAUDIO)) {
82         ALOGD("channelCount out of range = %d", mSamplesPerFrame);
83         return AAUDIO_ERROR_OUT_OF_RANGE;
84     }
85 
86     // TODO(b/379139078): Query AudioSystem::listAudioPorts
87     for (auto deviceId : mDeviceIds) {
88         if (deviceId < 0) {
89             ALOGE("deviceId out of range = %d, deviceIds = %s", deviceId,
90                       android::toString(mDeviceIds).c_str());
91             return AAUDIO_ERROR_OUT_OF_RANGE;
92         }
93     }
94 
95     // All Session ID values are legal.
96     switch (mSessionId) {
97         case AAUDIO_SESSION_ID_NONE:
98         case AAUDIO_SESSION_ID_ALLOCATE:
99         default:
100             break;
101     }
102 
103     switch (mSharingMode) {
104         case AAUDIO_SHARING_MODE_EXCLUSIVE:
105         case AAUDIO_SHARING_MODE_SHARED:
106             break;
107         default:
108             ALOGD("illegal sharingMode = %d", mSharingMode);
109             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
110             // break;
111     }
112 
113     aaudio_result_t result = isFormatValid (mAudioFormat);
114     if (result != AAUDIO_OK) return result;
115 
116     if (mSampleRate != AAUDIO_UNSPECIFIED &&
117         (mSampleRate < SAMPLE_RATE_HZ_MIN_AAUDIO || mSampleRate > SAMPLE_RATE_HZ_MAX_IEC610937)) {
118         ALOGD("sampleRate out of range = %d", mSampleRate);
119         return AAUDIO_ERROR_INVALID_RATE;
120     }
121 
122     if (mBufferCapacity < 0) {
123         ALOGD("bufferCapacity out of range = %d", mBufferCapacity);
124         return AAUDIO_ERROR_OUT_OF_RANGE;
125     }
126 
127     switch (mDirection) {
128         case AAUDIO_DIRECTION_INPUT:
129         case AAUDIO_DIRECTION_OUTPUT:
130             break; // valid
131         default:
132             ALOGD("direction not valid = %d", mDirection);
133             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
134             // break;
135     }
136 
137     switch (mUsage) {
138         case AAUDIO_UNSPECIFIED:
139         case AAUDIO_USAGE_MEDIA:
140         case AAUDIO_USAGE_VOICE_COMMUNICATION:
141         case AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
142         case AAUDIO_USAGE_ALARM:
143         case AAUDIO_USAGE_NOTIFICATION:
144         case AAUDIO_USAGE_NOTIFICATION_RINGTONE:
145         case AAUDIO_USAGE_NOTIFICATION_EVENT:
146         case AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
147         case AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
148         case AAUDIO_USAGE_ASSISTANCE_SONIFICATION:
149         case AAUDIO_USAGE_GAME:
150         case AAUDIO_USAGE_ASSISTANT:
151         case AAUDIO_SYSTEM_USAGE_EMERGENCY:
152         case AAUDIO_SYSTEM_USAGE_SAFETY:
153         case AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS:
154         case AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT:
155             break; // valid
156         default:
157             ALOGD("usage not valid = %d", mUsage);
158             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
159             // break;
160     }
161 
162     switch (mContentType) {
163         case AAUDIO_UNSPECIFIED:
164         case AAUDIO_CONTENT_TYPE_MUSIC:
165         case AAUDIO_CONTENT_TYPE_MOVIE:
166         case AAUDIO_CONTENT_TYPE_SONIFICATION:
167         case AAUDIO_CONTENT_TYPE_SPEECH:
168             break; // valid
169         default:
170             ALOGD("content type not valid = %d", mContentType);
171             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
172             // break;
173     }
174 
175     switch (mSpatializationBehavior) {
176         case AAUDIO_UNSPECIFIED:
177         case AAUDIO_SPATIALIZATION_BEHAVIOR_AUTO:
178         case AAUDIO_SPATIALIZATION_BEHAVIOR_NEVER:
179             break; // valid
180         default:
181             ALOGD("spatialization behavior not valid = %d", mSpatializationBehavior);
182             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
183             // break;
184     }
185 
186     // no validation required for mIsContentSpatialized
187 
188     switch (mInputPreset) {
189         case AAUDIO_UNSPECIFIED:
190         case AAUDIO_INPUT_PRESET_GENERIC:
191         case AAUDIO_INPUT_PRESET_CAMCORDER:
192         case AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION:
193         case AAUDIO_INPUT_PRESET_VOICE_RECOGNITION:
194         case AAUDIO_INPUT_PRESET_UNPROCESSED:
195         case AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE:
196         case AAUDIO_INPUT_PRESET_SYSTEM_ECHO_REFERENCE:
197         case AAUDIO_INPUT_PRESET_SYSTEM_HOTWORD:
198             break; // valid
199         default:
200             ALOGD("input preset not valid = %d", mInputPreset);
201             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
202             // break;
203     }
204 
205     switch (mAllowedCapturePolicy) {
206         case AAUDIO_UNSPECIFIED:
207         case AAUDIO_ALLOW_CAPTURE_BY_ALL:
208         case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
209         case AAUDIO_ALLOW_CAPTURE_BY_NONE:
210             break; // valid
211         default:
212             ALOGD("allowed capture policy not valid = %d", mAllowedCapturePolicy);
213             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
214             // break;
215     }
216 
217     if (getTagsAsString().size() >= AUDIO_ATTRIBUTES_TAGS_MAX_SIZE) {
218         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
219     }
220 
221     return validateChannelMask();
222 }
223 
validateChannelMask() const224 aaudio_result_t AAudioStreamParameters::validateChannelMask() const {
225     if (mChannelMask == AAUDIO_UNSPECIFIED) {
226         return AAUDIO_OK;
227     }
228 
229     if (mChannelMask & AAUDIO_CHANNEL_BIT_INDEX) {
230         switch (mChannelMask) {
231             case AAUDIO_CHANNEL_INDEX_MASK_1:
232             case AAUDIO_CHANNEL_INDEX_MASK_2:
233             case AAUDIO_CHANNEL_INDEX_MASK_3:
234             case AAUDIO_CHANNEL_INDEX_MASK_4:
235             case AAUDIO_CHANNEL_INDEX_MASK_5:
236             case AAUDIO_CHANNEL_INDEX_MASK_6:
237             case AAUDIO_CHANNEL_INDEX_MASK_7:
238             case AAUDIO_CHANNEL_INDEX_MASK_8:
239             case AAUDIO_CHANNEL_INDEX_MASK_9:
240             case AAUDIO_CHANNEL_INDEX_MASK_10:
241             case AAUDIO_CHANNEL_INDEX_MASK_11:
242             case AAUDIO_CHANNEL_INDEX_MASK_12:
243             case AAUDIO_CHANNEL_INDEX_MASK_13:
244             case AAUDIO_CHANNEL_INDEX_MASK_14:
245             case AAUDIO_CHANNEL_INDEX_MASK_15:
246             case AAUDIO_CHANNEL_INDEX_MASK_16:
247             case AAUDIO_CHANNEL_INDEX_MASK_17:
248             case AAUDIO_CHANNEL_INDEX_MASK_18:
249             case AAUDIO_CHANNEL_INDEX_MASK_19:
250             case AAUDIO_CHANNEL_INDEX_MASK_20:
251             case AAUDIO_CHANNEL_INDEX_MASK_21:
252             case AAUDIO_CHANNEL_INDEX_MASK_22:
253             case AAUDIO_CHANNEL_INDEX_MASK_23:
254             case AAUDIO_CHANNEL_INDEX_MASK_24:
255                 return AAUDIO_OK;
256             default:
257                 ALOGD("Invalid channel index mask %#x", mChannelMask);
258                 return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
259         }
260     }
261 
262     if (getDirection() == AAUDIO_DIRECTION_INPUT) {
263         switch (mChannelMask) {
264             case AAUDIO_CHANNEL_MONO:
265             case AAUDIO_CHANNEL_STEREO:
266             case AAUDIO_CHANNEL_FRONT_BACK:
267             case AAUDIO_CHANNEL_2POINT0POINT2:
268             case AAUDIO_CHANNEL_2POINT1POINT2:
269             case AAUDIO_CHANNEL_3POINT0POINT2:
270             case AAUDIO_CHANNEL_3POINT1POINT2:
271             case AAUDIO_CHANNEL_5POINT1:
272                 return AAUDIO_OK;
273             default:
274                 ALOGD("Invalid channel mask %#x, IN", mChannelMask);
275                 return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
276         }
277     } else {
278         switch (mChannelMask) {
279             case AAUDIO_CHANNEL_MONO:
280             case AAUDIO_CHANNEL_STEREO:
281             case AAUDIO_CHANNEL_2POINT1:
282             case AAUDIO_CHANNEL_TRI:
283             case AAUDIO_CHANNEL_TRI_BACK:
284             case AAUDIO_CHANNEL_3POINT1:
285             case AAUDIO_CHANNEL_2POINT0POINT2:
286             case AAUDIO_CHANNEL_2POINT1POINT2:
287             case AAUDIO_CHANNEL_3POINT0POINT2:
288             case AAUDIO_CHANNEL_3POINT1POINT2:
289             case AAUDIO_CHANNEL_QUAD:
290             case AAUDIO_CHANNEL_QUAD_SIDE:
291             case AAUDIO_CHANNEL_SURROUND:
292             case AAUDIO_CHANNEL_PENTA:
293             case AAUDIO_CHANNEL_5POINT1:
294             case AAUDIO_CHANNEL_5POINT1_SIDE:
295             case AAUDIO_CHANNEL_5POINT1POINT2:
296             case AAUDIO_CHANNEL_5POINT1POINT4:
297             case AAUDIO_CHANNEL_6POINT1:
298             case AAUDIO_CHANNEL_7POINT1:
299             case AAUDIO_CHANNEL_7POINT1POINT2:
300             case AAUDIO_CHANNEL_7POINT1POINT4:
301             case AAUDIO_CHANNEL_9POINT1POINT4:
302             case AAUDIO_CHANNEL_9POINT1POINT6:
303                 return AAUDIO_OK;
304             default:
305                 ALOGD("Invalid channel mask %#x. OUT", mChannelMask);
306                 return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
307         }
308     }
309 }
310 
getTagsAsString() const311 std::string AAudioStreamParameters::getTagsAsString() const {
312     return android::base::Join(mTags, AUDIO_ATTRIBUTES_TAGS_SEPARATOR);
313 }
314 
dump() const315 void AAudioStreamParameters::dump() const {
316     ALOGD("mDeviceIds            = %s",  android::toString(mDeviceIds).c_str());
317     ALOGD("mSessionId            = %6d", mSessionId);
318     ALOGD("mSampleRate           = %6d", mSampleRate);
319     ALOGD("mSamplesPerFrame      = %6d", mSamplesPerFrame);
320     ALOGD("mChannelMask          = %#x", mChannelMask);
321     ALOGD("mSharingMode          = %6d", (int)mSharingMode);
322     ALOGD("mAudioFormat          = %6d", (int)mAudioFormat);
323     ALOGD("mDirection            = %6d", mDirection);
324     ALOGD("mBufferCapacity       = %6d", mBufferCapacity);
325     ALOGD("mUsage                = %6d", mUsage);
326     ALOGD("mContentType          = %6d", mContentType);
327     ALOGD("mTags                 = %s",  getTagsAsString().c_str());
328     ALOGD("mSpatializationBehavior = %6d", mSpatializationBehavior);
329     ALOGD("mIsContentSpatialized = %s", mIsContentSpatialized ? "true" : "false");
330     ALOGD("mInputPreset          = %6d", mInputPreset);
331     ALOGD("mAllowedCapturePolicy = %6d", mAllowedCapturePolicy);
332     ALOGD("mIsPrivacySensitive   = %s", mIsPrivacySensitive ? "true" : "false");
333     ALOGD("mOpPackageName        = %s", !mOpPackageName.has_value() ?
334         "(null)" : mOpPackageName.value().c_str());
335     ALOGD("mAttributionTag       = %s", !mAttributionTag.has_value() ?
336         "(null)" : mAttributionTag.value().c_str());
337     ALOGD("mHardwareSamplesPerFrame = %6d", mHardwareSamplesPerFrame);
338     ALOGD("mHardwareSampleRate   = %6d", mHardwareSampleRate);
339     ALOGD("mHardwareAudioFormat  = %6d", (int)mHardwareAudioFormat);
340 }
341