svcore
1.9
|
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 MIDIFileImportPreferenceAcquirer // welcome to our grand marble foyer 00039 { 00040 public: 00041 enum TrackPreference { 00042 ImportNothing, 00043 ImportSingleTrack, 00044 MergeAllTracks, 00045 MergeAllNonPercussionTracks 00046 }; 00047 00048 virtual ~MIDIFileImportPreferenceAcquirer() { } 00049 00050 virtual TrackPreference getTrackImportPreference 00051 (QStringList trackNames, bool haveSomePercussion, 00052 QString &singleTrack) const = 0; 00053 00054 virtual void showError(QString error) = 0; 00055 }; 00056 00057 00058 class MIDIFileReader : public DataFileReader 00059 { 00060 Q_OBJECT 00061 00062 public: 00063 MIDIFileReader(QString path, 00064 MIDIFileImportPreferenceAcquirer *pref, 00065 int mainModelSampleRate); 00066 virtual ~MIDIFileReader(); 00067 00068 virtual bool isOK() const; 00069 virtual QString getError() const; 00070 virtual Model *load() const; 00071 00072 protected: 00073 typedef std::vector<MIDIEvent *> MIDITrack; 00074 typedef std::map<unsigned int, MIDITrack> MIDIComposition; 00075 typedef std::pair<RealTime, double> TempoChange; // time, qpm 00076 typedef std::map<unsigned long, TempoChange> TempoMap; // key is MIDI time 00077 00078 typedef enum { 00079 MIDI_SINGLE_TRACK_FILE = 0x00, 00080 MIDI_SIMULTANEOUS_TRACK_FILE = 0x01, 00081 MIDI_SEQUENTIAL_TRACK_FILE = 0x02, 00082 MIDI_FILE_BAD_FORMAT = 0xFF 00083 } MIDIFileFormatType; 00084 00085 bool parseFile(); 00086 bool parseHeader(const std::string &midiHeader); 00087 bool parseTrack(unsigned int &trackNum); 00088 00089 Model *loadTrack(unsigned int trackNum, 00090 Model *existingModel = 0, 00091 int minProgress = 0, 00092 int progressAmount = 100) const; 00093 00094 bool consolidateNoteOffEvents(unsigned int track); 00095 void updateTempoMap(unsigned int track); 00096 void calculateTempoTimestamps(); 00097 RealTime getTimeForMIDITime(unsigned long midiTime) const; 00098 00099 // Internal convenience functions 00100 // 00101 int midiBytesToInt(const std::string &bytes); 00102 long midiBytesToLong(const std::string &bytes); 00103 00104 long getNumberFromMIDIBytes(int firstByte = -1); 00105 00106 MIDIByte getMIDIByte(); 00107 std::string getMIDIBytes(unsigned long bytes); 00108 00109 bool skipToNextTrack(); 00110 00111 bool m_smpte; 00112 int m_timingDivision; // pulses per quarter note 00113 int m_fps; // if smpte 00114 int m_subframes; // if smpte 00115 MIDIFileFormatType m_format; 00116 unsigned int m_numberOfTracks; 00117 00118 long m_trackByteCount; 00119 bool m_decrementCount; 00120 00121 std::map<int, QString> m_trackNames; 00122 std::set<unsigned int> m_loadableTracks; 00123 std::set<unsigned int> m_percussionTracks; 00124 MIDIComposition m_midiComposition; 00125 TempoMap m_tempoMap; 00126 00127 QString m_path; 00128 std::ifstream *m_midiFile; 00129 int m_fileSize; 00130 QString m_error; 00131 int m_mainModelSampleRate; 00132 00133 MIDIFileImportPreferenceAcquirer *m_acquirer; 00134 }; 00135 00136 00137 #endif // _MIDI_FILE_READER_H_