64 m_iNumOfBlocks = m_iDataLength;
65 m_iBlockSize =
static_cast<int>(matData.cols());
66 m_iSensors =
static_cast<int>(matData.rows());
67 m_matCircBuf.resize(m_iSensors,
static_cast<Eigen::Index
>(m_iNumOfBlocks) * m_iBlockSize);
69 m_bFirstBlock =
false;
73 m_matCircBuf.block(0, m_iBlockIndex * m_iBlockSize, m_iSensors, m_iBlockSize) = matData;
76 if(m_iBlockIndex < m_iNumOfBlocks) {
83 const int iTotalSamples = m_iNumOfBlocks * m_iBlockSize;
84 const int iHalfSpec = m_iFftLength / 2 + 1;
85 const int nb = iTotalSamples / m_iFftLength + 1;
87 MatrixXd sum_psdx = MatrixXd::Zero(m_iSensors, iHalfSpec);
88 RowVectorXd vecDataZeroPad = RowVectorXd::Zero(m_iFftLength);
89 RowVectorXcd vecFreqData(iHalfSpec);
91 for(
int n = 0; n < nb; ++n) {
92 const int iOffset = n * m_iFftLength;
94 for(
int i = 0; i < m_iSensors; ++i) {
96 vecDataZeroPad.setZero();
97 const int iCopyLen = std::min(m_iFftLength, iTotalSamples - iOffset);
98 vecDataZeroPad.head(iCopyLen) = m_matCircBuf.block(i, iOffset, 1, iCopyLen);
101 for(
int k = 0; k < m_iFftLength; ++k) {
102 vecDataZeroPad[k] *= m_fWin[k];
106 Eigen::FFT<double> fft;
107 fft.SetFlag(fft.HalfSpectrum);
108 fft.fwd(vecFreqData, vecDataZeroPad);
111 for(
int j = 0; j < iHalfSpec; ++j) {
112 const double mag = std::abs(vecFreqData(j));
113 double spower = mag / (m_dFs * m_iFftLength);
114 if(j > 0 && j < m_iFftLength / 2) {
117 sum_psdx(i, j) += spower;
123 MatrixXd matResult(m_iSensors, iHalfSpec);
124 for(
int i = 0; i < m_iSensors; ++i) {
125 for(
int j = 0; j < iHalfSpec; ++j) {
126 matResult(i, j) = 10.0 * std::log10(sum_psdx(i, j) / nb);
181 qRegisterMetaType<Eigen::MatrixXd>(
"Eigen::MatrixXd");
183 auto* worker =
new RtNoiseWorker(iFftLength, pFiffInfo, iDataLength);
184 worker->moveToThread(&m_workerThread);
186 connect(&m_workerThread, &QThread::finished,
187 worker, &QObject::deleteLater);