1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "intell_voice_sensibility.h"
16
17 #include <fstream>
18 #include <algorithm>
19
20 #include "history_info_mgr.h"
21 #include "intell_voice_log.h"
22 #include "string_util.h"
23 #include "intell_voice_definitions.h"
24
25 #define LOG_TAG "IntellVoiceSensibility"
26
27 using namespace std;
28 using namespace OHOS::IntellVoiceUtils;
29
30 namespace OHOS {
31 namespace IntellVoiceEngine {
32 static constexpr int32_t MIN_SENSIBILITY_VALUE = 1;
33 static constexpr int32_t MAX_SENSIBILITY_VALUE = 3;
34 static constexpr int32_t THRESH_OFFST = 3;
35 static constexpr uint32_t HAL_FEATURE_KWS_NODES_900 = 0x2;
36 static const std::string WAKEUP_CONF_DEFAULPHRASE = "DefaultPhrase";
37
GetDspSensibility(const std::string & sensibility,const std::string & dspFeature,const std::string & configPath)38 std::string IntellVoiceSensibility::GetDspSensibility(const std::string &sensibility, const std::string &dspFeature,
39 const std::string &configPath)
40 {
41 int32_t value = 0;
42 if (!StringUtil::StringToInt(sensibility, value)) {
43 INTELL_VOICE_LOG_ERROR("failed to get sensibility");
44 return "";
45 }
46 if ((value < MIN_SENSIBILITY_VALUE) || (value > MAX_SENSIBILITY_VALUE)) {
47 INTELL_VOICE_LOG_WARN("invalid sensibility:%{public}d", value);
48 return "";
49 }
50 std::string wakeupPhrase = HistoryInfoMgr::GetInstance().GetStringKVPair(KEY_WAKEUP_PHRASE);
51 if (wakeupPhrase.empty()) {
52 INTELL_VOICE_LOG_WARN("wakeup phrase is empty");
53 return "";
54 }
55 int32_t index = (IsSupportNodes800(dspFeature) ? (value + THRESH_OFFST - 1) : (value - 1));
56 return ParseWakeupConfigDspSensibility(wakeupPhrase, static_cast<uint32_t>(index), configPath);
57 }
58
ParseWakeupConfigDspSensibility(const std::string & wakeupPhrase,uint32_t index,const std::string & configPath)59 std::string IntellVoiceSensibility::ParseWakeupConfigDspSensibility(const std::string &wakeupPhrase, uint32_t index,
60 const std::string &configPath)
61 {
62 std::ifstream jsonStrm(configPath);
63 if (!jsonStrm.is_open()) {
64 INTELL_VOICE_LOG_ERROR("open file faile!");
65 return "";
66 }
67 Json::Value wakeupJson;
68 Json::CharReaderBuilder reader;
69 reader["collectComments"] = false;
70 std::string errs;
71 if (!parseFromStream(reader, jsonStrm, &wakeupJson, &errs)) {
72 INTELL_VOICE_LOG_ERROR("parseFromStream json faile!");
73 return "";
74 }
75
76 if (IsDefaltPhrase(wakeupJson, wakeupPhrase)) {
77 return ParseDefaultDspSensibility(wakeupJson, wakeupPhrase, index);
78 }
79
80 return ParseUserDspSensibility(wakeupJson, index);
81 }
82
ParseDefaultDspSensibility(const Json::Value & wakeupJson,const std::string & wakeupPhrase,uint32_t index)83 std::string IntellVoiceSensibility::ParseDefaultDspSensibility(const Json::Value &wakeupJson,
84 const std::string &wakeupPhrase, uint32_t index)
85 {
86 if ((wakeupJson.isMember(WAKEUP_CONF_DEFAULPHRASE)) &&
87 (wakeupJson[WAKEUP_CONF_DEFAULPHRASE].isMember(wakeupPhrase))) {
88 Json::Value sensibilityArray = wakeupJson[WAKEUP_CONF_DEFAULPHRASE][wakeupPhrase];
89 if ((sensibilityArray.isArray()) && (sensibilityArray.size() > index) && (sensibilityArray[index].isInt())) {
90 return std::to_string(sensibilityArray[index].asInt());
91 }
92 INTELL_VOICE_LOG_WARN("index:%{public}u, default sensibility is invalid", index);
93 return "";
94 }
95 if ((!wakeupJson.isMember("SensibilityParams")) ||
96 (!wakeupJson["SensibilityParams"].isMember("DspSentenceThresholds"))) {
97 INTELL_VOICE_LOG_WARN("no sensiblity param");
98 return "";
99 }
100
101 Json::Value sensibilityParam = wakeupJson["SensibilityParams"]["DspSentenceThresholds"];
102 if ((sensibilityParam.isMember("Default")) && (sensibilityParam["Default"].isArray()) &&
103 (sensibilityParam["Default"].size() > index) && sensibilityParam["Default"][index].isInt()) {
104 return std::to_string(sensibilityParam["Default"][index].asInt());
105 }
106
107 INTELL_VOICE_LOG_WARN("index:%{public}u, default sensibility param is invalid", index);
108 return "";
109 }
110
ParseUserDspSensibility(const Json::Value & wakeupJson,uint32_t index)111 std::string IntellVoiceSensibility::ParseUserDspSensibility(const Json::Value &wakeupJson, uint32_t index)
112 {
113 if ((!wakeupJson.isMember("SensibilityParams")) ||
114 (!wakeupJson["SensibilityParams"].isMember("DspSentenceThresholds"))) {
115 INTELL_VOICE_LOG_WARN("no sensiblity param");
116 return "";
117 }
118
119 Json::Value sensibilityParam = wakeupJson["SensibilityParams"]["DspSentenceThresholds"];
120 if ((sensibilityParam.isMember("UserDefined")) && (sensibilityParam["UserDefined"].isArray()) &&
121 (sensibilityParam["UserDefined"].size() > index) && sensibilityParam["UserDefined"][index].isInt()) {
122 return std::to_string(sensibilityParam["Default"][index].asInt());
123 }
124
125 INTELL_VOICE_LOG_WARN("index:%{public}u, default sensibility param is invalid", index);
126 return "";
127 }
128
IsDefaltPhrase(const Json::Value & wakeupJson,const std::string & wakeupPhrase)129 bool IntellVoiceSensibility::IsDefaltPhrase(const Json::Value &wakeupJson, const std::string &wakeupPhrase)
130 {
131 const std::vector<std::string> defaultPhrases = {"你好小E", "你好小易", "你好华为", "小艺小艺", "你好悠悠"};
132 if (wakeupJson.isMember(WAKEUP_CONF_DEFAULPHRASE)) {
133 if (wakeupJson[WAKEUP_CONF_DEFAULPHRASE].isMember(wakeupPhrase)) {
134 return true;
135 }
136 } else {
137 auto it = std::find(defaultPhrases.begin(), defaultPhrases.end(), wakeupPhrase);
138 if (it != defaultPhrases.end()) {
139 return true;
140 }
141 }
142
143 return false;
144 }
145
IsSupportNodes800(const std::string & dspFeature)146 bool IntellVoiceSensibility::IsSupportNodes800(const std::string &dspFeature)
147 {
148 if (dspFeature.empty()) {
149 return false;
150 }
151
152 int32_t feature = 0;
153 if (!StringUtil::StringToInt(dspFeature, feature)) {
154 INTELL_VOICE_LOG_ERROR("failed to get dsp feature");
155 return false;
156 }
157
158 if ((feature & HAL_FEATURE_KWS_NODES_900) == HAL_FEATURE_KWS_NODES_900) {
159 return true;
160 }
161
162 return false;
163 }
164 }
165 }