File indexing completed on 2025-01-05 04:25:40
0001 /* 0002 * Copyright 2018 Malte Veerman <malte.veerman@gmail.com> 0003 * 0004 * This program is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU General Public License as 0006 * published by the Free Software Foundation; either version 2 of 0007 * the License or (at your option) version 3 or any later version 0008 * accepted by the membership of KDE e.V. (or its successor approved 0009 * by the membership of KDE e.V.), which shall act as a proxy 0010 * defined in Section 14 of version 3 of the license. 0011 * 0012 * This program is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 * GNU General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU General Public License 0018 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0019 */ 0020 0021 #ifndef ANALYZERWORKER_H 0022 #define ANALYZERWORKER_H 0023 0024 #include "AnalyzerBase.h" 0025 0026 #include <phonon/audiodataoutput.h> 0027 0028 #include <QElapsedTimer> 0029 #include <QMutex> 0030 #include <QObject> 0031 #include <QTime> 0032 0033 #include <complex> 0034 #include <fftw3.h> 0035 0036 0037 class QTimer; 0038 0039 namespace Analyzer 0040 { 0041 0042 /** 0043 * Base worker class for all analyzers 0044 * All compute heavy tasks should be offloaded to this. 0045 */ 0046 class Worker : public QObject 0047 { 0048 friend class Base; 0049 0050 Q_OBJECT 0051 0052 public: 0053 const static int PROCESSING_INTERVAL = 5; // Interval between new data lookups 0054 const static int DATA_BUFFER_SIZE = 8; // Higher values increase latency, lower values increase risk of missing frames 0055 0056 Worker(); 0057 ~Worker() override; 0058 0059 protected: 0060 /** 0061 * @return The current scope data. 0062 */ 0063 const QVector<double>& scope() const { return m_currentScope; } 0064 0065 /** 0066 * This function is being called after new scope data is ready. 0067 * Get the scope to be analyzed by calling scope(). 0068 * Subclasses must implement this function. 0069 */ 0070 virtual void analyze() = 0; 0071 0072 private: 0073 struct BandInfo 0074 { 0075 double lowerFreq; 0076 double midFreq; 0077 double upperFreq; 0078 double lowerK; 0079 double midK; 0080 double upperK; 0081 int scopeIndex; 0082 }; 0083 0084 /** 0085 * This function is thread-safe. 0086 */ 0087 void receiveData( const QMap<Phonon::AudioDataOutput::Channel, QVector<qint16> > &newData ); 0088 0089 // None of the following functions are thread-safe. Only connect with queued connections to them. 0090 void processData(); 0091 void applyWindowFunction(); 0092 void makeScope(); 0093 void setSampleSize( uint size ); 0094 void setWindowFunction( Base::WindowFunction windowFunction ); 0095 void setScopeSize( int size ); 0096 void calculateExpFactor( qreal minFreq, qreal maxFreq, int sampleRate ); 0097 void resetDemo() { m_demoT = 201; } 0098 void playbackStateChanged(); 0099 0100 /** 0101 * Override this function for your custom idle animation. 0102 */ 0103 virtual void demo(); 0104 0105 fftw_plan m_plan; 0106 mutable QMutex m_rawInMutex; 0107 QList<double> m_rawIn; 0108 double *m_in; 0109 std::complex<double> *m_out; 0110 QVector<double> m_currentScope; 0111 QVector<BandInfo> m_interpolatedScopeBands; 0112 QVector<BandInfo> m_notInterpolatedScopeBands; 0113 uint m_size; 0114 double m_expFactor; 0115 Base::WindowFunction m_windowFunction; 0116 int m_expectedDataTime; 0117 int m_demoT; 0118 QElapsedTimer m_lastUpdate; 0119 QTimer *m_demoTimer; 0120 QTimer *m_processTimer; 0121 }; 0122 0123 } 0124 0125 #endif // ANALYZERWORKER_H