blob: ffeb0518e302d2eafa386496cb034c2c27682977 [file] [log] [blame]
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted (subject to the limitations in the
* disclaimer below) provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ACDPlatformInfo.h"
#include "VoiceUIPlatformInfo.h"
#include "SoundTriggerPlatformInfo.h"
#define LOG_TAG "PAL: SoundTriggerPlatformInfo"
CaptureProfile::CaptureProfile(const std::string name) :
name_(name),
device_id_(PAL_DEVICE_IN_MIN),
sample_rate_(16000),
channels_(1),
bitwidth_(16),
device_pp_kv_(std::make_pair(0, 0)),
snd_name_("va-mic"),
is_ec_req_(false)
{
}
void CaptureProfile::HandleStartTag(const char* tag, const char** attribs)
{
PAL_DBG(LOG_TAG, "Got start tag %s", tag);
if (!strcmp(tag, "param")) {
uint32_t i = 0;
while (attribs[i]) {
if (!strcmp(attribs[i], "device_id")) {
auto itr = deviceIdLUT.find(attribs[++i]);
if (itr == deviceIdLUT.end()) {
PAL_ERR(LOG_TAG, "could not find key %s in lookup table",
attribs[i]);
} else {
device_id_ = itr->second;
}
} else if (!strcmp(attribs[i], "sample_rate")) {
sample_rate_ = std::stoi(attribs[++i]);
} else if (!strcmp(attribs[i], "bit_width")) {
bitwidth_ = std::stoi(attribs[++i]);
} else if (!strcmp(attribs[i], "channels")) {
channels_ = std::stoi(attribs[++i]);
} else if (!strcmp(attribs[i], "snd_name")) {
snd_name_ = attribs[++i];
} else if (!strcmp(attribs[i], "ec_ref")) {
is_ec_req_ = !strncasecmp(attribs[++i], "true", 4) ? true : false;
} else {
PAL_ERR(LOG_TAG, "Invalid attribute %s", attribs[i++]);
}
++i; /* move to next attribute */
}
} else {
PAL_ERR(LOG_TAG, "Invalid tag %s", (char *)tag);
}
}
/*
* Priority compare result indicated by return value as below:
* 1. CAPTURE_PROFILE_PRIORITY_HIGH
* current capture profile has higher priority than cap_prof
* 2. CAPTURE_PROFILE_PRIORITY_LOW
* current capture profile has lower priority than cap_prof
* 3. CAPTURE_PROFILE_PRIORITY_SAME
* current capture profile has same priority than cap_prof
*/
int32_t CaptureProfile::ComparePriority(std::shared_ptr<CaptureProfile> cap_prof)
{
int32_t priority_check = 0;
if (!cap_prof) {
priority_check = CAPTURE_PROFILE_PRIORITY_HIGH;
} else {
// only compare channels for priority for now
if (channels_ < cap_prof->GetChannels()) {
priority_check = CAPTURE_PROFILE_PRIORITY_LOW;
} else if (channels_ > cap_prof->GetChannels()) {
priority_check = CAPTURE_PROFILE_PRIORITY_HIGH;
} else {
priority_check = CAPTURE_PROFILE_PRIORITY_SAME;
}
}
return priority_check;
}
std::shared_ptr<SoundTriggerPlatformInfo> SoundTriggerPlatformInfo::me_ = nullptr;
bool SoundTriggerPlatformInfo::lpi_enable_ = true;
bool SoundTriggerPlatformInfo::support_nlpi_switch_ = true;
bool SoundTriggerPlatformInfo::support_device_switch_ = false;
bool SoundTriggerPlatformInfo::enable_debug_dumps_ = false;
bool SoundTriggerPlatformInfo::concurrent_capture_ = false;
bool SoundTriggerPlatformInfo::concurrent_voice_call_ = false;
bool SoundTriggerPlatformInfo::concurrent_voip_call_ = false;
bool SoundTriggerPlatformInfo::low_latency_bargein_enable_ = false;
SoundTriggerPlatformInfo::SoundTriggerPlatformInfo() : curr_child_(nullptr)
{
}
std::shared_ptr<SoundTriggerPlatformInfo> SoundTriggerPlatformInfo::GetInstance()
{
if (!me_)
me_ = std::shared_ptr<SoundTriggerPlatformInfo>(new SoundTriggerPlatformInfo);
return me_;
}
void SoundTriggerPlatformInfo::ReadCapProfileNames(StOperatingModes mode,
const char** attribs,
st_op_modes_t& op_modes)
{
uint32_t i = 0;
while (attribs[i]) {
if (!strcmp(attribs[i], "capture_profile_handset")) {
op_modes[std::make_pair(mode, ST_INPUT_MODE_HANDSET)] =
capture_profile_map_.at(std::string(attribs[++i]));
} else if(!strcmp(attribs[i], "capture_profile_headset")) {
op_modes[std::make_pair(mode, ST_INPUT_MODE_HEADSET)] =
capture_profile_map_.at(std::string(attribs[++i]));
} else {
PAL_ERR(LOG_TAG, "Error:%d got unexpected attribute: %s",
-EINVAL, attribs[i]);
}
++i; /* move to next attribute */
}
}
void SoundTriggerPlatformInfo::HandleStartTag(const char* tag, const char** attribs)
{
/* Delegate to child element if currently active */
if (curr_child_) {
curr_child_->HandleStartTag(tag, attribs);
return;
}
PAL_DBG(LOG_TAG, "Got start tag %s", tag);
if (!strcmp(tag, "vui_platform_info")) {
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
VoiceUIPlatformInfo::GetInstance());
return;
}
if (!strcmp(tag, "acd_platform_info")) {
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
ACDPlatformInfo::GetInstance());
return;
}
if (!strcmp(tag, "capture_profile")) {
if (attribs[0] && !strcmp(attribs[0], "name")) {
curr_child_ = std::static_pointer_cast<SoundTriggerXml>(
std::make_shared<CaptureProfile>(attribs[1]));
return;
} else {
PAL_ERR(LOG_TAG,"missing name attrib for tag %s", tag);
return;
}
}
if (!strcmp(tag, "common_config") || !strcmp(tag, "capture_profile_list")) {
PAL_VERBOSE(LOG_TAG, "tag:%s appeared, nothing to do", tag);
return;
}
if (!strcmp(tag, "param")) {
uint32_t i = 0;
while (attribs[i]) {
if (!attribs[i]) {
PAL_ERR(LOG_TAG,"missing attrib value for tag %s", tag);
} else if (!strcmp(attribs[i], "lpi_enable")) {
lpi_enable_ =
!strncasecmp(attribs[++i], "true", 4) ? true : false;
} else if (!strcmp(attribs[i], "support_nlpi_switch")) {
support_nlpi_switch_ =
!strncasecmp(attribs[++i], "true", 4) ? true : false;
} else if (!strcmp(attribs[i], "support_device_switch")) {
support_device_switch_ =
!strncasecmp(attribs[++i], "true", 4) ? true : false;
} else if (!strcmp(attribs[i], "enable_debug_dumps")) {
enable_debug_dumps_ =
!strncasecmp(attribs[++i], "true", 4) ? true : false;
} else if (!strcmp(attribs[i], "concurrent_capture")) {
concurrent_capture_ =
!strncasecmp(attribs[++i], "true", 4) ? true : false;
} else if (!strcmp(attribs[i], "concurrent_voice_call") &&
concurrent_capture_) {
concurrent_voice_call_ =
!strncasecmp(attribs[++i], "true", 4) ? true : false;
} else if (!strcmp(attribs[i], "concurrent_voip_call") &&
concurrent_capture_) {
concurrent_voip_call_ =
!strncasecmp(attribs[++i], "true", 4) ? true : false;
} else if (!strcmp(attribs[i], "low_latency_bargein_enable")) {
low_latency_bargein_enable_ =
!strncasecmp(attribs[++i], "true", 4) ? true : false;
} else {
PAL_ERR(LOG_TAG, "Invalid attribute %s", attribs[i++]);
}
++i; /* move to next attribute */
}
} else {
PAL_ERR(LOG_TAG, "Invalid tag %s", tag);
}
}
void SoundTriggerPlatformInfo::HandleEndTag(struct xml_userdata *data, const char* tag)
{
PAL_DBG(LOG_TAG, "Got end tag %s", tag);
if (!strcmp(tag, "capture_profile")) {
std::shared_ptr<CaptureProfile> cap_prof(
std::static_pointer_cast<CaptureProfile>(curr_child_));
const auto res = capture_profile_map_.insert(
std::make_pair(cap_prof->GetName(), cap_prof));
if (!res.second)
PAL_ERR(LOG_TAG, "Failed to insert to map");
curr_child_ = nullptr;
} else if (!strcmp(tag, "acd_platform_info") ||
!strcmp(tag, "vui_platform_info")) {
curr_child_ = nullptr;
}
if (curr_child_)
curr_child_->HandleEndTag(data, tag);
return;
}