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 // TODO Remove 8 channel limitation.
29 #define SAMPLES_PER_FRAME_MAX        FCC_8
30 #define SAMPLE_RATE_HZ_MIN           8000
31 // HDMI supports up to 32 channels at 1536000 Hz.
32 #define SAMPLE_RATE_HZ_MAX           1600000
33 
AAudioStreamParameters()34 AAudioStreamParameters::AAudioStreamParameters() {}
~AAudioStreamParameters()35 AAudioStreamParameters::~AAudioStreamParameters() {}
36 
copyFrom(const AAudioStreamParameters & other)37 void AAudioStreamParameters::copyFrom(const AAudioStreamParameters &other) {
38     mSamplesPerFrame      = other.mSamplesPerFrame;
39     mSampleRate           = other.mSampleRate;
40     mDeviceId             = other.mDeviceId;
41     mSessionId            = other.mSessionId;
42     mSharingMode          = other.mSharingMode;
43     mAudioFormat          = other.mAudioFormat;
44     mDirection            = other.mDirection;
45     mBufferCapacity       = other.mBufferCapacity;
46     mUsage                = other.mUsage;
47     mContentType          = other.mContentType;
48     mInputPreset          = other.mInputPreset;
49     mAllowedCapturePolicy = other.mAllowedCapturePolicy;
50     mIsPrivacySensitive   = other.mIsPrivacySensitive;
51 }
52 
isFormatValid(audio_format_t format)53 static aaudio_result_t isFormatValid(audio_format_t format) {
54     switch (format) {
55         case AUDIO_FORMAT_DEFAULT:
56         case AUDIO_FORMAT_PCM_16_BIT:
57         case AUDIO_FORMAT_PCM_FLOAT:
58             break; // valid
59         default:
60             ALOGD("audioFormat not valid, audio_format_t = 0x%08x", format);
61             return AAUDIO_ERROR_INVALID_FORMAT;
62             // break;
63     }
64     return AAUDIO_OK;
65 }
66 
validate() const67 aaudio_result_t AAudioStreamParameters::validate() const {
68     if (mSamplesPerFrame != AAUDIO_UNSPECIFIED
69         && (mSamplesPerFrame < SAMPLES_PER_FRAME_MIN || mSamplesPerFrame > SAMPLES_PER_FRAME_MAX)) {
70         ALOGD("channelCount out of range = %d", mSamplesPerFrame);
71         return AAUDIO_ERROR_OUT_OF_RANGE;
72     }
73 
74     if (mDeviceId < 0) {
75         ALOGD("deviceId out of range = %d", mDeviceId);
76         return AAUDIO_ERROR_OUT_OF_RANGE;
77     }
78 
79     // All Session ID values are legal.
80     switch (mSessionId) {
81         case AAUDIO_SESSION_ID_NONE:
82         case AAUDIO_SESSION_ID_ALLOCATE:
83             break;
84         default:
85             break;
86     }
87 
88     switch (mSharingMode) {
89         case AAUDIO_SHARING_MODE_EXCLUSIVE:
90         case AAUDIO_SHARING_MODE_SHARED:
91             break;
92         default:
93             ALOGD("illegal sharingMode = %d", mSharingMode);
94             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
95             // break;
96     }
97 
98     aaudio_result_t result = isFormatValid (mAudioFormat);
99     if (result != AAUDIO_OK) return result;
100 
101     if (mSampleRate != AAUDIO_UNSPECIFIED
102         && (mSampleRate < SAMPLE_RATE_HZ_MIN || mSampleRate > SAMPLE_RATE_HZ_MAX)) {
103         ALOGD("sampleRate out of range = %d", mSampleRate);
104         return AAUDIO_ERROR_INVALID_RATE;
105     }
106 
107     if (mBufferCapacity < 0) {
108         ALOGD("bufferCapacity out of range = %d", mBufferCapacity);
109         return AAUDIO_ERROR_OUT_OF_RANGE;
110     }
111 
112     switch (mDirection) {
113         case AAUDIO_DIRECTION_INPUT:
114         case AAUDIO_DIRECTION_OUTPUT:
115             break; // valid
116         default:
117             ALOGD("direction not valid = %d", mDirection);
118             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
119             // break;
120     }
121 
122     switch (mUsage) {
123         case AAUDIO_UNSPECIFIED:
124         case AAUDIO_USAGE_MEDIA:
125         case AAUDIO_USAGE_VOICE_COMMUNICATION:
126         case AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
127         case AAUDIO_USAGE_ALARM:
128         case AAUDIO_USAGE_NOTIFICATION:
129         case AAUDIO_USAGE_NOTIFICATION_RINGTONE:
130         case AAUDIO_USAGE_NOTIFICATION_EVENT:
131         case AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
132         case AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
133         case AAUDIO_USAGE_ASSISTANCE_SONIFICATION:
134         case AAUDIO_USAGE_GAME:
135         case AAUDIO_USAGE_ASSISTANT:
136         case AAUDIO_SYSTEM_USAGE_EMERGENCY:
137         case AAUDIO_SYSTEM_USAGE_SAFETY:
138         case AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS:
139         case AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT:
140             break; // valid
141         default:
142             ALOGD("usage not valid = %d", mUsage);
143             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
144             // break;
145     }
146 
147     switch (mContentType) {
148         case AAUDIO_UNSPECIFIED:
149         case AAUDIO_CONTENT_TYPE_MUSIC:
150         case AAUDIO_CONTENT_TYPE_MOVIE:
151         case AAUDIO_CONTENT_TYPE_SONIFICATION:
152         case AAUDIO_CONTENT_TYPE_SPEECH:
153             break; // valid
154         default:
155             ALOGD("content type not valid = %d", mContentType);
156             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
157             // break;
158     }
159 
160     switch (mInputPreset) {
161         case AAUDIO_UNSPECIFIED:
162         case AAUDIO_INPUT_PRESET_GENERIC:
163         case AAUDIO_INPUT_PRESET_CAMCORDER:
164         case AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION:
165         case AAUDIO_INPUT_PRESET_VOICE_RECOGNITION:
166         case AAUDIO_INPUT_PRESET_UNPROCESSED:
167         case AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE:
168             break; // valid
169         default:
170             ALOGD("input preset not valid = %d", mInputPreset);
171             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
172             // break;
173     }
174 
175     switch (mAllowedCapturePolicy) {
176         case AAUDIO_UNSPECIFIED:
177         case AAUDIO_ALLOW_CAPTURE_BY_ALL:
178         case AAUDIO_ALLOW_CAPTURE_BY_SYSTEM:
179         case AAUDIO_ALLOW_CAPTURE_BY_NONE:
180             break; // valid
181         default:
182             ALOGD("allowed capture policy not valid = %d", mAllowedCapturePolicy);
183             return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
184             // break;
185     }
186 
187     return AAUDIO_OK;
188 }
189 
dump() const190 void AAudioStreamParameters::dump() const {
191     ALOGD("mDeviceId             = %6d", mDeviceId);
192     ALOGD("mSessionId            = %6d", mSessionId);
193     ALOGD("mSampleRate           = %6d", mSampleRate);
194     ALOGD("mSamplesPerFrame      = %6d", mSamplesPerFrame);
195     ALOGD("mSharingMode          = %6d", (int)mSharingMode);
196     ALOGD("mAudioFormat          = %6d", (int)mAudioFormat);
197     ALOGD("mDirection            = %6d", mDirection);
198     ALOGD("mBufferCapacity       = %6d", mBufferCapacity);
199     ALOGD("mUsage                = %6d", mUsage);
200     ALOGD("mContentType          = %6d", mContentType);
201     ALOGD("mInputPreset          = %6d", mInputPreset);
202     ALOGD("mAllowedCapturePolicy = %6d", mAllowedCapturePolicy);
203     ALOGD("mIsPrivacySensitive   = %s", mIsPrivacySensitive ? "true" : "false");
204 }
205