55 using namespace RTPROCESSINGLIB;
56 using namespace FIFFLIB;
57 using namespace Eigen;
58 using namespace UTILSLIB;
69 , m_iFftLength(p_iMaxSamples)
70 , m_pFiffInfo(p_pFiffInfo)
71 , m_dataLength(p_dataLen)
78 qRegisterMetaType<Eigen::MatrixXd>(
"Eigen::MatrixXd");
81 m_Fs = m_pFiffInfo->sfreq;
83 m_bSendDataToBuffer =
true;
88 m_fWin = hanning(m_iFftLength,0);
90 qDebug()<<
"Hanning window is created.";
104 QVector <float> RtNoise::hanning(
int N,
short itype)
107 QVector <float> w(N,0.0);
117 for(i=0; i<half; i++)
118 w[i] = 0.5 * (1 - cos(2*3.14159265*(i+1) / (n+1)));
121 for(i=half; i<n; i++) {
129 for(i=0; i<half; i++)
130 w[i] = 0.5 * (1 - cos(23.14159265*(i+1) / (n+1)));
133 for(i=half; i<n; i++) {
141 for(i=N-1; i>=1; i--)
152 if(!m_pCircularBuffer)
155 if (m_bSendDataToBuffer)
156 m_pCircularBuffer->push(p_DataSegment);
177 m_bIsRunning =
false;
179 m_pCircularBuffer->clear();
181 qDebug()<<
" RtNoise Thread is stopped.";
190 #ifdef EIGEN_FFTW_DEFAULT
191 fftw_make_planner_thread_safe();
194 bool FirstStart =
true;
197 while(m_bIsRunning) {
198 if(m_pCircularBuffer) {
199 if(m_pCircularBuffer->pop(block)) {
202 if(m_dataLength < 0) m_dataLength = 10;
203 m_iNumOfBlocks = m_dataLength;
204 m_iBlockSize = block.cols();
205 m_iSensors = block.rows();
207 m_matCircBuf.resize(m_iSensors,m_iNumOfBlocks*m_iBlockSize);
213 for (
int i=0; i< m_iSensors; i++)
214 for (
int j=0; j< m_iBlockSize; j++)
215 m_matCircBuf(i,j+m_iBlockIndex*m_iBlockSize) = block(i,j);
218 if (m_iBlockIndex >= m_iNumOfBlocks){
222 m_bSendDataToBuffer =
false;
226 MatrixXd sum_psdx = MatrixXd::Zero(m_iSensors,m_iFftLength/2+1);
228 int nb = floor(m_iNumOfBlocks*m_iBlockSize/m_iFftLength)+1;
229 qDebug()<<
"nb"<<nb<<
"NumOfBlocks"<<m_iNumOfBlocks<<
"BlockSize"<<m_iBlockSize;
230 MatrixXd t_mat(m_iSensors,m_iFftLength);
231 MatrixXd t_psdx(m_iSensors,m_iFftLength/2+1);
232 for (
int n = 0; n<nb; n++){
236 for(qint32 ii=0; ii<m_iSensors; ii++)
237 for(qint32 jj=0; jj<m_iFftLength; jj++)
238 if(jj+n*m_iFftLength<m_iNumOfBlocks*m_iBlockSize)
239 t_mat(ii,jj) = m_matCircBuf(ii,jj+n*m_iFftLength);
246 for(qint32 ii=0; ii<m_iSensors; ii++)
247 for(qint32 jj=0; jj<m_iFftLength; jj++)
248 t_mat(ii,jj) = m_matCircBuf(ii,jj+n*m_iFftLength);
252 for(qint32 i = 0; i < t_mat.rows(); i++){
258 RowVectorXd vecDataZeroPad = RowVectorXd::Zero(m_iFftLength);
259 vecDataZeroPad.head(data.cols()) = data;
261 for (qint32 lk = 0; lk<m_iFftLength; lk++)
262 vecDataZeroPad[lk] = vecDataZeroPad[lk]*m_fWin[lk];
265 Eigen::FFT<double> fft;
266 fft.SetFlag(fft.HalfSpectrum);
269 RowVectorXcd vecFreqData(m_iFftLength/2+1);
270 fft.fwd(vecFreqData,vecDataZeroPad);
273 for(qint32 j=0; j<m_iFftLength/2+1;j++)
275 double mag_abs = sqrt(vecFreqData(j).real()* vecFreqData(j).real() + vecFreqData(j).imag()*vecFreqData(j).imag());
276 double spower = (1.0/(m_Fs*m_iFftLength))* mag_abs;
277 if (j>0&&j<m_iFftLength/2) spower = 2.0*spower;
278 sum_psdx(i,j) = sum_psdx(i,j) + spower;
284 for(qint32 ii=0; ii<m_iSensors; ii++)
285 for(qint32 jj=0; jj<m_iFftLength/2+1; jj++)
286 t_psdx(ii,jj) = 10.0*log10(sum_psdx(ii,jj)/nb);
288 qDebug()<<
"Send spectrum to Noise Estimator";
291 m_bSendDataToBuffer =
true;