#ifndef NOISEDETECTTHREAD_H_ #define NOISEDETECTTHREAD_H_ #include "BaseCalculateThread.h" #include "AudioData.h" #include "SystemConfig.h" #include "RingQueueManualMutex.hpp" class CreateWAVThread; class CreateLongFileThread ; /** 噪音检测线程类 1、噪音检测线程是调用动态库检测噪音 2、噪音检测线程参数和对比项无关,是公共的参数,这里没有对比项信息 3、因为报警信息需要有对比项信息,所以这里有个map,保存对比项传入的信息,根据对比项信息 开启报警录制,如果这个通道被多个对比项使用,可能会同时录制多个报警文件。 噪音判断逻辑 1、每次检测噪音时,都会检测左右声道的噪音,如果有一个声道有噪音,就认为是噪音 2、假设设置的噪音检测持续次数是10次,设置的百分比是0.8,10次里有8个是噪音,就判断为噪音 3、噪音预警,如果连续n次都是噪音,就认为是噪音预警 4、噪音恢复,连续检测次数中低于设置的百分比就认为噪音恢复了 */ class NoiseDetectThread : public BaseCalculateThread { public: NoiseDetectThread(CalculateThreadInfo_t& threadInfo); ~NoiseDetectThread() override; /* 获取通道信息 */ const SoundCardRoadInfo_t& getRoadInfo() const { return m_roadInfo; } /* 获取当前噪音结果 */ bool isNoise() const { return m_isNoise.load(); } /* 获取是否噪音预警 */ bool isNoiseWarning() const { return m_isNoiseWarning.load(); } /* 开启对比项通道的噪音报警功能 */ void startCompareItemNoiseAlarm(const int itemID, const QString strName, const CompareItemRoadInfo_t& compareItemRoadInfo); /* 关闭对比项通道的噪音报警功能 */ void stopCompareItemNoiseAlarm(const int itemID, const QString strName, const CompareItemRoadInfo_t& compareItemRoadInfo); protected: /* 线程功能函数 */ void task() override; /* 初始化数据 */ bool initData() override; /* 清理数据 */ void clearData() override; private: /* 调用动态库检测噪音 */ bool detectNoise(); /* 保存结果 */ void saveResult(); private: SoundCardRoadInfo_t m_roadInfo; /* 录音通道编号 */ std::string m_roadName; /* 录音通道名称 */ CreateWAVThread* m_pThreadWav = nullptr; /* WAV小文件生成线程指针 */ CreateLongFileThread * m_pThreadCreateAlarm = nullptr; /* 生成报警文件的线程 */ AudioLeftRightData m_leftRightData; /* 左右声道数据 */ /* 计算的结果变量 */ bool m_currentIsNoise = false; /* 当前是否检测到噪音 */ /* 结果 */ std::atomic_bool m_isNoiseWarning = false; /* 噪音预警 */ std::atomic_bool m_isNoise = false; /* 是否检测到噪音 */ bool m_isNoiseLast = false; /* 上一次的噪音检测结果 */ /* ------------------------------------ 噪音检测的一些参数 ------------------------------------ */ NoiseDetectParam_t m_noiseDetectParam; /* 噪音检测参数,这个是从数据库中读取过来的 */ /* 噪音检测动态库需要的参数 */ const std::vector m_window_params = {"tukey", "0.25"}; double m_sample_rate = 48000; /* 采样率 */ double m_silence_threshold = 3e-3; /* 静音检测阈值 */ double m_db_threshold = -70.0; /* 分贝阈值 */ double m_cv_threshold = -70.0; /* 变异系数阈值 */ int m_nperseg = 256; /* 每段样本数 */ int m_noverlap = 32; /* 重叠样本数 */ int m_nfft = 256; /* FFT点数 */ /* ------------------------------------ 报警相关变量 ------------------------------------ */ std::mutex m_mutexAlarm; /* 报警信息互斥锁 */ std::map m_mapAlarmInfo; /* 报警信息,key是对比项ID */ RingQueueManualMutex m_ringQueueIsNoise; /* 噪音检测结果环形队列,保存最近的噪音检测结果 */ }; #endif // NOISEDETECTTHREAD_H_