NoiseDetectThread.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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. while(m_isRunning)
  31. {
  32. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  33. /*------------------------------------------------------------------------
  34. * 获取最新的左右声道数据
  35. *------------------------------------------------------------------------*/
  36. if(m_pWAVThread->getLatestLeftRightData(m_leftRightData))
  37. {
  38. continue;
  39. }
  40. /*------------------------------------------------------------------------
  41. * 计算数据
  42. *------------------------------------------------------------------------*/
  43. if(!detectNoise())
  44. {
  45. continue;
  46. }
  47. /*------------------------------------------------------------------------
  48. * 处理结果,写噪音报警信息到数据库
  49. *------------------------------------------------------------------------*/
  50. saveResult();
  51. }
  52. clearData(); // 清理数据
  53. SPDLOG_LOGGER_INFO(m_logger, "{} 噪音检测线程结束", m_logBase);
  54. }
  55. /* 初始化数据 */
  56. bool NoiseDetectThread::initData()
  57. {
  58. auto begin = m_threadInfo.compareItemInfo.mapRoad.begin(); // 获取第一个通道的信息
  59. m_roadInfo = begin->scRoadInfo; // 录音通道信息
  60. m_roadName = fmt::format("{}:{}", m_roadInfo.strSoundCardName.toStdString(), m_roadInfo.roadInfo.nRoadNum);
  61. m_logBase = fmt::format("噪音检测通道 {}:", m_roadName);
  62. m_pWAVThread = ThreadMan.getCreateWAVThread(m_roadInfo.nSoundCardNum, m_roadInfo.roadInfo.nRoadNum);
  63. if(m_pWAVThread == nullptr)
  64. {
  65. SPDLOG_LOGGER_ERROR(m_logger, "{} 获取数据生成线程失败", m_logBase);
  66. return false;
  67. }
  68. auto sampleRate = GInfo.sampleRate();
  69. m_sample_rate = static_cast<double>(sampleRate);
  70. return true;
  71. }
  72. /* 清理数据 */
  73. void NoiseDetectThread::clearData()
  74. {
  75. }
  76. /* 调用动态库检测噪音 */
  77. bool NoiseDetectThread::detectNoise()
  78. {
  79. bool isNoiseLeft = false; /* 是否检测到左声道噪音 */
  80. bool isNoiseRight = false; /* 是否检测到右声道噪音 */
  81. try
  82. {
  83. /*-------------------------- 先检测左声道 --------------------------*/
  84. nJson jsonOutput;
  85. auto ret = signalstats_wrapper::detect_signal_wrapper(
  86. jsonOutput, /* 返回结果,和jsonResult是一样的 */
  87. m_leftRightData.vecLeftData, /* 左声道数据 */
  88. m_sample_rate, /* 采样率(HZ) */
  89. m_silence_threshold, /* 静音阈值 */
  90. m_db_threshold, /* 分贝阈值 */
  91. m_cv_threshold, /* 变异系数阈值 */
  92. m_window_params, /* 窗函数参数 */
  93. m_nperseg, /* 每段样本数 */
  94. m_noverlap, /* 重叠样本数 */
  95. m_nfft, /* FFT点数 */
  96. false /* 是否输出调试信息, true表示输出调试信息, false表示不输出调试信息 */
  97. );
  98. isNoiseLeft = jsonOutput["noise"].is_null() ? false : jsonOutput["noise"].get<bool>();
  99. /*-------------------------- 再检测右声道 --------------------------*/
  100. jsonOutput.clear(); /* 清空输出结果 */
  101. signalstats_wrapper::detect_signal_wrapper(
  102. jsonOutput, /* 返回结果,和jsonResult是一样的 */
  103. m_leftRightData.vecRightData, /* 右声道数据 */
  104. m_sample_rate, /* 采样率(HZ) */
  105. m_silence_threshold, /* 静音阈值 */
  106. m_db_threshold, /* 分贝阈值 */
  107. m_cv_threshold, /* 变异系数阈值 */
  108. m_window_params, /* 窗函数参数 */
  109. m_nperseg, /* 每段样本数 */
  110. m_noverlap, /* 重叠样本数 */
  111. m_nfft, /* FFT点数 */
  112. false /* 是否输出调试信息, true表示输出调试信息, false表示不输出调试信息 */
  113. );
  114. isNoiseRight = jsonOutput["noise"].is_null() ? false : jsonOutput["noise"].get<bool>();
  115. }
  116. catch (const std::exception& e)
  117. {
  118. SPDLOG_LOGGER_ERROR(m_logger, "{} 调用动态库检测噪音失败: {}", m_logBase, e.what());
  119. return false;
  120. }
  121. /* -------------------------- 和以往的结果对比 --------------------------*/
  122. m_isNoiseLast = m_isNoise.load(); /* 上一次的噪音检测结果 */
  123. m_isNoise.store(isNoiseLeft || isNoiseRight); /* 是否检测到噪音 */
  124. return true;
  125. }
  126. /* 保存结果 */
  127. void NoiseDetectThread::saveResult()
  128. {
  129. if(m_isNoiseLast)
  130. {
  131. /* 判断这次是否是噪音,没有噪音就报警结束 */
  132. }else
  133. {
  134. /* 上一次没有噪音,这次有噪音,噪音报警开始 */
  135. }
  136. }