#include "NoiseDetectThread.h" #include "CreateWAVThread.h" #include "ThreadManager.h" #include "commonDefine.h" #include "GlobalInfo.h" #include "signalstats_wrapper.h" NoiseDetectThread::NoiseDetectThread(CalculateThreadInfo_t& threadInfo) : BaseCalculateThread(threadInfo), m_leftRightData(0) { m_logger = spdlog::get("ACAServer"); if(m_logger == nullptr) { fmt::print("NoiseDetectThread: ACAServer Logger not found.\n"); return; } } NoiseDetectThread::~NoiseDetectThread() { } /* 线程功能函数 */ void NoiseDetectThread::task() { /* 初始化数据 */ 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(10)); /*------------------------------------------------------------------------ * 获取最新的左右声道数据 *------------------------------------------------------------------------*/ if(!m_pWAVThread->getLatestLeftRightData(m_leftRightData)) { continue; } SPDLOG_LOGGER_ERROR(m_logger, "{} 获取最新的左右声道数据成功,开始调用动态库计算噪音------------------------------------------ ", m_logBase); /*------------------------------------------------------------------------ * 计算数据 *------------------------------------------------------------------------*/ if(!detectNoise()) { continue; } /*------------------------------------------------------------------------ * 处理结果,写噪音报警信息到数据库(这里不写数据库,只计算结果返回给对比项) * 上面那个函数已经把结果保存了 *------------------------------------------------------------------------*/ // saveResult(); } clearData(); // 清理数据 SPDLOG_LOGGER_INFO(m_logger, " ******************* {} 噪音检测线程结束 ******************* ", m_logBase); } /* 初始化数据 */ bool NoiseDetectThread::initData() { auto begin = m_threadInfo.compareItemInfo.mapRoad.begin(); // 获取第一个通道的信息 m_roadInfo = begin->scRoadInfo; // 录音通道信息 m_roadName = fmt::format("{}:{}", m_roadInfo.strSoundCardID.toStdString(), m_roadInfo.roadInfo.nRoadNum); m_logBase = fmt::format("噪音检测通道 {}:", m_roadName); m_pWAVThread = ThreadMan.getCreateWAVThread(m_roadInfo.nSoundCardNum, m_roadInfo.roadInfo.nRoadNum); if(m_pWAVThread == nullptr) { SPDLOG_LOGGER_ERROR(m_logger, "{} 获取数据生成线程失败", m_logBase); return false; } auto sampleRate = GInfo.sampleRate(); m_sample_rate = static_cast(sampleRate); return true; } /* 清理数据 */ void NoiseDetectThread::clearData() { } /* 调用动态库检测噪音 */ bool NoiseDetectThread::detectNoise() { auto startTime = std::chrono::steady_clock::now(); bool isNoiseLeft = false; /* 是否检测到左声道噪音 */ bool isNoiseRight = false; /* 是否检测到右声道噪音 */ try { /*-------------------------- 先检测左声道 --------------------------*/ nJson jsonOutput; auto ret = signalstats_wrapper::detect_signal_wrapper( jsonOutput, /* 返回结果,和jsonResult是一样的 */ m_leftRightData.vecLeftData, /* 左声道数据 */ m_sample_rate, /* 采样率(HZ) */ m_silence_threshold, /* 静音阈值 */ m_db_threshold, /* 分贝阈值 */ m_cv_threshold, /* 变异系数阈值 */ m_window_params, /* 窗函数参数 */ m_nperseg, /* 每段样本数 */ m_noverlap, /* 重叠样本数 */ m_nfft, /* FFT点数 */ false /* 是否输出调试信息, true表示输出调试信息, false表示不输出调试信息 */ ); isNoiseLeft = jsonOutput["noise"].is_null() ? false : jsonOutput["noise"].get(); /*-------------------------- 再检测右声道 --------------------------*/ jsonOutput.clear(); /* 清空输出结果 */ signalstats_wrapper::detect_signal_wrapper( jsonOutput, /* 返回结果,和jsonResult是一样的 */ m_leftRightData.vecRightData, /* 右声道数据 */ m_sample_rate, /* 采样率(HZ) */ m_silence_threshold, /* 静音阈值 */ m_db_threshold, /* 分贝阈值 */ m_cv_threshold, /* 变异系数阈值 */ m_window_params, /* 窗函数参数 */ m_nperseg, /* 每段样本数 */ m_noverlap, /* 重叠样本数 */ m_nfft, /* FFT点数 */ false /* 是否输出调试信息, true表示输出调试信息, false表示不输出调试信息 */ ); isNoiseRight = jsonOutput["noise"].is_null() ? false : jsonOutput["noise"].get(); } catch (const std::exception& e) { SPDLOG_LOGGER_ERROR(m_logger, "{} 调用动态库检测噪音失败: {}", m_logBase, e.what()); return false; } std::chrono::duration duration = std::chrono::steady_clock::now() - startTime; std::chrono::milliseconds ms = std::chrono::duration_cast(duration); SPDLOG_LOGGER_DEBUG(m_logger, "{} 调用动态库检测噪音耗时: {}ms", m_logBase, ms.count()); SPDLOG_LOGGER_DEBUG(m_logger, "{} 左声道噪音检测结果: {}, 右声道噪音检测结果: {}", m_logBase, isNoiseLeft, isNoiseRight); /* -------------------------- 和以往的结果对比 --------------------------*/ m_isNoiseLast = m_isNoise.load(); /* 上一次的噪音检测结果 */ m_isNoise.store(isNoiseLeft || isNoiseRight); /* 是否检测到噪音 */ return true; } /* 保存结果 */ void NoiseDetectThread::saveResult() { if(m_isNoiseLast) { /* 判断这次是否是噪音,没有噪音就报警结束 */ }else { /* 上一次没有噪音,这次有噪音,噪音报警开始 */ } }