MIDIFileReader.h

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     
00008     This program is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU General Public License as
00010     published by the Free Software Foundation; either version 2 of the
00011     License, or (at your option) any later version.  See the file
00012     COPYING included with this distribution for more information.
00013 */
00014 
00015 
00016 /*
00017    This is a modified version of a source file from the 
00018    Rosegarden MIDI and audio sequencer and notation editor.
00019    This file copyright 2000-2006 Richard Bown and Chris Cannam.
00020 */
00021 
00022 #ifndef _MIDI_FILE_READER_H_
00023 #define _MIDI_FILE_READER_H_
00024 
00025 #include "DataFileReader.h"
00026 #include "base/RealTime.h"
00027 
00028 #include <map>
00029 #include <set>
00030 #include <vector>
00031 
00032 #include <QObject>
00033 
00034 class MIDIEvent;
00035 
00036 typedef unsigned char MIDIByte;
00037 
00038 class MIDIFileReader : public DataFileReader
00039 {
00040     Q_OBJECT
00041 
00042 public:
00043     MIDIFileReader(QString path, size_t mainModelSampleRate);
00044     virtual ~MIDIFileReader();
00045 
00046     virtual bool isOK() const;
00047     virtual QString getError() const;
00048     virtual Model *load() const;
00049 
00050 protected:
00051     typedef std::vector<MIDIEvent *> MIDITrack;
00052     typedef std::map<unsigned int, MIDITrack> MIDIComposition;
00053     typedef std::pair<RealTime, double> TempoChange; // time, qpm
00054     typedef std::map<unsigned long, TempoChange> TempoMap; // key is MIDI time
00055 
00056     typedef enum {
00057         MIDI_SINGLE_TRACK_FILE          = 0x00,
00058         MIDI_SIMULTANEOUS_TRACK_FILE    = 0x01,
00059         MIDI_SEQUENTIAL_TRACK_FILE      = 0x02,
00060         MIDI_FILE_BAD_FORMAT            = 0xFF
00061     } MIDIFileFormatType;
00062 
00063     bool parseFile();
00064     bool parseHeader(const std::string &midiHeader);
00065     bool parseTrack(unsigned int &trackNum);
00066 
00067     Model *loadTrack(unsigned int trackNum,
00068                      Model *existingModel = 0,
00069                      int minProgress = 0,
00070                      int progressAmount = 100) const;
00071 
00072     bool consolidateNoteOffEvents(unsigned int track);
00073     void updateTempoMap(unsigned int track);
00074     void calculateTempoTimestamps();
00075     RealTime getTimeForMIDITime(unsigned long midiTime) const;
00076 
00077     // Internal convenience functions
00078     //
00079     int  midiBytesToInt(const std::string &bytes);
00080     long midiBytesToLong(const std::string &bytes);
00081 
00082     long getNumberFromMIDIBytes(int firstByte = -1);
00083 
00084     MIDIByte getMIDIByte();
00085     std::string getMIDIBytes(unsigned long bytes);
00086 
00087     bool skipToNextTrack();
00088 
00089     int                    m_timingDivision;   // pulses per quarter note
00090     MIDIFileFormatType     m_format;
00091     unsigned int           m_numberOfTracks;
00092 
00093     long                   m_trackByteCount;
00094     bool                   m_decrementCount;
00095 
00096     std::map<int, QString> m_trackNames;
00097     std::set<unsigned int> m_loadableTracks;
00098     std::set<unsigned int> m_percussionTracks;
00099     MIDIComposition        m_midiComposition;
00100     TempoMap               m_tempoMap;
00101 
00102     QString                m_path;
00103     std::ifstream         *m_midiFile;
00104     size_t                 m_fileSize;
00105     QString                m_error;
00106     size_t                 m_mainModelSampleRate;
00107 };
00108 
00109 
00110 #endif // _MIDI_FILE_READER_H_

Generated on Wed Feb 20 15:45:26 2008 for SonicVisualiser by  doxygen 1.5.1