#include "ConsistencyCompareThread.h" #include "ThreadManager.h" #include "CreateWAVThread.h" #include "LHCompareAPI.h" ConsistencyCompareThread::ConsistencyCompareThread(CalculateThreadInfo_t& threadInfo) : BaseCalculateThread(threadInfo) { } ConsistencyCompareThread::~ConsistencyCompareThread() { } /* 获取一致性比对的结果 */ StConsistencyResult ConsistencyCompareThread::getConsistencyResult() { std::lock_guard lock(m_mutexResult); return m_consistencyResult; } /* 判断录音通道是否相等 */ bool ConsistencyCompareThread::isRoadEqual(const SoundCardRoadInfo_t& roadInfo1, const SoundCardRoadInfo_t& roadInfo2) { /* r1对比m_r1,r2对比M_r2 */ if( roadInfo1.nSoundCardNum == m_roadInfo1.nSoundCardNum && roadInfo1.roadInfo.nRoadNum == m_roadInfo1.roadInfo.nRoadNum && roadInfo2.nSoundCardNum == m_roadInfo2.nSoundCardNum && roadInfo2.roadInfo.nRoadNum == m_roadInfo2.roadInfo.nRoadNum ) { return true; } /* 反过来对比一下 */ if( roadInfo1.nSoundCardNum == m_roadInfo2.nSoundCardNum && roadInfo1.roadInfo.nRoadNum == m_roadInfo2.roadInfo.nRoadNum && roadInfo2.nSoundCardNum == m_roadInfo1.nSoundCardNum && roadInfo2.roadInfo.nRoadNum == m_roadInfo1.roadInfo.nRoadNum ) { return true; } return false; } /* 线程功能函数 */ void ConsistencyCompareThread::task() { m_isRunning = true; /* 初始化 */ if(!initData()) { SPDLOG_LOGGER_ERROR(m_logger, "{} 初始化数据失败", m_logBase); return; } SPDLOG_LOGGER_INFO(m_logger, "******************* {} 一致性对比线程(调用动态库)开始运行 ******************* ", m_logBase); while(m_isRunning) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); /*-------------------------------------------------------------- * 更新最新数据 *--------------------------------------------------------------*/ m_pCreateWAVThread1->getLatestFileName(m_wavFilePath1); m_pCreateWAVThread2->getLatestFileName(m_wavFilePath2); /* 检查是否有新的数据 */ if(m_wavFilePath1 == m_prevWavFilePath1 || m_wavFilePath2 == m_prevWavFilePath2) { // SPDLOG_LOGGER_INFO(m_logger, "{} 检测到文件路径未变化", m_logBase); continue; } /*-------------------------------------------------------------- * 开始比对计算,并保存计算结果 *--------------------------------------------------------------*/ if(!compareConsistency()) { continue; } m_prevWavFilePath1 = m_wavFilePath1; // 更新上一个wav文件路径 m_prevWavFilePath2 = m_wavFilePath2; // 更新上一个wav文件路径 } clearData(); SPDLOG_LOGGER_INFO(m_logger, " ******************* {} 一致性对比线程(调用动态库)已结束运行 ******************* ", m_logBase); } /* 初始化数据 */ bool ConsistencyCompareThread::initData() { if(m_threadInfo.compareItemInfo.mapRoad.size() < 2) { SPDLOG_LOGGER_ERROR(m_logger, "{} 录音通道信息不足,至少需要两个通道", m_logBase); return false; } /* 获取两个录音通道的信息 */ auto it = m_threadInfo.compareItemInfo.mapRoad.begin(); m_roadInfo1 = it.value().scRoadInfo; // 第一个通道 it++; m_roadInfo2 = it.value().scRoadInfo; // 第二个通道 m_logBase = fmt::format("对比通道 {}:{} - {}:{}", m_roadInfo1.strSoundCardName.toStdString(), m_roadInfo1.roadInfo.nRoadNum, m_roadInfo2.strSoundCardName.toStdString(), m_roadInfo2.roadInfo.nRoadNum); /* 获取创建wav文件的指针 */ auto startTime = std::chrono::steady_clock::now(); // 记录开始时间 while(true) { if(m_pCreateWAVThread1 == nullptr) { m_pCreateWAVThread1 = ThreadMan.getCreateWAVThread(m_roadInfo1.nSoundCardNum, m_roadInfo1.roadInfo.nRoadNum); } if(m_pCreateWAVThread2 == nullptr) { m_pCreateWAVThread2 = ThreadMan.getCreateWAVThread(m_roadInfo2.nSoundCardNum, m_roadInfo2.roadInfo.nRoadNum); } if(m_pCreateWAVThread1 != nullptr && m_pCreateWAVThread2 != nullptr) { break; // 获取到两个线程,跳出循环 } /* 超过10秒还没有获取到线程,返回失败 */ if(std::chrono::steady_clock::now() - startTime > std::chrono::seconds(10)) { SPDLOG_LOGGER_ERROR(m_logger, "{} 获取生成音量的线程超时", m_logBase); return false; } std::this_thread::sleep_for(std::chrono::milliseconds(10)); } if(m_pCreateWAVThread1 == nullptr || m_pCreateWAVThread2 == nullptr) { SPDLOG_LOGGER_ERROR(m_logger, "{} 获取录音线程失败", m_logBase); return false; } return true; } /* 清理数据 */ void ConsistencyCompareThread::clearData() { } /* 比对两个wav文件的一致性 */ bool ConsistencyCompareThread::compareConsistency() { /* 计算比对需要的时间 */ std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now(); CompareResult* result = LHCompare(m_wavFilePath1.fileName.c_str(), m_wavFilePath2.fileName.c_str(), m_sensitivity); if(result == nullptr) { SPDLOG_LOGGER_ERROR(m_logger, "{} 一致性比对失败,可能是文件格式不支持或动态库加载失败", m_logBase); return false; } /* 计算比对耗时 */ std::chrono::steady_clock::time_point endTime = std::chrono::steady_clock::now(); std::chrono::duration duration = endTime - startTime; SPDLOG_LOGGER_DEBUG(m_logger, "{} 一致性比对耗时: {}ms", m_logBase, std::chrono::duration_cast(duration).count()); /* 如果高相似度小于1,将两个通道反过来对比一下 */ if(result->highest_similarity < 1) { delete result; result = nullptr; SPDLOG_LOGGER_WARN(m_logger, "{} 高相似度小于1,尝试反向对比", m_logBase); result = LHCompare(m_wavFilePath2.fileName.c_str(), m_wavFilePath1.fileName.c_str(), m_sensitivity); if(result == nullptr) { SPDLOG_LOGGER_ERROR(m_logger, "{} 一致性比对失败,可能是文件格式不支持或动态库加载失败", m_logBase); return false; } } // SPDLOG_LOGGER_DEBUG(m_logger, "{} 一致性比对结果: 源文件: {}, 目标文件: {}, 最高相似度: {:.3f}, 平均相似度: {:.3f}", // m_logBase, m_wavFilePath1.fileName, m_wavFilePath2.fileName, result->highest_similarity, result->average_similarity); /* 保存结果 */ m_mutexResult.lock(); m_consistencyResult.AddRetAICompareFile(result->highest_similarity / 100.0); m_mutexResult.unlock(); delete result; result = nullptr; return true; }