NoiseDetectThread.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include "NoiseDetectThread.h"
  2. #include "CreateWAVThread.h"
  3. #include "ThreadManager.h"
  4. #include "commonDefine.h"
  5. #include "GlobalInfo.h"
  6. #include "signalstats_wrapper.h"
  7. NoiseDetectThread::NoiseDetectThread(CalculateThreadInfo_t& threadInfo)
  8. : BaseCalculateThread(threadInfo),
  9. m_leftRightData(0)
  10. {
  11. m_logger = spdlog::get("ACAServer");
  12. if(m_logger == nullptr)
  13. {
  14. fmt::print("NoiseDetectThread: ACAServer Logger not found.\n");
  15. return;
  16. }
  17. }
  18. NoiseDetectThread::~NoiseDetectThread()
  19. {
  20. }
  21. /* 线程功能函数 */
  22. void NoiseDetectThread::task()
  23. {
  24. /* 初始化数据 */
  25. if(!initData())
  26. {
  27. SPDLOG_LOGGER_ERROR(m_logger, "{} 初始化数据失败", m_logBase);
  28. return;
  29. }
  30. SPDLOG_LOGGER_INFO(m_logger, " ******************* {} 噪音检测线程开始运行 ******************* ", m_logBase);
  31. while(m_isRunning)
  32. {
  33. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  34. /*------------------------------------------------------------------------
  35. * 获取最新的左右声道数据
  36. *------------------------------------------------------------------------*/
  37. if(!m_pWAVThread->getLatestLeftRightData(m_leftRightData))
  38. {
  39. continue;
  40. }
  41. SPDLOG_LOGGER_ERROR(m_logger, "{} 获取最新的左右声道数据成功,开始调用动态库计算噪音------------------------------------------ ", m_logBase);
  42. /*------------------------------------------------------------------------
  43. * 计算数据
  44. *------------------------------------------------------------------------*/
  45. if(!detectNoise())
  46. {
  47. continue;
  48. }
  49. /*------------------------------------------------------------------------
  50. * 处理结果,写噪音报警信息到数据库(这里不写数据库,只计算结果返回给对比项)
  51. * 上面那个函数已经把结果保存了
  52. *------------------------------------------------------------------------*/
  53. // saveResult();
  54. }
  55. clearData(); // 清理数据
  56. SPDLOG_LOGGER_INFO(m_logger, " ******************* {} 噪音检测线程结束 ******************* ", m_logBase);
  57. }
  58. /* 初始化数据 */
  59. bool NoiseDetectThread::initData()
  60. {
  61. auto begin = m_threadInfo.compareItemInfo.mapRoad.begin(); // 获取第一个通道的信息
  62. m_roadInfo = begin->scRoadInfo; // 录音通道信息
  63. m_roadName = fmt::format("{}:{}", m_roadInfo.strSoundCardID.toStdString(), m_roadInfo.roadInfo.nRoadNum);
  64. m_logBase = fmt::format("噪音检测通道 {}:", m_roadName);
  65. m_pWAVThread = ThreadMan.getCreateWAVThread(m_roadInfo.nSoundCardNum, m_roadInfo.roadInfo.nRoadNum);
  66. if(m_pWAVThread == nullptr)
  67. {
  68. SPDLOG_LOGGER_ERROR(m_logger, "{} 获取数据生成线程失败", m_logBase);
  69. return false;
  70. }
  71. auto sampleRate = GInfo.sampleRate();
  72. m_sample_rate = static_cast<double>(sampleRate);
  73. return true;
  74. }
  75. /* 清理数据 */
  76. void NoiseDetectThread::clearData()
  77. {
  78. }
  79. /* 调用动态库检测噪音 */
  80. bool NoiseDetectThread::detectNoise()
  81. {
  82. auto startTime = std::chrono::steady_clock::now();
  83. bool isNoiseLeft = false; /* 是否检测到左声道噪音 */
  84. bool isNoiseRight = false; /* 是否检测到右声道噪音 */
  85. try
  86. {
  87. /*-------------------------- 先检测左声道 --------------------------*/
  88. nJson jsonOutput;
  89. auto ret = signalstats_wrapper::detect_signal_wrapper(
  90. jsonOutput, /* 返回结果,和jsonResult是一样的 */
  91. m_leftRightData.vecLeftData, /* 左声道数据 */
  92. m_sample_rate, /* 采样率(HZ) */
  93. m_silence_threshold, /* 静音阈值 */
  94. m_db_threshold, /* 分贝阈值 */
  95. m_cv_threshold, /* 变异系数阈值 */
  96. m_window_params, /* 窗函数参数 */
  97. m_nperseg, /* 每段样本数 */
  98. m_noverlap, /* 重叠样本数 */
  99. m_nfft, /* FFT点数 */
  100. false /* 是否输出调试信息, true表示输出调试信息, false表示不输出调试信息 */
  101. );
  102. isNoiseLeft = jsonOutput["noise"].is_null() ? false : jsonOutput["noise"].get<bool>();
  103. /*-------------------------- 再检测右声道 --------------------------*/
  104. jsonOutput.clear(); /* 清空输出结果 */
  105. signalstats_wrapper::detect_signal_wrapper(
  106. jsonOutput, /* 返回结果,和jsonResult是一样的 */
  107. m_leftRightData.vecRightData, /* 右声道数据 */
  108. m_sample_rate, /* 采样率(HZ) */
  109. m_silence_threshold, /* 静音阈值 */
  110. m_db_threshold, /* 分贝阈值 */
  111. m_cv_threshold, /* 变异系数阈值 */
  112. m_window_params, /* 窗函数参数 */
  113. m_nperseg, /* 每段样本数 */
  114. m_noverlap, /* 重叠样本数 */
  115. m_nfft, /* FFT点数 */
  116. false /* 是否输出调试信息, true表示输出调试信息, false表示不输出调试信息 */
  117. );
  118. isNoiseRight = jsonOutput["noise"].is_null() ? false : jsonOutput["noise"].get<bool>();
  119. }
  120. catch (const std::exception& e)
  121. {
  122. SPDLOG_LOGGER_ERROR(m_logger, "{} 调用动态库检测噪音失败: {}", m_logBase, e.what());
  123. return false;
  124. }
  125. std::chrono::duration<double> duration = std::chrono::steady_clock::now() - startTime;
  126. std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration);
  127. SPDLOG_LOGGER_DEBUG(m_logger, "{} 调用动态库检测噪音耗时: {}ms", m_logBase, ms.count());
  128. SPDLOG_LOGGER_DEBUG(m_logger, "{} 左声道噪音检测结果: {}, 右声道噪音检测结果: {}", m_logBase, isNoiseLeft, isNoiseRight);
  129. /* -------------------------- 和以往的结果对比 --------------------------*/
  130. m_isNoiseLast = m_isNoise.load(); /* 上一次的噪音检测结果 */
  131. m_isNoise.store(isNoiseLeft || isNoiseRight); /* 是否检测到噪音 */
  132. return true;
  133. }
  134. /* 保存结果 */
  135. void NoiseDetectThread::saveResult()
  136. {
  137. if(m_isNoiseLast)
  138. {
  139. /* 判断这次是否是噪音,没有噪音就报警结束 */
  140. }else
  141. {
  142. /* 上一次没有噪音,这次有噪音,噪音报警开始 */
  143. }
  144. }