156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi/* 256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Copyright (C) 2015 The Android Open Source Project 356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * 456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * you may not use this file except in compliance with the License. 656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * You may obtain a copy of the License at 756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * 856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * 1056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 1156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 1256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * See the License for the specific language governing permissions and 1456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * limitations under the License. 1556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi */ 1656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 1756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#define LOG_TAG "APM::IOProfile" 1856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi//#define LOG_NDEBUG 0 1956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 20ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "IOProfile.h" 21ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "HwModule.h" 2298cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie#include "AudioGain.h" 23112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie#include "TypeConverter.h" 2456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 2556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivinamespace android { 2656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 2756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi// checks if the IO profile is compatible with specified parameters. 2856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi// Sampling rate, format and channel mask must be specified in order to 2956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi// get a valid a match 3056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool IOProfile::isCompatibleProfile(audio_devices_t device, 3153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie String8 address, 3253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie uint32_t samplingRate, 3353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie uint32_t *updatedSamplingRate, 3453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie audio_format_t format, 35f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung audio_format_t *updatedFormat, 3653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie audio_channel_mask_t channelMask, 37f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung audio_channel_mask_t *updatedChannelMask, 3853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie uint32_t flags) const 3956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 40a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie const bool isPlaybackThread = 41a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie getType() == AUDIO_PORT_TYPE_MIX && getRole() == AUDIO_PORT_ROLE_SOURCE; 42a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie const bool isRecordThread = 43a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie getType() == AUDIO_PORT_TYPE_MIX && getRole() == AUDIO_PORT_ROLE_SINK; 4456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi ALOG_ASSERT(isPlaybackThread != isRecordThread); 4556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 46f5d144f7ca773750ea7be371f14f9fc975a15862Eric Laurent 47f5d144f7ca773750ea7be371f14f9fc975a15862Eric Laurent if (device != AUDIO_DEVICE_NONE) { 48f5d144f7ca773750ea7be371f14f9fc975a15862Eric Laurent // just check types if multiple devices are selected 49f5d144f7ca773750ea7be371f14f9fc975a15862Eric Laurent if (popcount(device & ~AUDIO_DEVICE_BIT_IN) > 1) { 50f5d144f7ca773750ea7be371f14f9fc975a15862Eric Laurent if ((mSupportedDevices.types() & device) != device) { 51f5d144f7ca773750ea7be371f14f9fc975a15862Eric Laurent return false; 52f5d144f7ca773750ea7be371f14f9fc975a15862Eric Laurent } 53f5d144f7ca773750ea7be371f14f9fc975a15862Eric Laurent } else if (mSupportedDevices.getDevice(device, address) == 0) { 54f5d144f7ca773750ea7be371f14f9fc975a15862Eric Laurent return false; 55f5d144f7ca773750ea7be371f14f9fc975a15862Eric Laurent } 5656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 5756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 5805ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten if (!audio_is_valid_format(format) || 5905ddca504ce8e0e61b41e5c1aebea72086eea57bGlenn Kasten (isPlaybackThread && (samplingRate == 0 || !audio_is_output_channel(channelMask))) || 60112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie (isRecordThread && (!audio_is_input_channel(channelMask)))) { 6156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 6256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 6356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 64f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung audio_format_t myUpdatedFormat = format; 65f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung audio_channel_mask_t myUpdatedChannelMask = channelMask; 66112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie uint32_t myUpdatedSamplingRate = samplingRate; 67112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (isRecordThread) 68112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie { 69112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (checkCompatibleAudioProfile( 70112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie myUpdatedSamplingRate, myUpdatedChannelMask, myUpdatedFormat) != NO_ERROR) { 71112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return false; 72112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 73112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } else { 74112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie if (checkExactAudioProfile(samplingRate, channelMask, format) != NO_ERROR) { 75112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie return false; 76112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie } 7756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 7856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 79a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie if (isPlaybackThread && (getFlags() & flags) != flags) { 8056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 8156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 8256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi // The only input flag that is allowed to be different is the fast flag. 8356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi // An existing fast stream is compatible with a normal track request. 8456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi // An existing normal stream is compatible with a fast track request, 8556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi // but the fast request will be denied by AudioFlinger and converted to normal track. 86a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie if (isRecordThread && ((getFlags() ^ flags) & 8756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi ~AUDIO_INPUT_FLAG_FAST)) { 8856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 8956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 9056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 9156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (updatedSamplingRate != NULL) { 9256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *updatedSamplingRate = myUpdatedSamplingRate; 9356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 94f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung if (updatedFormat != NULL) { 95f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung *updatedFormat = myUpdatedFormat; 96f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung } 97f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung if (updatedChannelMask != NULL) { 98f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung *updatedChannelMask = myUpdatedChannelMask; 99f129b03fa583d4cc26fd9c9171b8fb3b0ed8d4f4Andy Hung } 10056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return true; 10156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 10256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 10356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid IOProfile::dump(int fd) 10456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 10556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const size_t SIZE = 256; 10656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi char buffer[SIZE]; 10756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi String8 result; 10856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 10956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi AudioPort::dump(fd, 4); 11056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 111a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie snprintf(buffer, SIZE, " - flags: 0x%04x\n", getFlags()); 11256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 11356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, result.string(), result.size()); 114f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie mSupportedDevices.dump(fd, String8("Supported"), 4, false); 11556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 11656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 11756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid IOProfile::log() 11856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 119112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie // @TODO: forward log to AudioPort 12056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 12156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 12256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}; // namespace android 123