1 /*
2 * Copyright (C) 2015 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 "APM::IOProfile"
18 //#define LOG_NDEBUG 0
19
20 #include "IOProfile.h"
21 #include "HwModule.h"
22 #include "AudioGain.h"
23
24 namespace android {
25
IOProfile(const String8 & name,audio_port_role_t role)26 IOProfile::IOProfile(const String8& name, audio_port_role_t role)
27 : AudioPort(name, AUDIO_PORT_TYPE_MIX, role)
28 {
29 }
30
~IOProfile()31 IOProfile::~IOProfile()
32 {
33 }
34
35 // checks if the IO profile is compatible with specified parameters.
36 // Sampling rate, format and channel mask must be specified in order to
37 // get a valid a match
isCompatibleProfile(audio_devices_t device,String8 address,uint32_t samplingRate,uint32_t * updatedSamplingRate,audio_format_t format,audio_format_t * updatedFormat,audio_channel_mask_t channelMask,audio_channel_mask_t * updatedChannelMask,uint32_t flags) const38 bool IOProfile::isCompatibleProfile(audio_devices_t device,
39 String8 address,
40 uint32_t samplingRate,
41 uint32_t *updatedSamplingRate,
42 audio_format_t format,
43 audio_format_t *updatedFormat,
44 audio_channel_mask_t channelMask,
45 audio_channel_mask_t *updatedChannelMask,
46 uint32_t flags) const
47 {
48 const bool isPlaybackThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SOURCE;
49 const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK;
50 ALOG_ASSERT(isPlaybackThread != isRecordThread);
51
52
53 if (device != AUDIO_DEVICE_NONE) {
54 // just check types if multiple devices are selected
55 if (popcount(device & ~AUDIO_DEVICE_BIT_IN) > 1) {
56 if ((mSupportedDevices.types() & device) != device) {
57 return false;
58 }
59 } else if (mSupportedDevices.getDevice(device, address) == 0) {
60 return false;
61 }
62 }
63
64 if (samplingRate == 0) {
65 return false;
66 }
67 uint32_t myUpdatedSamplingRate = samplingRate;
68 if (isPlaybackThread && checkExactSamplingRate(samplingRate) != NO_ERROR) {
69 return false;
70 }
71 if (isRecordThread && checkCompatibleSamplingRate(samplingRate, &myUpdatedSamplingRate) !=
72 NO_ERROR) {
73 return false;
74 }
75
76 if (!audio_is_valid_format(format)) {
77 return false;
78 }
79 if (isPlaybackThread && checkExactFormat(format) != NO_ERROR) {
80 return false;
81 }
82 audio_format_t myUpdatedFormat = format;
83 if (isRecordThread && checkCompatibleFormat(format, &myUpdatedFormat) != NO_ERROR) {
84 return false;
85 }
86
87 if (isPlaybackThread && (!audio_is_output_channel(channelMask) ||
88 checkExactChannelMask(channelMask) != NO_ERROR)) {
89 return false;
90 }
91 audio_channel_mask_t myUpdatedChannelMask = channelMask;
92 if (isRecordThread && (!audio_is_input_channel(channelMask) ||
93 checkCompatibleChannelMask(channelMask, &myUpdatedChannelMask) != NO_ERROR)) {
94 return false;
95 }
96
97 if (isPlaybackThread && (mFlags & flags) != flags) {
98 return false;
99 }
100 // The only input flag that is allowed to be different is the fast flag.
101 // An existing fast stream is compatible with a normal track request.
102 // An existing normal stream is compatible with a fast track request,
103 // but the fast request will be denied by AudioFlinger and converted to normal track.
104 if (isRecordThread && ((mFlags ^ flags) &
105 ~AUDIO_INPUT_FLAG_FAST)) {
106 return false;
107 }
108
109 if (updatedSamplingRate != NULL) {
110 *updatedSamplingRate = myUpdatedSamplingRate;
111 }
112 if (updatedFormat != NULL) {
113 *updatedFormat = myUpdatedFormat;
114 }
115 if (updatedChannelMask != NULL) {
116 *updatedChannelMask = myUpdatedChannelMask;
117 }
118 return true;
119 }
120
dump(int fd)121 void IOProfile::dump(int fd)
122 {
123 const size_t SIZE = 256;
124 char buffer[SIZE];
125 String8 result;
126
127 AudioPort::dump(fd, 4);
128
129 snprintf(buffer, SIZE, " - flags: 0x%04x\n", mFlags);
130 result.append(buffer);
131 snprintf(buffer, SIZE, " - devices:\n");
132 result.append(buffer);
133 write(fd, result.string(), result.size());
134 for (size_t i = 0; i < mSupportedDevices.size(); i++) {
135 mSupportedDevices[i]->dump(fd, 6, i);
136 }
137 }
138
log()139 void IOProfile::log()
140 {
141 const size_t SIZE = 256;
142 char buffer[SIZE];
143 String8 result;
144
145 ALOGV(" - sampling rates: ");
146 for (size_t i = 0; i < mSamplingRates.size(); i++) {
147 ALOGV(" %d", mSamplingRates[i]);
148 }
149
150 ALOGV(" - channel masks: ");
151 for (size_t i = 0; i < mChannelMasks.size(); i++) {
152 ALOGV(" 0x%04x", mChannelMasks[i]);
153 }
154
155 ALOGV(" - formats: ");
156 for (size_t i = 0; i < mFormats.size(); i++) {
157 ALOGV(" 0x%08x", mFormats[i]);
158 }
159
160 ALOGV(" - devices: 0x%04x\n", mSupportedDevices.types());
161 ALOGV(" - flags: 0x%04x\n", mFlags);
162 }
163
164 }; // namespace android
165