00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef PEAK_H
00023 #define PEAK_H
00024
00025 #include <QObject>
00026 #include <QThread>
00027 #include <QMutex>
00028 #include <QQueue>
00029 #include <QWaitCondition>
00030 #include <QFile>
00031 #include <QHash>
00032 #include <QPair>
00033
00034 #include "defines.h"
00035
00036 class ReadSource;
00037 class AudioSource;
00038 class Peak;
00039 class PPThread;
00040 class DecodeBuffer;
00041 class PeakDataReader;
00042
00043 class PeakProcessor : public QObject
00044 {
00045 Q_OBJECT
00046
00047 public:
00048 void queue_task(Peak* peak);
00049 void free_peak(Peak* peak);
00050
00051 private:
00052 PPThread* m_ppthread;
00053 QMutex m_mutex;
00054 QWaitCondition m_wait;
00055 bool m_taskRunning;
00056 Peak* m_runningPeak;
00057
00058 QQueue<Peak* > m_queue;
00059
00060 void dequeue_queue();
00061
00062 PeakProcessor();
00063 ~PeakProcessor();
00064 PeakProcessor(const PeakProcessor&);
00065
00066 friend PeakProcessor& pp();
00067
00068 private slots:
00069 void start_task();
00070
00071 signals:
00072 void newTask();
00073
00074 };
00075
00076 class PPThread : public QThread
00077 {
00078 public:
00079 PPThread(PeakProcessor* pp);
00080
00081 protected:
00082 void run();
00083
00084 private:
00085 PeakProcessor* m_pp;
00086 };
00087
00088
00089
00090 PeakProcessor& pp();
00091
00092
00093 class Peak : public QObject
00094 {
00095 Q_OBJECT
00096
00097 public:
00098 static const int ZOOM_LEVELS = 22;
00099 static const int SAVING_ZOOM_FACTOR = 8;
00100 static const int MAX_ZOOM_USING_SOURCEFILE = SAVING_ZOOM_FACTOR - 1;
00101
00102
00103 static const int MAX_DB_VALUE = 8000;
00104 static int zoomStep[ZOOM_LEVELS + 1];
00105
00106 Peak(AudioSource* source);
00107 ~Peak();
00108
00109 enum { NO_PEAKDATA_FOUND = -1,
00110 NO_PEAK_FILE = -2,
00111 PERMANENT_FAILURE = -3
00112 };
00113
00114 void process(uint channel, audio_sample_t* buffer, nframes_t frames);
00115 int prepare_processing(int rate);
00116 int finish_processing();
00117 int calculate_peaks(int chan, float** buffer, TimeRef startlocation, int peakDataCount, qreal framesPerPeak);
00118
00119 void close();
00120
00121 void start_peak_loading();
00122
00123 audio_sample_t get_max_amplitude(TimeRef startlocation, TimeRef endlocation);
00124
00125 static QHash<int, int>* cache_index_lut();
00126 static int max_zoom_value();
00127
00128 private:
00129 ReadSource* m_source;
00130 bool m_peaksAvailable;
00131 bool m_permanentFailure;
00132 bool m_interuptPeakBuild;
00133 static QHash<int, int> chacheIndexLut;
00134
00135 struct ProcessData {
00136 ProcessData() {
00137 normValue = peakUpperValue = peakLowerValue = 0;
00138 processBufferSize = progress = normProcessedFrames = normDataCount = 0;
00139 nextDataPointLocation = processRange;
00140 }
00141
00142 audio_sample_t peakUpperValue;
00143 audio_sample_t peakLowerValue;
00144 audio_sample_t normValue;
00145
00146 TimeRef stepSize;
00147 TimeRef processRange;
00148 TimeRef processLocation;
00149 TimeRef nextDataPointLocation;
00150
00151 nframes_t normProcessedFrames;
00152
00153 int progress;
00154 int processBufferSize;
00155 int normDataCount;
00156 };
00157
00158 struct PeakHeaderData {
00159 int headerSize;
00160 int normValuesDataOffset;
00161 int peakDataOffsets[ZOOM_LEVELS - SAVING_ZOOM_FACTOR];
00162 int peakDataSizeForLevel[ZOOM_LEVELS - SAVING_ZOOM_FACTOR];
00163 char label[6];
00164 int version[2];
00165 };
00166
00167 struct ChannelData {
00168 ChannelData() {
00169 memory = 0;
00170 peakdataDecodeBuffer = 0;
00171 }
00172 ~ChannelData();
00173 QString fileName;
00174 QString normFileName;
00175 QFile file;
00176 QFile normFile;
00177 PeakHeaderData headerdata;
00178 PeakDataReader* peakreader;
00179 ProcessData* pd;
00180 DecodeBuffer* peakdataDecodeBuffer;
00181 uchar* memory;
00182 QHash<uchar *, QPair<int , int > > maps;
00183 };
00184
00185 QList<ChannelData* > m_channelData;
00186
00187 int create_from_scratch();
00188 int read_header();
00189 int write_header(ChannelData* data);
00190 static void calculate_lut_data();
00191
00192 friend class PeakProcessor;
00193 friend class PeakDataReader;
00194
00195 signals:
00196 void finished();
00197 void progress(int m_progress);
00198 };
00199
00200 class PeakDataReader
00201 {
00202 public:
00203 PeakDataReader(Peak::ChannelData* data);
00204 ~PeakDataReader(){};
00205
00206 nframes_t read_from(DecodeBuffer* buffer, nframes_t start, nframes_t count);
00207
00208 private:
00209 Peak::ChannelData* m_d;
00210 nframes_t m_readPos;
00211 nframes_t m_nframes;
00212
00213 bool seek(nframes_t start);
00214 nframes_t read(DecodeBuffer* buffer, nframes_t frameCount);
00215 };
00216
00217 inline QHash< int, int > * Peak::cache_index_lut()
00218 {
00219 if(chacheIndexLut.isEmpty()) {
00220 calculate_lut_data();
00221 }
00222 return &chacheIndexLut;
00223 }
00224
00225
00226 #endif
00227
00228