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