summaryrefslogtreecommitdiffstats
path: root/src/sound/AudioFileManager.h
blob: 97216694955e528c4f27ed5659674cb2a848b62b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
// -*- c-indentation-style:"stroustrup" c-basic-offset: 4 -*-
/*
  Rosegarden
  A sequencer and musical notation editor.

  This program is Copyright 2000-2008
  Guillaume Laurent   <glaurent@telegraph-road.org>,
  Chris Cannam        <cannam@all-day-breakfast.com>,
  Richard Bown        <bownie@bownie.com>

  The moral right of the authors to claim authorship of this work
  has been asserted.

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License as
  published by the Free Software Foundation; either version 2 of the
  License, or (at your option) any later version.  See the file
  COPYING included with this distribution for more information.
*/

#ifndef _AUDIOFILEMANAGER_H_
#define _AUDIOFILEMANAGER_H_

#include <string>
#include <vector>
#include <set>
#include <map>

#include <qpixmap.h>
#include <qobject.h>

#include "AudioFile.h"
#include "XmlExportable.h"
#include "PeakFileManager.h"
#include "PeakFile.h"
#include "Exception.h"

#include <kurl.h>

// AudioFileManager loads and maps audio files to their
// internal references (ids).  A point of contact for
// AudioFile information - loading a Composition should
// use this class to pick up the AudioFile references,
// editing the AudioFiles in a Composition will be
// made through this manager.

// This is in the sound library because it's so closely
// connected to other sound classes like the AudioFile
// ones.  However, the audio file manager itself within
// Rosegarden is stored in the GUI process.  This class
// is not (and should not be) used elsewhere within the
// sound or sequencer libraries.

class KProcess;

namespace Rosegarden
{

typedef std::vector<AudioFile*>::const_iterator AudioFileManagerIterator;

class AudioFileManager : public QObject, public XmlExportable
{
    Q_OBJECT
public:
    AudioFileManager();
    virtual ~AudioFileManager();
    
    class BadAudioPathException : public Exception
    {
    public:
        BadAudioPathException(std::string path) :
            Exception("Bad audio file path " + path), m_path(path) { }
        BadAudioPathException(std::string path, std::string file, int line) :
            Exception("Bad audio file path " + path, file, line), m_path(path) { }
        BadAudioPathException(const SoundFile::BadSoundFileException &e) :
            Exception("Bad audio file path (malformed file?) " + e.getPath()), m_path(e.getPath()) { }

        ~BadAudioPathException() throw() { }

        std::string getPath() const { return m_path; }

    private:
        std::string m_path;
    };

private:
    AudioFileManager(const AudioFileManager &aFM);
    AudioFileManager& operator=(const AudioFileManager &);

public:

    // Create an audio file from an absolute path - we use this interface
    // to add an actual file.
    //
    AudioFileId addFile(const std::string &filePath);
    // throw BadAudioPathException

    // Return true if a file would require importFile to import it, rather
    // than a simple addFile.  You can use importFile even when a file
    // doesn't need conversion, but this tells you whether it's necessary
    //
    bool fileNeedsConversion(const std::string &filePath,
                             int targetSampleRate = 0);

    // Create an audio file by importing (i.e. converting and/or
    // resampling) an existing file using the external conversion
    // utility
    //
    AudioFileId importFile(const std::string &filePath,
			   int targetSampleRate = 0);
    // throw BadAudioPathException, BadSoundFileException

    // Create an audio file by importing from a URL
    //
    AudioFileId importURL(const KURL &filePath,
			  int targetSampleRate = 0);
    // throw BadAudioPathException, BadSoundFileException

    // Insert an audio file into the AudioFileManager and get the
    // first allocated id for it.  Used from the RG file as we already
    // have both name and filename/path.
    //
    AudioFileId insertFile(const std::string &name,
                           const std::string &fileName);
    // throw BadAudioPathException

    // And insert an AudioFile and specify an id
    //
    bool insertFile(const std::string &name, const std::string &fileName,
                    AudioFileId id);
    // throw BadAudioPathException

    // Remove a file from the AudioManager by id
    //
    bool removeFile(AudioFileId id);

    // Does a specific file id exist?
    //
    bool fileExists(AudioFileId id);

    // Does a specific file path exist?  Return ID or -1.
    //
    int fileExists(const std::string &path);

    // get audio file by id
    //
    AudioFile* getAudioFile(AudioFileId id);

    // Get the list of files
    //
    std::vector<AudioFile*>::const_iterator begin() const
        { return m_audioFiles.begin(); }

    std::vector<AudioFile*>::const_iterator end() const
        { return m_audioFiles.end(); }

    // Clear down all audio file references
    //
    void clear();

    // Get and set the record path
    //
    std::string getAudioPath() const { return m_audioPath; }
    void setAudioPath(const std::string &path);

