44 #include <Eigen/SparseCore>
45 #include <unsupported/Eigen/FFT>
52 #include <QElapsedTimer>
54 #include <QtConcurrent>
60 using namespace UTILSLIB;
61 using namespace Eigen;
72 signal.array() -= signal.mean();
73 QList<SpectogramInputData> lData;
74 int iThreadSize = QThread::idealThreadCount()*2;
75 int iStepsSize = signal.rows()/iThreadSize;
76 int iResidual = signal.rows()%iThreadSize;
79 dataTemp.vecInputData = signal;
80 dataTemp.window_size = windowSize;
81 if(dataTemp.window_size == 0) {
82 dataTemp.window_size = signal.rows()/15;
85 for (
int i = 0; i < iThreadSize; ++i) {
86 dataTemp.iRangeLow = i*iStepsSize;
87 dataTemp.iRangeHigh = i*iStepsSize+iStepsSize;
88 lData.append(dataTemp);
91 dataTemp.iRangeLow = iThreadSize*iStepsSize;
92 dataTemp.iRangeHigh = iThreadSize*iStepsSize+iResidual;
93 lData.append(dataTemp);
95 QFuture<MatrixXd> resultMat = QtConcurrent::mappedReduced(lData,
98 resultMat.waitForFinished();
101 return resultMat.result();
106 VectorXd Spectrogram::gaussWindow(qint32 sample_count, qreal scale, quint32 translation)
108 VectorXd gauss = VectorXd::Zero(sample_count);
110 for(qint32 n = 0; n < sample_count; n++)
112 qreal t = (qreal(n) - translation) / scale;
113 gauss[n] = exp(-3.14 * pow(t, 2))*pow(sqrt(scale),(-1))*pow(qreal(2),(0.25));
123 #ifdef EIGEN_FFTW_DEFAULT
124 fftw_make_planner_thread_safe();
127 Eigen::FFT<double> fft;
128 MatrixXd tf_matrix = MatrixXd::Zero(inputData.vecInputData.rows()/2, inputData.vecInputData.rows());
129 VectorXd envelope, windowed_sig, real_coeffs;
130 VectorXcd fft_win_sig;
131 qint32 window_size = inputData.window_size;
133 for(quint32 translate = inputData.iRangeLow; translate < inputData.iRangeHigh; translate++) {
134 envelope = gaussWindow(inputData.vecInputData.rows(), window_size, translate);
136 windowed_sig = VectorXd::Zero(inputData.vecInputData.rows());
137 fft_win_sig = VectorXcd::Zero(inputData.vecInputData.rows());
139 windowed_sig = inputData.vecInputData.array() * envelope.array();\
141 fft.fwd(fft_win_sig, windowed_sig);
143 real_coeffs = fft_win_sig.segment(0,inputData.vecInputData.rows()/2).array().abs2();
145 tf_matrix.col(translate) = real_coeffs;
153 void Spectrogram::reduce(MatrixXd &resultData,
154 const MatrixXd &data)
156 if(resultData.size() == 0) {