diff options
Diffstat (limited to 'src/sound/AudioFileManager.h')
-rw-r--r-- | src/sound/AudioFileManager.h | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/src/sound/AudioFileManager.h b/src/sound/AudioFileManager.h new file mode 100644 index 0000000..9721669 --- /dev/null +++ b/src/sound/AudioFileManager.h @@ -0,0 +1,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_ |