lbajardsilogic@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ lbajardsilogic@0: lbajardsilogic@0: /* lbajardsilogic@0: Sonic Visualiser lbajardsilogic@0: An audio file viewer and annotation editor. lbajardsilogic@0: Centre for Digital Music, Queen Mary, University of London. lbajardsilogic@0: lbajardsilogic@0: This program is free software; you can redistribute it and/or lbajardsilogic@0: modify it under the terms of the GNU General Public License as lbajardsilogic@0: published by the Free Software Foundation; either version 2 of the lbajardsilogic@0: License, or (at your option) any later version. See the file lbajardsilogic@0: COPYING included with this distribution for more information. lbajardsilogic@0: */ lbajardsilogic@0: lbajardsilogic@0: lbajardsilogic@0: /* lbajardsilogic@0: This is a modified version of a source file from the lbajardsilogic@0: Rosegarden MIDI and audio sequencer and notation editor. lbajardsilogic@0: This file copyright 2000-2006 Richard Bown and Chris Cannam. lbajardsilogic@0: */ lbajardsilogic@0: lbajardsilogic@0: #ifndef _MIDI_FILE_READER_H_ lbajardsilogic@0: #define _MIDI_FILE_READER_H_ lbajardsilogic@0: lbajardsilogic@0: #include "DataFileReader.h" lbajardsilogic@0: #include "base/RealTime.h" lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: class MIDIEvent; lbajardsilogic@0: lbajardsilogic@0: class MIDIFileReader : public DataFileReader lbajardsilogic@0: { lbajardsilogic@0: Q_OBJECT lbajardsilogic@0: lbajardsilogic@0: public: lbajardsilogic@0: MIDIFileReader(QString path, size_t mainModelSampleRate); lbajardsilogic@0: virtual ~MIDIFileReader(); lbajardsilogic@0: lbajardsilogic@0: virtual bool isOK() const; lbajardsilogic@0: virtual QString getError() const; lbajardsilogic@0: virtual Model *load() const; lbajardsilogic@0: lbajardsilogic@0: typedef unsigned char MIDIByte; lbajardsilogic@0: lbajardsilogic@0: protected: lbajardsilogic@0: typedef std::vector MIDITrack; lbajardsilogic@0: typedef std::map MIDIComposition; lbajardsilogic@0: typedef std::pair TempoChange; // time, qpm lbajardsilogic@0: typedef std::map TempoMap; // key is MIDI time lbajardsilogic@0: lbajardsilogic@0: typedef enum { lbajardsilogic@0: MIDI_SINGLE_TRACK_FILE = 0x00, lbajardsilogic@0: MIDI_SIMULTANEOUS_TRACK_FILE = 0x01, lbajardsilogic@0: MIDI_SEQUENTIAL_TRACK_FILE = 0x02, lbajardsilogic@0: MIDI_FILE_BAD_FORMAT = 0xFF lbajardsilogic@0: } MIDIFileFormatType; lbajardsilogic@0: lbajardsilogic@0: bool parseFile(); lbajardsilogic@0: bool parseHeader(const std::string &midiHeader); lbajardsilogic@0: bool parseTrack(unsigned int &trackNum); lbajardsilogic@0: lbajardsilogic@0: Model *loadTrack(unsigned int trackNum, lbajardsilogic@0: Model *existingModel = 0, lbajardsilogic@0: int minProgress = 0, lbajardsilogic@0: int progressAmount = 100) const; lbajardsilogic@0: lbajardsilogic@0: bool consolidateNoteOffEvents(unsigned int track); lbajardsilogic@0: void updateTempoMap(unsigned int track); lbajardsilogic@0: void calculateTempoTimestamps(); lbajardsilogic@0: RealTime getTimeForMIDITime(unsigned long midiTime) const; lbajardsilogic@0: lbajardsilogic@0: // Internal convenience functions lbajardsilogic@0: // lbajardsilogic@0: int midiBytesToInt(const std::string &bytes); lbajardsilogic@0: long midiBytesToLong(const std::string &bytes); lbajardsilogic@0: lbajardsilogic@0: long getNumberFromMIDIBytes(int firstByte = -1); lbajardsilogic@0: lbajardsilogic@0: MIDIByte getMIDIByte(); lbajardsilogic@0: std::string getMIDIBytes(unsigned long bytes); lbajardsilogic@0: lbajardsilogic@0: bool skipToNextTrack(); lbajardsilogic@0: lbajardsilogic@0: int m_timingDivision; // pulses per quarter note lbajardsilogic@0: MIDIFileFormatType m_format; lbajardsilogic@0: unsigned int m_numberOfTracks; lbajardsilogic@0: lbajardsilogic@0: long m_trackByteCount; lbajardsilogic@0: bool m_decrementCount; lbajardsilogic@0: lbajardsilogic@0: std::map m_trackNames; lbajardsilogic@0: std::set m_loadableTracks; lbajardsilogic@0: std::set m_percussionTracks; lbajardsilogic@0: MIDIComposition m_midiComposition; lbajardsilogic@0: TempoMap m_tempoMap; lbajardsilogic@0: lbajardsilogic@0: QString m_path; lbajardsilogic@0: std::ifstream *m_midiFile; lbajardsilogic@0: size_t m_fileSize; lbajardsilogic@0: QString m_error; lbajardsilogic@0: size_t m_mainModelSampleRate; lbajardsilogic@0: }; lbajardsilogic@0: lbajardsilogic@0: lbajardsilogic@0: #endif // _MIDI_FILE_READER_H_