123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #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<double>(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<bool>();
- /*-------------------------- 再检测右声道 --------------------------*/
- 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<bool>();
- }
- catch (const std::exception& e)
- {
- SPDLOG_LOGGER_ERROR(m_logger, "{} 调用动态库检测噪音失败: {}", m_logBase, e.what());
- return false;
- }
- std::chrono::duration<double> duration = std::chrono::steady_clock::now() - startTime;
- std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(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
- {
- /* 上一次没有噪音,这次有噪音,噪音报警开始 */
-
- }
- }
|