ConsistencyCompareThread.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #include "ConsistencyCompareThread.h"
  2. #include "GlobalVariable.h"
  3. #include "ThreadManager.h"
  4. #include "CreateWAVThread.h"
  5. #include "LHCompareAPI.h"
  6. ConsistencyCompareThread::ConsistencyCompareThread(CalculateThreadInfo_t& threadInfo)
  7. : BaseCalculateThread(threadInfo)
  8. {
  9. }
  10. ConsistencyCompareThread::~ConsistencyCompareThread()
  11. {
  12. }
  13. /* 获取一致性比对的结果 */
  14. StConsistencyResult ConsistencyCompareThread::getConsistencyResult()
  15. {
  16. std::lock_guard<std::mutex> lock(m_mutexResult);
  17. return m_consistencyResult;
  18. }
  19. /* 判断录音通道是否相等 */
  20. bool ConsistencyCompareThread::isRoadEqual(const SoundCardRoadInfo_t& roadInfo1, const SoundCardRoadInfo_t& roadInfo2)
  21. {
  22. /* r1对比m_r1,r2对比M_r2 */
  23. if( roadInfo1.nSoundCardNum == m_roadInfo1.nSoundCardNum && roadInfo1.roadInfo.nRoadNum == m_roadInfo1.roadInfo.nRoadNum &&
  24. roadInfo2.nSoundCardNum == m_roadInfo2.nSoundCardNum && roadInfo2.roadInfo.nRoadNum == m_roadInfo2.roadInfo.nRoadNum )
  25. {
  26. return true;
  27. }
  28. /* 反过来对比一下 */
  29. if( roadInfo1.nSoundCardNum == m_roadInfo2.nSoundCardNum && roadInfo1.roadInfo.nRoadNum == m_roadInfo2.roadInfo.nRoadNum &&
  30. roadInfo2.nSoundCardNum == m_roadInfo1.nSoundCardNum && roadInfo2.roadInfo.nRoadNum == m_roadInfo1.roadInfo.nRoadNum )
  31. {
  32. return true;
  33. }
  34. return false;
  35. }
  36. /* 初始化 */
  37. bool ConsistencyCompareThread::initConsistencyCompare()
  38. {
  39. /* 初始化数据 */
  40. if(!initData())
  41. {
  42. SPDLOG_LOGGER_ERROR(m_logger, "{} 初始化数据失败", m_logBase);
  43. return false;
  44. }
  45. SPDLOG_LOGGER_INFO(m_logger, " ★ {} 一致性对比功能(调用动态库)初始化完成 ", m_logBase);
  46. return true;
  47. }
  48. /* 比对函数 */
  49. bool ConsistencyCompareThread::compareConsistencyData()
  50. {
  51. /*--------------------------------------------------------------
  52. * 更新最新数据
  53. *--------------------------------------------------------------*/
  54. m_pCreateWAVThread1->getLatestFileName(m_wavFilePath1);
  55. m_pCreateWAVThread2->getLatestFileName(m_wavFilePath2);
  56. /* 检查是否有新的数据 */
  57. if(m_wavFilePath1 == m_prevWavFilePath1 || m_wavFilePath2 == m_prevWavFilePath2)
  58. {
  59. // SPDLOG_LOGGER_INFO(m_logger, "{} 检测到文件路径未变化", m_logBase);
  60. return true;
  61. }
  62. /*--------------------------------------------------------------
  63. * 开始比对计算,并保存计算结果
  64. *--------------------------------------------------------------*/
  65. if(!compareConsistency())
  66. {
  67. return false;
  68. }
  69. m_prevWavFilePath1 = m_wavFilePath1; // 更新上一个wav文件路径
  70. m_prevWavFilePath2 = m_wavFilePath2; // 更新上一个wav文件路径
  71. return true;
  72. }
  73. /* 清理数据 */
  74. void ConsistencyCompareThread::clearConsistencyCompareData()
  75. {
  76. clearData();
  77. SPDLOG_LOGGER_INFO(m_logger, " ★ {} 一致性对比功能(调用动态库)清理完成 ", m_logBase);
  78. }
  79. /* 线程功能函数 */
  80. void ConsistencyCompareThread::task()
  81. {
  82. m_isRunning = true;
  83. /* 初始化 */
  84. if(!initData())
  85. {
  86. SPDLOG_LOGGER_ERROR(m_logger, "{} 初始化数据失败", m_logBase);
  87. return;
  88. }
  89. SPDLOG_LOGGER_INFO(m_logger, " ★ {} 一致性对比线程(调用动态库)开始运行 ", m_logBase);
  90. while(m_isRunning)
  91. {
  92. std::this_thread::sleep_for(std::chrono::milliseconds(100));
  93. /*--------------------------------------------------------------
  94. * 更新最新数据
  95. *--------------------------------------------------------------*/
  96. m_pCreateWAVThread1->getLatestFileName(m_wavFilePath1);
  97. m_pCreateWAVThread2->getLatestFileName(m_wavFilePath2);
  98. /* 检查是否有新的数据 */
  99. if(m_wavFilePath1 == m_prevWavFilePath1 || m_wavFilePath2 == m_prevWavFilePath2)
  100. {
  101. // SPDLOG_LOGGER_INFO(m_logger, "{} 检测到文件路径未变化", m_logBase);
  102. continue;
  103. }
  104. /*--------------------------------------------------------------
  105. * 开始比对计算,并保存计算结果
  106. *--------------------------------------------------------------*/
  107. if(!compareConsistency())
  108. {
  109. continue;
  110. }
  111. m_prevWavFilePath1 = m_wavFilePath1; // 更新上一个wav文件路径
  112. m_prevWavFilePath2 = m_wavFilePath2; // 更新上一个wav文件路径
  113. }
  114. clearData();
  115. SPDLOG_LOGGER_WARN(m_logger, " ★ {} 一致性对比线程(调用动态库)已结束运行 ", m_logBase);
  116. }
  117. /* 初始化数据 */
  118. bool ConsistencyCompareThread::initData()
  119. {
  120. if(m_threadInfo.compareItemInfo.mapRoad.size() < 2)
  121. {
  122. SPDLOG_LOGGER_ERROR(m_logger, "{} 录音通道信息不足,至少需要两个通道", m_logBase);
  123. return false;
  124. }
  125. /* 获取两个录音通道的信息 */
  126. auto it = m_threadInfo.compareItemInfo.mapRoad.begin();
  127. m_roadInfo1 = it.value().scRoadInfo; // 第一个通道
  128. it++;
  129. m_roadInfo2 = it.value().scRoadInfo; // 第二个通道
  130. m_logBase = fmt::format("对比通道 {}:{} - {}:{}",
  131. m_roadInfo1.strSoundCardName.toStdString(), m_roadInfo1.roadInfo.nRoadNum,
  132. m_roadInfo2.strSoundCardName.toStdString(), m_roadInfo2.roadInfo.nRoadNum);
  133. /* 获取创建wav文件的指针 */
  134. auto startTime = std::chrono::steady_clock::now(); // 记录开始时间
  135. while(true)
  136. {
  137. if(m_pCreateWAVThread1 == nullptr)
  138. {
  139. m_pCreateWAVThread1 = ThreadMan.getCreateWAVThread(m_roadInfo1.nSoundCardNum, m_roadInfo1.roadInfo.nRoadNum);
  140. }
  141. if(m_pCreateWAVThread2 == nullptr)
  142. {
  143. m_pCreateWAVThread2 = ThreadMan.getCreateWAVThread(m_roadInfo2.nSoundCardNum, m_roadInfo2.roadInfo.nRoadNum);
  144. }
  145. if(m_pCreateWAVThread1 != nullptr && m_pCreateWAVThread2 != nullptr)
  146. {
  147. break; // 获取到两个线程,跳出循环
  148. }
  149. /* 超过10秒还没有获取到线程,返回失败 */
  150. if(std::chrono::steady_clock::now() - startTime > std::chrono::seconds(10))
  151. {
  152. SPDLOG_LOGGER_ERROR(m_logger, "{} 获取生成音量的线程超时", m_logBase);
  153. return false;
  154. }
  155. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  156. }
  157. if(m_pCreateWAVThread1 == nullptr || m_pCreateWAVThread2 == nullptr)
  158. {
  159. SPDLOG_LOGGER_ERROR(m_logger, "{} 获取录音线程失败", m_logBase);
  160. return false;
  161. }
  162. return true;
  163. }
  164. /* 清理数据 */
  165. void ConsistencyCompareThread::clearData()
  166. {
  167. m_isRunning = false;
  168. m_pCreateWAVThread1 = nullptr;
  169. m_pCreateWAVThread2 = nullptr;
  170. /* 设置标志位 */
  171. m_isRunning = false;
  172. m_isStop.store(true);
  173. m_threadInfo.threadState = EThreadState::State_Stopped;
  174. }
  175. /* 比对两个wav文件的一致性 */
  176. bool ConsistencyCompareThread::compareConsistency()
  177. {
  178. /* 计算比对需要的时间 */
  179. std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
  180. CompareResult* result = LHCompare(m_wavFilePath1.fileName.c_str(), m_wavFilePath2.fileName.c_str(), m_sensitivity);
  181. if(result == nullptr)
  182. {
  183. SPDLOG_LOGGER_ERROR(m_logger, "{} 一致性比对失败,可能是文件格式不支持或动态库加载失败", m_logBase);
  184. return false;
  185. }
  186. /* 计算比对耗时 */
  187. std::chrono::steady_clock::time_point endTime = std::chrono::steady_clock::now();
  188. std::chrono::duration<double> duration = endTime - startTime;
  189. SPDLOG_LOGGER_DEBUG(m_logger, "{} 一致性比对耗时: {}ms", m_logBase,
  190. std::chrono::duration_cast<std::chrono::milliseconds>(duration).count());
  191. /* 如果高相似度小于1,将两个通道反过来对比一下 */
  192. if(result->highest_similarity < 1)
  193. {
  194. delete result;
  195. result = nullptr;
  196. SPDLOG_LOGGER_WARN(m_logger, "{} 高相似度小于1,尝试反向对比", m_logBase);
  197. result = LHCompare(m_wavFilePath2.fileName.c_str(), m_wavFilePath1.fileName.c_str(), m_sensitivity);
  198. if(result == nullptr)
  199. {
  200. SPDLOG_LOGGER_ERROR(m_logger, "{} 一致性比对失败,可能是文件格式不支持或动态库加载失败", m_logBase);
  201. return false;
  202. }
  203. }
  204. // SPDLOG_LOGGER_DEBUG(m_logger, "{} 一致性比对结果: 源文件: {}, 目标文件: {}, 最高相似度: {:.3f}, 平均相似度: {:.3f}",
  205. // m_logBase, m_wavFilePath1.fileName, m_wavFilePath2.fileName, result->highest_similarity, result->average_similarity);
  206. /* 保存结果 */
  207. m_mutexResult.lock();
  208. m_consistencyResult.AddRetAICompareFile(result->highest_similarity / 100.0);
  209. m_mutexResult.unlock();
  210. delete result;
  211. result = nullptr;
  212. return true;
  213. }