CompareDoubleThread.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. #include "CompareDoubleThread.h"
  2. #include "GlobalInfo.h"
  3. #include "GlobalVariable.h"
  4. #include "GlobalInfo.h"
  5. #include "ThreadManager.h"
  6. #include "ConsistencyCompareThread.h"
  7. #include "CreateRecordFileThread.h"
  8. #include "ThreadAlarmManager.h"
  9. CompareDoubleThread::CompareDoubleThread(CalculateThreadInfo_t& compareItemInfo)
  10. : BaseCalculateThread(compareItemInfo)
  11. {
  12. m_logger = spdlog::get("ACAServer");
  13. if(m_logger == nullptr)
  14. {
  15. fmt::print("CompareDouble: ACAServer Logger not found.\n");
  16. return;
  17. }
  18. m_threadInfo = compareItemInfo;
  19. }
  20. CompareDoubleThread::~CompareDoubleThread()
  21. {
  22. }
  23. /* 获取计算结果 */
  24. OneRoadVolume_t CompareDoubleThread::getVolumeInfo()
  25. {
  26. std::lock_guard<std::mutex> lock(m_mutexVolumeInfo);
  27. return m_roadResult;
  28. }
  29. /**
  30. * @brief 获取最新的计算结果,这里目前只有一致性检测的结果,没有噪音检测的结果
  31. * 1、这里目前没有进行时间判断,直接返回最新的结果
  32. *
  33. * @param volumeInfo
  34. * @return true
  35. * @return false
  36. */
  37. bool CompareDoubleThread::getlastResult(OneRoadVolume_t& volumeInfo)
  38. {
  39. std::lock_guard<std::mutex> lock(m_mutexVolumeInfo);
  40. volumeInfo.isConsistency = m_roadResult.isConsistency;
  41. volumeInfo.isNotConsistencyWarning = m_roadResult.isNotConsistencyWarning;
  42. return true;
  43. }
  44. /* 线程功能函数 */
  45. void CompareDoubleThread::task()
  46. {
  47. /* 初始化数据 */
  48. if(!initData())
  49. {
  50. SPDLOG_LOGGER_ERROR(m_logger, "{} 初始化数据失败", m_logBase);
  51. return;
  52. }
  53. SPDLOG_LOGGER_INFO(m_logger, " ★ {} 计算一致性对比的线程开始运行 ", m_logBase);
  54. while(m_isRunning)
  55. {
  56. std::this_thread::sleep_for(std::chrono::milliseconds(20));
  57. /* 判断是否开启不一致检测 */
  58. if(m_isEnableNotConsistencyDetect.load() == false)
  59. {
  60. /* 不开启不一致检测,直接返回一致性结果 */
  61. m_roadResult.isConsistency = true;
  62. m_roadResult.isNotConsistencyWarning = false;
  63. continue; // 跳过后续的计算
  64. }
  65. /* 判断是否在检测时间段内 */
  66. if(m_isInDetectPeriod.load() == false)
  67. {
  68. /* 不在检测时间段内,不需要比对,结果一直为一致性 */
  69. m_roadResult.isConsistency = true;
  70. m_roadResult.isNotConsistencyWarning = false;
  71. /* 如果此时还在非一致性报警中,结束报警 */
  72. if(m_alarmConsistencyMain.isAlarm || m_alarmConsistencySub.isAlarm)
  73. {
  74. saveAlarmInfo();
  75. }
  76. continue;
  77. }
  78. /* 使用比对动态库比对一致性 */
  79. m_pConsistencyCompareThread->compareConsistencyData();
  80. /* 更新数据,更新音量数据和动态库比对的结果 */
  81. if(!updateData())
  82. {
  83. continue; // 数据不足,继续等待
  84. }
  85. // SPDLOG_LOGGER_INFO(m_logger, "{} 更新数据成功,开始计算音量数据", m_logBase);
  86. /* 计算音量数据 */
  87. calculateData();
  88. /* 保存结果,结果已经在上面那个函数中保存了 */
  89. /* 清除标志位 */
  90. m_isUpdated1 = false;
  91. m_isUpdated2 = false;
  92. }
  93. /* 结束报警,主要是为了停止报警录音 */
  94. endAlarm();
  95. /* 清理数据 */
  96. clearData();
  97. SPDLOG_LOGGER_WARN(m_logger, " ★ {} 计算双通道对比的线程结束 ", m_logBase);
  98. m_threadInfo.threadState = EThreadState::State_Stopped;
  99. }
  100. /* 初始化数据 */
  101. bool CompareDoubleThread::initData()
  102. {
  103. if(m_threadInfo.compareItemInfo.mapRoad.size() < 2)
  104. {
  105. SPDLOG_LOGGER_WARN(m_logger, "{} 对比项信息错误,录音通道数量小于2", m_threadInfo.compareItemInfo.strName.toStdString());
  106. return false;
  107. }
  108. m_isEnableNotConsistencyDetect = true; // 默认开启不一致检测
  109. /* 获取两个通道的信息 */
  110. auto it = m_threadInfo.compareItemInfo.mapRoad.begin();
  111. m_itemRoadInfo1 = it.value();
  112. m_roadInfo1 = it->scRoadInfo;
  113. it++; // 移动到下一个元素
  114. m_roadInfo2 = it->scRoadInfo; // 录音通道2信息
  115. m_itemRoadInfo2 = it.value();
  116. m_logBase = fmt::format("{} 对比项: {}:{} - {}:{}", m_threadInfo.compareItemInfo.strName.toStdString(),
  117. m_roadInfo1.strSoundCardName.toStdString(), m_roadInfo1.roadInfo.nRoadNum,
  118. m_roadInfo2.strSoundCardName.toStdString(), m_roadInfo2.roadInfo.nRoadNum);
  119. m_offsetMSeconds = GInfo.offsetMSeconds(); // 获取偏移量
  120. // m_calculateSeconds = GInfo.calculateDataSeconds(); // 获取计算需要的秒数
  121. m_avgDBCalculateSeconds = GInfo.avgDBCalculateSeconds(); // 获取计算平均音量所需要的时长
  122. m_silentThreshold = GInfo.silentThreshold(); // 获取静音阈值
  123. m_sinSeconds = GInfo.sinSeconds(); // 获取正弦波计算所需要的时长
  124. // m_isAINotConsistencyAlone = GInfo.isAINotConsistencyAlone(); // 获取杭州台是否按上面的逻辑来
  125. m_nIsSameBothMinDBWaitNum = GInfo.nIsSameBothMinDBWaitNum(); // 获取是否需要等待静音状态
  126. m_nCompareTimeSpan = GInfo.compareTimeSpan(); // 获取比对时间间隔
  127. /* 获取生成音量的线程,循环等待获取 */
  128. auto startTime = std::chrono::steady_clock::now(); // 记录开始时间
  129. while(true)
  130. {
  131. /* 获取创建音量包的线程 */
  132. if(m_threadCreateDB1 == nullptr)
  133. {
  134. m_threadCreateDB1 = ThreadMan.getCreateDBThread(m_roadInfo1.nSoundCardNum, m_roadInfo1.roadInfo.nRoadNum);
  135. }
  136. if(m_threadCreateDB2 == nullptr)
  137. {
  138. m_threadCreateDB2 = ThreadMan.getCreateDBThread(m_roadInfo2.nSoundCardNum, m_roadInfo2.roadInfo.nRoadNum);
  139. }
  140. /* 获取生成报警音频文件的线程 */
  141. if(m_threadCreateAlarmFile1 == nullptr)
  142. {
  143. m_threadCreateAlarmFile1 = ThreadMan.getCreateRecordFileThread(m_roadInfo1.nSoundCardNum, m_roadInfo1.roadInfo.nRoadNum);
  144. }
  145. if(m_threadCreateAlarmFile2 == nullptr)
  146. {
  147. m_threadCreateAlarmFile2 = ThreadMan.getCreateRecordFileThread(m_roadInfo2.nSoundCardNum, m_roadInfo2.roadInfo.nRoadNum);
  148. }
  149. if( m_threadCreateDB1 != nullptr && m_threadCreateDB2 != nullptr
  150. && m_threadCreateAlarmFile1 != nullptr && m_threadCreateAlarmFile2 != nullptr )
  151. {
  152. break; // 获取到两个线程,跳出循环
  153. }
  154. /* 超过10秒还没有获取到线程,返回失败 */
  155. if(std::chrono::steady_clock::now() - startTime > std::chrono::seconds(10))
  156. {
  157. return false;
  158. }
  159. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  160. }
  161. if(m_threadCreateDB1 == nullptr || m_threadCreateDB2 == nullptr)
  162. {
  163. SPDLOG_LOGGER_ERROR(m_logger, "{} 获取生成音量的线程失败", m_logBase);
  164. return false;
  165. }
  166. if(m_threadCreateAlarmFile1 == nullptr || m_threadCreateAlarmFile2 == nullptr)
  167. {
  168. SPDLOG_LOGGER_ERROR(m_logger, "{} 获取生成报警音频文件的线程失败", m_logBase);
  169. return false;
  170. }
  171. /* 创建一致性比较的线程,这里不再单独开线程了,合并到这个线程中执行 */
  172. m_pConsistencyCompareThread = new ConsistencyCompareThread(m_threadInfo);
  173. // if(m_pConsistencyCompareThread == nullptr)
  174. // {
  175. // SPDLOG_LOGGER_ERROR(m_logger, "{} 创建一致性比较线程失败", m_logBase);
  176. // return false;
  177. // }
  178. // CPPTP.add_task(&ConsistencyCompareThread::threadTask, m_pConsistencyCompareThread);
  179. /* 初始化对比功能 */
  180. m_pConsistencyCompareThread->initConsistencyCompare();
  181. return true;
  182. }
  183. /* 清理数据 */
  184. void CompareDoubleThread::clearData()
  185. {
  186. // if(m_pConsistencyCompareThread != nullptr)
  187. // {
  188. // m_pConsistencyCompareThread->stopThreadBlock(); // 停止线程
  189. // delete m_pConsistencyCompareThread;
  190. // m_pConsistencyCompareThread = nullptr;
  191. // }
  192. if(m_pConsistencyCompareThread != nullptr)
  193. {
  194. m_pConsistencyCompareThread->clearConsistencyCompareData();
  195. delete m_pConsistencyCompareThread;
  196. m_pConsistencyCompareThread = nullptr;
  197. }
  198. }
  199. /* 更新数据 */
  200. bool CompareDoubleThread::updateData()
  201. {
  202. /* 获取原始的音量值 */
  203. if(m_isUpdated1 == false)
  204. {
  205. if(m_threadCreateDB1->getLatestResult(m_localData1.ringQueue) == false)
  206. {
  207. // SPDLOG_LOGGER_TRACE(m_logger, "{} 未获取通道1最新数据", m_logBase);
  208. return false; // 没有获取到最新数据,继续等待
  209. }
  210. m_isUpdated1 = true;
  211. }
  212. if(m_isUpdated2 == false)
  213. {
  214. if(m_threadCreateDB2->getLatestResult(m_localData2.ringQueue) == false)
  215. {
  216. // SPDLOG_LOGGER_DEBUG(m_logger, "{} 未获取通道2最新数据", m_logBase);
  217. return false; // 没有获取到最新数据,继续等待
  218. }
  219. m_isUpdated2 = true;
  220. }
  221. if(m_isUpdated1 == false || m_isUpdated2 == false)
  222. {
  223. // SPDLOG_LOGGER_TRACE(m_logger, "{} 队列数据未更新,等待数据更新", m_logBase);
  224. return false;
  225. }
  226. if(m_localData1.isEmpty() || m_localData2.isEmpty())
  227. {
  228. SPDLOG_LOGGER_TRACE(m_logger, "{} 队列数据不足,等待数据更新", m_logBase);
  229. return false;
  230. }
  231. /* 获取一致性线程计算的结果 */
  232. // m_consistencyResult = m_pConsistencyCompareThread->getConsistencyResult();
  233. return true;
  234. }
  235. /**
  236. * 再次判断噪音和不一致
  237. *
  238. */
  239. void CompareDoubleThread::calculateData()
  240. {
  241. // 2、用最新数据计算音频状态:静音、过载、反相
  242. bool isAvgDBLessMin = false; /* 平均音量是否最小 */
  243. bool isSin1 = false; /* 通道1是否正弦波 */
  244. bool isSin2 = false; /* 通道2是否正弦波 */
  245. bool isSinDBEqual = false; /* 通道1和通道2的正弦波音量是否相等 */
  246. bool isOffsetSilence1 = false; /* 通道1偏移之后是否静音 */
  247. bool isOffsetSilence2 = false; /* 通道2偏移之后是否静音 */
  248. OneRoadVolume_t oneRoadVolume; /* 一个录音通道的音量信息,临时结果 */
  249. /* 保存通道2的时间 */
  250. oneRoadVolume.dateTime = m_localData2.ringQueue.back()->startTime;
  251. /* ---------------------------------------------------------------
  252. * 这一段计算音量偏移后的静音和正弦波(正弦波也是一种噪音,防止动态库检测不出来)
  253. * (正弦波结果貌似并没有用到)
  254. * ---------------------------------------------------------------*/
  255. {
  256. /* 获取偏移值 */
  257. long chn1Offset = 0;
  258. long chn2Offset = 0;
  259. calculateOffset(chn1Offset, chn2Offset);
  260. // 设置音频偏移
  261. m_localData1.setOffset(chn1Offset);
  262. m_localData2.setOffset(chn2Offset);
  263. // 计算偏移之后的静音
  264. int nSilentEndPos = 0, nSilentEndPos2 = 0;
  265. int nSilentStartPos = 0, nSilentStartPos2 = 0;
  266. isOffsetSilence1 = m_localData1.calculateSilent(m_volumeParam, m_avgDBCalculateSeconds, nSilentStartPos, nSilentEndPos);
  267. isOffsetSilence2 = m_localData2.calculateSilent(m_volumeParam, m_avgDBCalculateSeconds, nSilentStartPos2, nSilentEndPos2);
  268. isAvgDBLessMin = m_localData1.isAvgDBLessThan(m_avgDBCalculateSeconds, m_silentThreshold) && m_localData2.isAvgDBLessThan(m_avgDBCalculateSeconds, m_silentThreshold);
  269. // 音量小时不用判定正弦波
  270. if (!isAvgDBLessMin)
  271. {
  272. // 正弦波处理:正弦波就是一个固定的音量值,这时不做判定,直接比较音量值
  273. // (主次通道的音量值相同,并且是一个固定的音量值时,直接判定为一致)
  274. int nLeftDB1, nRightDB1;
  275. isSin1 = m_localData1.isSinDB(m_sinSeconds, m_avgDBCalculateSeconds, nLeftDB1, nRightDB1);
  276. int nLeftDB2, nRightDB2;
  277. isSin2 = m_localData2.isSinDB(m_sinSeconds, m_avgDBCalculateSeconds, nLeftDB2, nRightDB2);
  278. if (nLeftDB1 == nLeftDB2 && nRightDB1 == nRightDB2)
  279. {
  280. isSinDBEqual = true;
  281. }
  282. }
  283. /* 恢复音频偏移,下面也没有用到这两个环形队列的地方了,所以提到前面恢复 */
  284. m_localData1.setOffset(0);
  285. m_localData2.setOffset(0);
  286. /* 这里貌似也没用到 */
  287. // m_data1 = m_localData1;
  288. // m_data2 = m_localData2;
  289. }
  290. /* ---------------------------------------------------------------
  291. * 和动态库检测的一致性结果进行对比
  292. * ---------------------------------------------------------------*/
  293. {
  294. getLatestConsistencyStatus(oneRoadVolume);
  295. }
  296. if (isOffsetSilence1 && isOffsetSilence2)
  297. {
  298. m_bBothMinDB = ESW_BothMute_TRUE;
  299. } else
  300. {
  301. if (isAvgDBLessMin)
  302. {
  303. m_bBothMinDB = ESW_BothMinDB_TRUE;
  304. } else
  305. {
  306. if (isOffsetSilence1 || isOffsetSilence2)
  307. {
  308. m_bBothMinDB = ESW_OneMinDB_FALSE;
  309. } else
  310. {
  311. m_bBothMinDB = ESW_ALL_NOT;
  312. }
  313. }
  314. m_isSin1 = isSin1;
  315. m_isSin2 = isSin2;
  316. m_isSinDBEqual = isSinDBEqual;
  317. }
  318. /* ---------------------------------------------------------------
  319. * 保存计算信息,目前只保存了一致性结果和报警
  320. * ---------------------------------------------------------------*/
  321. {
  322. std::lock_guard<std::mutex> lock(m_mutexVolumeInfo);
  323. /* 保存一致性结果 */
  324. m_roadResult.isConsistency = oneRoadVolume.isConsistency;
  325. m_roadResult.isNotConsistencyWarning = oneRoadVolume.isNotConsistencyWarning;
  326. m_roadResult.dateTime = oneRoadVolume.dateTime;
  327. /* 保存报警信息 */
  328. saveAlarmInfo();
  329. }
  330. }
  331. /* 计算偏移值 */
  332. void CompareDoubleThread::calculateOffset(long chn1Offset, long chn2Offset)
  333. {
  334. chn1Offset = 0;
  335. chn2Offset = 0;
  336. if(m_offsetMSeconds > 0)
  337. {
  338. chn1Offset = m_offsetMSeconds;
  339. } else if(m_offsetMSeconds < 0) {
  340. chn2Offset = std::abs(m_offsetMSeconds);
  341. }
  342. }
  343. /**
  344. * @brief 获取最新的一致性状态
  345. * 1、先使用音量进行静音比对,都不是静音时,使用AI对比
  346. * 2、是否使用AI对比由外部传入的配置决定
  347. *
  348. * @param sendInfo
  349. * @return true
  350. * @return false
  351. */
  352. bool CompareDoubleThread::getLatestConsistencyStatus(OneRoadVolume_t& oneRoad)
  353. {
  354. // 非对比时间时,默认为一致
  355. // if (!m_isCompareTime)
  356. // {
  357. // initMiniArray();
  358. // // SPDLOG_LOGGER_DEBUG(m_logger, "{}: 非对比时间时,默认为一致", m_chnName);
  359. // oneRoad.isConsistency = true;
  360. // return true;
  361. // }
  362. /* 使用Python对比的结果,这里没有这个功能 */
  363. /* 如果没有开启比较线程,默认为一致 */
  364. // if (!m_isRunCompareThread)
  365. // {
  366. // oneRoad.isConsistency = true;
  367. // SPDLOG_LOGGER_INFO(m_logger, "{}: 没有开启比较线程,默认为一致", m_chnName);
  368. // return true;
  369. // }
  370. /* 不做一致性检测,返回一致性 */
  371. // if (!m_consistencyParam.GetConsistencySwitch())
  372. // {
  373. // SPDLOG_LOGGER_INFO(m_logger, "{}: 一致性检测关闭,不做一致性检测,返回一致性", m_chnName);
  374. // oneRoad.isConsistency = true;
  375. // return true;
  376. // }
  377. /* 判断是否开启计算这两个通道音量值的线程
  378. * 如果两个线程都在不在运行,无法判断,则设置成一致,一个在运行一个不在运行,则不一致
  379. * */
  380. // if(!m_isRunCalDB1Thread && !m_isRunCalDB2Thread)
  381. // {
  382. // oneRoad.isConsistency = true;
  383. // SPDLOG_LOGGER_INFO(m_logger, "{}: 通道指针为空,默认为一致", m_chnName);
  384. // return true;
  385. // }
  386. // // 一个为空,一个不空判定为不一致
  387. // if (m_isRunCalDB1Thread != m_isRunCalDB2Thread)
  388. // {
  389. // oneRoad.isConsistency = false;
  390. // SPDLOG_LOGGER_INFO(m_logger, "{}: 一个通道正在运行计算音量的线程,一个通道未在运行,判定为不一致", m_chnName);
  391. // return false;
  392. // }
  393. /* 上一次的一致性标记 */
  394. m_mutexVolumeInfo.lock();
  395. const bool lastConsistency = m_roadResult.isConsistency;
  396. m_mutexVolumeInfo.unlock();
  397. bool bConsistency = lastConsistency;
  398. // if (!m_isRunCompareThread)
  399. // {
  400. // /* 没有开启比对线程 */
  401. // bConsistency = false;
  402. // if(m_recordDev1ID == m_recordDev2ID)
  403. // {
  404. // // 同一个通道肯定是一致的
  405. // bConsistency = true;
  406. // SPDLOG_LOGGER_INFO(m_logger, "同一个通道肯定是一致的");
  407. // }
  408. // }
  409. // else if(!m_isRunCalDB1Thread && !m_isRunCalDB2Thread)
  410. // {
  411. // // 都没有开启,表示两者是静音
  412. // bConsistency = true;
  413. // SPDLOG_LOGGER_INFO(m_logger, "都没有开启,表示两者是静音");
  414. // }
  415. // else if(m_isRunCalDB1Thread != m_isRunCalDB2Thread)
  416. // {
  417. // // 一个开启了,一个没有开启,表示不一致
  418. // bConsistency = false;
  419. // SPDLOG_LOGGER_INFO(m_logger, "一个开启了,一个没有开启,表示不一致");
  420. // }else
  421. {
  422. /* 都开启了计算音量的线程 */
  423. /* 获取上一次的低音量信息 */
  424. int bBothMinDB = m_bBothMinDB;
  425. addBothMiniDB(bBothMinDB);
  426. /*************************************************************
  427. * 金海林加入
  428. * 时间: 2023年8月30日 16:09:25
  429. * 描述: 杭州台:在其它报警时,不一致不报警且后台不进行不一致比对,在其它报警恢复后,不一致重新计时比对
  430. if (ESW_ALL_NOT != bBothMinDB)
  431. *************************************************************/
  432. /* m_isAINotConsistencyAlone 是外部的配置选项 */
  433. // if (ESW_ALL_NOT != bBothMinDB && !m_isAINotConsistencyAlone)
  434. if(ESW_ALL_NOT != bBothMinDB)
  435. /**********金海林加入结束*************/
  436. {
  437. if (ESW_BothMinDB_TRUE == bBothMinDB)
  438. {
  439. SPDLOG_LOGGER_INFO(m_logger, "{}: 平均音量比较小时,维持当前状态不变!", m_chnName);
  440. }
  441. else if (ESW_BothMute_TRUE == bBothMinDB)
  442. {
  443. /*************************************************************
  444. * 金海林加入
  445. * 时间: 2022年4月6日 10:58:19
  446. * 描述: 静音判断可能存在时间偏移,所有要多等待一次对比
  447. *************************************************************/
  448. if (isSameBothMinDB(ESW_BothMute_TRUE))
  449. {
  450. SPDLOG_LOGGER_INFO(m_logger, "{}: 两个都是静音,判定为一致!", m_chnName);
  451. bConsistency = true;
  452. }
  453. else
  454. {
  455. SPDLOG_LOGGER_INFO(m_logger, "{}: 两个都是静音,前3次维持当前状态不变!", m_chnName);
  456. //bConsistency = FALSE;
  457. }
  458. /**********金海林加入结束*************/
  459. }
  460. else
  461. {
  462. /* 一个静音,一个非静音 */
  463. /*************************************************************
  464. * 金海林修改
  465. * 时间: 2018年11月2日 14:31:34
  466. * 描述: 一个静音一个非静音,第一次维持不一致状态不变;第二次直接判定位不一致
  467. *************************************************************/
  468. if (isSameBothMinDB(ESW_OneMinDB_FALSE))
  469. {
  470. SPDLOG_LOGGER_INFO(m_logger, "{}: 一个静音一个非静音,上次也是这样,直接判定为不一致!", m_chnName);
  471. bConsistency = false;
  472. }
  473. else
  474. {
  475. SPDLOG_LOGGER_INFO(m_logger, "{}: 一个静音一个非静音,前3次维持当前状态不变!", m_chnName);
  476. //bConsistency = false;
  477. }
  478. /**********金海林修改结束*************/
  479. }
  480. }
  481. else
  482. {
  483. /* 两个都是静音,进一步进行一致性比较 */
  484. /*************************************************************
  485. * 金海林加入
  486. * 时间: 2022年3月31日 16:04:30
  487. * 描述: 开启基础(静音正弦波判断)和AI对比
  488. *************************************************************/
  489. compareConsistencyBaseOnAI(bConsistency, lastConsistency);
  490. /**********金海林加入结束*************/
  491. std::string strMsgLog;
  492. if (bConsistency)
  493. {
  494. if (oneRoad.isNotConsistencyWarning == true)
  495. {
  496. strMsgLog = fmt::format("{}:预警【一致】:{}", m_logBase, m_chnName);
  497. }
  498. else
  499. {
  500. strMsgLog = fmt::format("{}:是一致:{}", m_logBase, m_chnName);
  501. }
  502. }
  503. else
  504. {
  505. strMsgLog = fmt::format("{}:不一致:{}", m_logBase, m_chnName);
  506. }
  507. SPDLOG_LOGGER_DEBUG(m_logger, strMsgLog);
  508. }
  509. }
  510. return true;
  511. }
  512. /* 基础静音判断和AI(这里是调用的动态库)判断进行对比 */
  513. bool CompareDoubleThread::compareConsistencyBaseOnAI(bool& bConsistency, const bool lastConsistency)
  514. {
  515. /*************************************************************
  516. * 金海林加入
  517. * 时间: 2023年8月30日 16:09:25
  518. * 描述: 杭州台:在其它报警时,不一致不报警且后台不进行不一致比对,在其它报警恢复后,不一致重新计时比对
  519. *************************************************************/
  520. // if (m_isHasAlarmExecpt)
  521. // {
  522. // bConsistency = true;
  523. // return false;
  524. // }
  525. /**********金海林加入结束*************/
  526. /* 更新动态库的一致性比对结果,计算结果 */
  527. std::string strAIValue, strAIValueNot;
  528. bool bAICon = m_consistencyResult.IsAIConsistency(GInfo.AICMPThresholdNum(), GInfo.AICMPThreshold(), strAIValue);
  529. bool bAINot = m_consistencyResult.IsAINotConsistency(GInfo.AICMPThresholdNum(), GInfo.AICMPThresholdNot(), strAIValueNot);
  530. if (false == bAICon || false == bAINot)
  531. {
  532. bConsistency = true;
  533. return false;
  534. }
  535. if (bAICon)
  536. {
  537. bConsistency = true;
  538. if (!lastConsistency)
  539. {
  540. SPDLOG_LOGGER_INFO(m_logger, "当前AI判定为一致,上次是不一致,确认为一致(第{}次),{}", ++m_arryAIChangeRetNum[1], strAIValue);
  541. }
  542. return true;
  543. }
  544. if (bAINot)
  545. {
  546. bConsistency = false;
  547. if (lastConsistency)
  548. {
  549. SPDLOG_LOGGER_INFO(m_logger, "当前AI判定为不一致,上次是一致,确认为不一致(第{}次),{}", ++m_arryAIChangeRetNum[3], strAIValueNot);
  550. }
  551. return true;
  552. }
  553. bConsistency = lastConsistency; // 如果都不是一致和不一致,则使用上一次的一致性结果
  554. return true;
  555. }
  556. /* 初始化低音量数组 */
  557. void CompareDoubleThread::initMiniArray()
  558. {
  559. for(auto& data : m_arrayMiniDB)
  560. {
  561. data = -1;
  562. }
  563. }
  564. /* 向低音量数组添加数字 */
  565. int CompareDoubleThread::addBothMiniDB(int db)
  566. {
  567. for(int i = 8; i >= 0; --i)
  568. {
  569. m_arrayMiniDB[i+1] = m_arrayMiniDB[i];
  570. }
  571. m_arrayMiniDB[0] = db;
  572. if (ESW_ALL_NOT == db)
  573. {
  574. }
  575. if (ESW_BothMinDB_TRUE == db)
  576. {
  577. SPDLOG_LOGGER_DEBUG(m_logger, "{}: 两个都是声音小,连续{}秒平均音量小于[{}]", m_chnName, m_avgDBCalculateSeconds, m_silentThreshold);
  578. SPDLOG_LOGGER_DEBUG(m_logger, "{}: 记录当前状态:两个都是声音小,连续{}秒平均音量小于[{}]", m_chnName, m_avgDBCalculateSeconds, m_silentThreshold);
  579. }
  580. if (ESW_BothMute_TRUE == db)
  581. {
  582. SPDLOG_LOGGER_DEBUG(m_logger, "{}: 两个静音({})", m_chnName, db);
  583. }
  584. if (ESW_OneMinDB_FALSE == db)
  585. {
  586. SPDLOG_LOGGER_DEBUG(m_logger, "{}: 一个静音一个非静音({})", m_chnName, db);
  587. }
  588. return 10;
  589. }
  590. /**
  591. * @brief 两个低音量是否相似
  592. *
  593. * @param db
  594. * @return true
  595. * @return false
  596. */
  597. bool CompareDoubleThread::isSameBothMinDB(int db)
  598. {
  599. bool bSame = true;
  600. int nThresholdNum = m_nIsSameBothMinDBWaitNum; //是否静音要等待3秒,因为音频有延时
  601. if (nThresholdNum < 0) nThresholdNum = 1;
  602. if (nThresholdNum > 10) nThresholdNum = 10;
  603. for(int i = 0; i < nThresholdNum; ++i)
  604. {
  605. if (db != m_arrayMiniDB[i])
  606. {
  607. bSame = false;
  608. break;
  609. }
  610. }
  611. return bSame;
  612. }
  613. /* 保存报警信息 */
  614. void CompareDoubleThread::saveAlarmInfo()
  615. {
  616. if(m_roadResult.isConsistency)
  617. {
  618. /* 这次是一致的,判断之前是否在一致性报警中 */
  619. if(m_alarmConsistencyMain.isAlarm || m_alarmConsistencySub.isAlarm)
  620. {
  621. /* 之前在一致性报警中,这次一致,结束不一致性报警 */
  622. m_alarmConsistencyMain.isAlarm = false;
  623. m_alarmConsistencySub.isAlarm = false;
  624. /* 结束时间向前推1秒 */
  625. m_alarmConsistencyMain.EndTime = m_localData1.ringQueue.back()->endTime.addSecs(1);
  626. m_alarmConsistencySub.EndTime = m_localData2.ringQueue.back()->endTime.addSecs(1);
  627. /* 结束录制报警音频 */
  628. m_threadCreateAlarmFile1->stopRecordAlarmFile(m_alarmConsistencyMain);
  629. m_threadCreateAlarmFile2->stopRecordAlarmFile(m_alarmConsistencySub);
  630. /* 将报警信息写入数据库 */
  631. AlarmManager.addAlarmInfo(m_alarmConsistencyMain);
  632. AlarmManager.addAlarmInfo(m_alarmConsistencySub);
  633. SPDLOG_LOGGER_INFO(m_logger, "{}: 一致性报警结束", m_logBase);
  634. /* 清除报警信息 */
  635. m_alarmConsistencyMain = AlarmInfo_t();
  636. m_alarmConsistencySub = AlarmInfo_t();
  637. }
  638. }else
  639. {
  640. /* 不一致,判断之前的一致性,判断一个就可以了 */
  641. if(!m_alarmConsistencySub.isAlarm)
  642. {
  643. /* 开是不一致报警 */
  644. m_alarmConsistencyMain.isAlarm = true;
  645. m_alarmConsistencySub.isAlarm = true;
  646. m_alarmConsistencyMain.CompareItemID = m_threadInfo.compareItemInfo.nID;
  647. m_alarmConsistencySub.CompareItemID = m_threadInfo.compareItemInfo.nID;
  648. m_alarmConsistencyMain.strCompareItemName = m_threadInfo.compareItemInfo.strName.toStdString();
  649. m_alarmConsistencySub.strCompareItemName = m_threadInfo.compareItemInfo.strName.toStdString();
  650. m_alarmConsistencyMain.RoadInfo = m_itemRoadInfo1;
  651. m_alarmConsistencySub.RoadInfo = m_itemRoadInfo2;
  652. m_alarmConsistencyMain.AlarmType = EAlarmType::EAR_Consistency;
  653. m_alarmConsistencySub.AlarmType = EAlarmType::EAR_Consistency;
  654. /* 计算开始时间 */
  655. int seconds = m_consistencyParam.GetConsistencyThresholdNotNum() * (m_nCompareTimeSpan / 1000);
  656. int pos1 = m_localData1.ringQueue.QueueSize() - seconds - 1;
  657. int pos2 = m_localData2.ringQueue.QueueSize() - seconds - 1;
  658. m_alarmConsistencyMain.StartTime = m_localData1.ringQueue[pos1]->startTime;
  659. m_alarmConsistencySub.StartTime = m_localData2.ringQueue[pos2]->startTime;
  660. SPDLOG_LOGGER_WARN(m_logger, "{}: 不一致报警开始", m_logBase);
  661. m_threadCreateAlarmFile1->startRecordAlarmFile(m_alarmConsistencyMain);
  662. m_threadCreateAlarmFile2->startRecordAlarmFile(m_alarmConsistencySub);
  663. }
  664. }
  665. }
  666. /* 结束报警 */
  667. void CompareDoubleThread::endAlarm()
  668. {
  669. m_roadResult.isConsistency = true;
  670. /* 这次是一致的,判断之前是否在一致性报警中 */
  671. if(m_alarmConsistencyMain.isAlarm || m_alarmConsistencySub.isAlarm)
  672. {
  673. /* 之前在一致性报警中,这次一致,结束不一致性报警 */
  674. m_alarmConsistencyMain.isAlarm = false;
  675. m_alarmConsistencySub.isAlarm = false;
  676. /* 结束时间向前推1秒 */
  677. m_alarmConsistencyMain.EndTime = m_localData1.ringQueue.back()->endTime.addSecs(1);
  678. m_alarmConsistencySub.EndTime = m_localData2.ringQueue.back()->endTime.addSecs(1);
  679. /* 结束录制报警音频 */
  680. m_threadCreateAlarmFile1->stopRecordAlarmFile(m_alarmConsistencyMain);
  681. m_threadCreateAlarmFile2->stopRecordAlarmFile(m_alarmConsistencySub);
  682. /* 将报警信息写入数据库 */
  683. AlarmManager.addAlarmInfo(m_alarmConsistencyMain);
  684. AlarmManager.addAlarmInfo(m_alarmConsistencySub);
  685. SPDLOG_LOGGER_INFO(m_logger, "{}: 一致性报警结束", m_logBase);
  686. /* 清除报警信息 */
  687. m_alarmConsistencyMain = AlarmInfo_t();
  688. m_alarmConsistencySub = AlarmInfo_t();
  689. }
  690. }