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