    // Throw if the current audio path does not exist or is not writable
    //
    void testAudioPath() throw(BadAudioPathException);

    // Get a new audio filename at the audio record path
    //
    AudioFile *createRecordingAudioFile();
    // throw BadAudioPathException

    // Get a set of new audio filenames at the audio record path
    //
    std::vector<std::string> createRecordingAudioFiles(unsigned int number);
    // throw BadAudioPathException

    // Return whether a file was created by recording within this "session"
    //
    bool wasAudioFileRecentlyRecorded(AudioFileId id);

    // Return whether a file was created by derivation within this "session"
    //
    bool wasAudioFileRecentlyDerived(AudioFileId id);

    // Indicate that a new "session" has started from the point of
    // view of recorded and derived audio files (e.g. that the
    // document has been saved)
    //
    void resetRecentlyCreatedFiles();
    
    // Create an empty file "derived from" the source (used by e.g. stretcher)
    // 
    AudioFile *createDerivedAudioFile(AudioFileId source,
				      const char *prefix);

    // return the last file in the vector - the last created
    //
    AudioFile* getLastAudioFile();

    // Export to XML
    //
    virtual std::string toXmlString();

    // Convenience function generate all previews on the audio file.
    //
    void generatePreviews();
    // throw BadSoundFileException, BadPeakFileException

    // Generate for a single audio file
    //
    bool generatePreview(AudioFileId id);
    // throw BadSoundFileException, BadPeakFileException

    // Get a preview for an AudioFile adjusted to Segment start and
    // end parameters (assuming they fall within boundaries).
    // 
    // We can get back a set of values (floats) or a Pixmap if we 
    // supply the details.
    //
    std::vector<float> getPreview(AudioFileId id,
                                  const RealTime &startTime, 
                                  const RealTime &endTime,
                                  int width,
                                  bool withMinima);
    // throw BadPeakFileException, BadAudioPathException

    // Draw a fixed size (fixed by QPixmap) preview of an audio file
    //
    void drawPreview(AudioFileId id,
                     const RealTime &startTime, 
                     const RealTime &endTime,
                     QPixmap *pixmap);
    // throw BadPeakFileException, BadAudioPathException

    // Usually used to show how an audio Segment makes up part of
    // an audio file.
    //
    void drawHighlightedPreview(AudioFileId it,
                                const RealTime &startTime,
                                const RealTime &endTime,
                                const RealTime &highlightStart,
                                const RealTime &highlightEnd,
                                QPixmap *pixmap);
    // throw BadPeakFileException, BadAudioPathException

    // Get a short file name from a long one (with '/'s)
    //
    std::string getShortFilename(const std::string &fileName);

    // Get a directory from a full file path
    //
    std::string getDirectory(const std::string &path);

    // Attempt to subsititute a tilde '~' for a home directory
    // to make paths a little more generic when saving.  Also
    // provide the inverse function as convenience here.
    //
    std::string substituteHomeForTilde(const std::string &path);
    std::string substituteTildeForHome(const std::string &path);

    // Show entries for debug purposes
    //
    void print(); 

    // Get a split point vector from a peak file
    //
    std::vector<SplitPointPair> 
        getSplitPoints(AudioFileId id,
                       const RealTime &startTime,
                       const RealTime &endTime,
                       int threshold,
                       const RealTime &minTime = RealTime(0, 100000000));
    // throw BadPeakFileException, BadAudioPathException

    // Get the peak file manager
    //
    const PeakFileManager& getPeakFileManager() const { return m_peakManager; }

    // Get the peak file manager
    //
    PeakFileManager& getPeakFileManager() { return m_peakManager; }

    int getExpectedSampleRate() const { return m_expectedSampleRate; }
    void setExpectedSampleRate(int rate) { m_expectedSampleRate = rate; }

    std::set<int> getActualSampleRates() const;

signals:
    void setProgress(int);
    void setOperationName(QString);

public slots:
    // Cancel a running preview
    //
    void slotStopPreview();

    void slotStopImport();

private:
    std::string getFileInPath(const std::string &file);

    AudioFileId getFirstUnusedID();

    std::vector<AudioFile*> m_audioFiles;
    std::string m_audioPath;

    PeakFileManager m_peakManager;

    // All audio files are stored in m_audioFiles.  These additional
    // sets of pointers just refer to those that have been created by
    // recording or derivations within the current session, and thus
    // that the user may wish to remove at the end of the session if
    // the document is not saved.
    std::set<AudioFile *> m_recordedAudioFiles;
    std::set<AudioFile *> m_derivedAudioFiles;

    KProcess *m_importProcess;

    int m_expectedSampleRate;
};

}

#endif // _AUDIOFILEMANAGER_H_