1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Rosegarden
5     A sequencer and musical notation editor.
6     Copyright 2000-2021 the Rosegarden development team.
7     See the AUTHORS file for more details.
8 
9     This program is free software; you can redistribute it and/or
10     modify it under the terms of the GNU General Public License as
11     published by the Free Software Foundation; either version 2 of the
12     License, or (at your option) any later version.  See the file
13     COPYING included with this distribution for more information.
14 */
15 
16 
17 #ifndef RG_PEAKFILEMANAGER_H
18 #define RG_PEAKFILEMANAGER_H
19 
20 #include <vector>
21 
22 #include <QObject>
23 #include <QString>
24 #include <QPointer>
25 
26 class QProgressDialog;
27 
28 #include "sound/SoundFile.h"
29 #include "PeakFile.h"  // for SplitPointPair
30 
31 namespace Rosegarden
32 {
33 
34 class AudioFile;
35 class PeakFile;
36 class RealTime;
37 
38 /**
39  * Accepts an AudioFIle and turns the sample data into peak data for
40  * storage in a peak file or a BWF format peak chunk.
41  */
42 class PeakFileManager : public QObject
43 {
44     Q_OBJECT
45 public:
46     PeakFileManager();
47     ~PeakFileManager() override;
48 
49     class BadPeakFileException : public Exception
50     {
51     public:
BadPeakFileException(QString path)52         BadPeakFileException(QString path) :
53             Exception(QObject::tr("Bad peak file ") + path), m_path(path) { }
BadPeakFileException(QString path,QString file,int line)54         BadPeakFileException(QString path, QString file, int line) :
55             Exception(QObject::tr("Bad peak file ") + path, file, line), m_path(path) { }
BadPeakFileException(const SoundFile::BadSoundFileException & e)56         BadPeakFileException(const SoundFile::BadSoundFileException &e) :
57             Exception(QObject::tr("Bad peak file (malformed audio?) ") + e.getPath()), m_path(e.getPath()) { }
58 
throw()59         ~BadPeakFileException() throw() override { }
60 
getPath()61         QString getPath() const { return m_path; }
62 
63     private:
64         QString m_path;
65     };
66 
67 private:
68     PeakFileManager(const PeakFileManager &pFM);
69     PeakFileManager& operator=(const PeakFileManager &);
70 
71 public:
72     /**
73      * Check that a given audio file has a valid and up to date
74      * peak file or peak chunk.
75      *
76      * throws BadSoundFileException, BadPeakFileException
77      */
78     bool hasValidPeaks(AudioFile *audioFile);
79 
80     /// For callers of generatePeaks().
setProgressDialog(QPointer<QProgressDialog> progressDialog)81     void setProgressDialog(QPointer<QProgressDialog> progressDialog)
82             { m_progressDialog = progressDialog; }
83 
84     /// Generate a peak file from file details.
85     /**
86      * if the peak file already exists _and_ it's up to date then we don't
87      * do anything.  For BWF files we generate an internal peak chunk.
88      *
89      * throw BadSoundFileException, BadPeakFileException
90      */
91     void generatePeaks(AudioFile *audioFile);
92 
93     /**
94      * throws BadSoundFileException, BadPeakFileException
95      */
96     std::vector<float> getPreview(AudioFile *audioFile,
97                                   const RealTime &startTime,
98                                   const RealTime &endTime,
99                                   int   width,
100                                   bool  showMinima);
101     /// Removes peak file from PeakFileManager - doesn't affect audioFile
102     bool removeAudioFile(AudioFile *audioFile);
103 
104     void clear();
105 
106     std::vector<SplitPointPair>
107         getSplitPoints(AudioFile *audioFile,
108                        const RealTime &startTime,
109                        const RealTime &endTime,
110                        int threshold,
111                        const RealTime &minTime);
112 
begin()113     std::vector<PeakFile *>::const_iterator begin() const
114                 { return m_peakFiles.begin(); }
115 
end()116     std::vector<PeakFile *>::const_iterator end() const
117                 { return m_peakFiles.end(); }
118 
119 protected:
120     /// Insert PeakFile based on AudioFile if it doesn't already exist.
121     bool insertAudioFile(AudioFile *audioFile);
122     /// Auto-inserts PeakFile into manager if it doesn't already exist.
123     PeakFile *getPeakFile(AudioFile *audioFile);
124 
125     std::vector<PeakFile *> m_peakFiles;
126 
127     QPointer<QProgressDialog> m_progressDialog;
128 };
129 
130 
131 }
132 
133 
134 #endif // RG_PEAKFILEMANAGER_H
135