/* Rosegarden A sequencer and musical notation editor. This program is Copyright 2000-2008 Guillaume Laurent , Chris Cannam , Richard Bown 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 _SOUNDFILE_H_ #define _SOUNDFILE_H_ // SoundFile is an abstract base class defining behaviour for both // MidiFiles and AudioFiles. The getBytes routine is buffered into // suitably sized chunks to prevent excessive file reads. // // #include #include #include #include "Exception.h" namespace Rosegarden { // Constants related to RIFF/WAV files // const std::string AUDIO_RIFF_ID = "RIFF"; const std::string AUDIO_WAVE_ID = "WAVE"; const std::string AUDIO_FORMAT_ID = "fmt "; // Always four bytes const std::string AUDIO_BWF_ID = "bext"; // BWF chunk id const std::string AUDIO_BWF_PEAK_ID = "levl"; // BWF peak chunk id const float SAMPLE_MAX_8BIT = (float)(0xff); const float SAMPLE_MAX_16BIT = (float)(0xffff/2); const float SAMPLE_MAX_24BIT = (float)(0xffffff/2); typedef unsigned char FileByte; class SoundFile { public: SoundFile(const std::string &fileName); virtual ~SoundFile(); class BadSoundFileException : public Exception { public: BadSoundFileException(std::string path) : Exception("Bad sound file " + path), m_path(path) { } BadSoundFileException(std::string path, std::string message) : Exception("Bad sound file " + path + ": " + message), m_path(path) { } BadSoundFileException(std::string path, std::string file, int line) : Exception("Bad sound file " + path, file, line), m_path(path) { } ~BadSoundFileException() throw() { } std::string getPath() const { return m_path; } private: std::string m_path; }; // All files should be able open, write and close virtual bool open() = 0; virtual bool write() = 0; virtual void close() = 0; std::string getShortFilename() const; std::string getFilename() const { return m_fileName; } void setFilename(const std::string &fileName) { m_fileName = fileName; } // Useful methods that operate on our file data // int getIntegerFromLittleEndian(const std::string &s); std::string getLittleEndianFromInteger(unsigned int value, unsigned int length); int getIntegerFromBigEndian(const std::string &s); std::string getBigEndianFromInteger(unsigned int value, unsigned int length); // Buffered read - allow this to be public // std::string getBytes(unsigned int numberOfBytes); // Return file size // unsigned int getSize() const { return m_fileSize; } void resetStream() { m_inFile->seekg(0); m_inFile->clear(); } // check EOF status // bool isEof() const { if (m_inFile) return m_inFile->eof(); else return true; } protected: std::string m_fileName; // get some bytes from an input stream - unbuffered as we can // modify the file stream std::string getBytes(std::ifstream *file, unsigned int numberOfBytes); // Get n bytes from an input stream and write them into buffer. // Return the actual number of bytes read. size_t getBytes(std::ifstream *file, char *buffer, size_t n); // write some bytes to an output stream void putBytes(std::ofstream *file, const std::string outputString); // write some bytes to an output stream void putBytes(std::ofstream *file, const char *buffer, size_t n); // Read buffering - define chunk size and buffer file reading // int m_readChunkPtr; int m_readChunkSize; std::string m_readBuffer; std::ifstream *m_inFile; std::ofstream *m_outFile; bool m_loseBuffer; // do we need to dump the read buffer // and re-fill it? unsigned int m_fileSize; }; } #endif // _SOUNDFILE_H_