annotate data/fileio/MIDIFileReader.h @ 377:166c22eff678

* Ensure waveforms are strictly correct even when using a non-power-of-two non-power-of-sqrt-two block size with cacheing off and painting only small areas at a time
author Chris Cannam
date Thu, 07 Feb 2008 15:25:05 +0000
parents 73537d900d4b
children 183ee2a55fc7
rev   line source
Chris@148 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@148 2
Chris@148 3 /*
Chris@148 4 Sonic Visualiser
Chris@148 5 An audio file viewer and annotation editor.
Chris@148 6 Centre for Digital Music, Queen Mary, University of London.
Chris@148 7
Chris@148 8 This program is free software; you can redistribute it and/or
Chris@148 9 modify it under the terms of the GNU General Public License as
Chris@148 10 published by the Free Software Foundation; either version 2 of the
Chris@148 11 License, or (at your option) any later version. See the file
Chris@148 12 COPYING included with this distribution for more information.
Chris@148 13 */
Chris@148 14
Chris@148 15
Chris@148 16 /*
Chris@148 17 This is a modified version of a source file from the
Chris@148 18 Rosegarden MIDI and audio sequencer and notation editor.
Chris@148 19 This file copyright 2000-2006 Richard Bown and Chris Cannam.
Chris@148 20 */
Chris@148 21
Chris@148 22 #ifndef _MIDI_FILE_READER_H_
Chris@148 23 #define _MIDI_FILE_READER_H_
Chris@148 24
Chris@148 25 #include "DataFileReader.h"
Chris@148 26 #include "base/RealTime.h"
Chris@148 27
Chris@148 28 #include <map>
Chris@148 29 #include <set>
Chris@148 30 #include <vector>
Chris@148 31
Chris@148 32 #include <QObject>
Chris@148 33
Chris@148 34 class MIDIEvent;
Chris@148 35
Chris@301 36 typedef unsigned char MIDIByte;
Chris@301 37
Chris@248 38 class MIDIFileReader : public DataFileReader
Chris@148 39 {
Chris@247 40 Q_OBJECT
Chris@247 41
Chris@148 42 public:
Chris@148 43 MIDIFileReader(QString path, size_t mainModelSampleRate);
Chris@148 44 virtual ~MIDIFileReader();
Chris@148 45
Chris@148 46 virtual bool isOK() const;
Chris@148 47 virtual QString getError() const;
Chris@148 48 virtual Model *load() const;
Chris@148 49
Chris@148 50 protected:
Chris@148 51 typedef std::vector<MIDIEvent *> MIDITrack;
Chris@148 52 typedef std::map<unsigned int, MIDITrack> MIDIComposition;
Chris@148 53 typedef std::pair<RealTime, double> TempoChange; // time, qpm
Chris@148 54 typedef std::map<unsigned long, TempoChange> TempoMap; // key is MIDI time
Chris@148 55
Chris@148 56 typedef enum {
Chris@148 57 MIDI_SINGLE_TRACK_FILE = 0x00,
Chris@148 58 MIDI_SIMULTANEOUS_TRACK_FILE = 0x01,
Chris@148 59 MIDI_SEQUENTIAL_TRACK_FILE = 0x02,
Chris@148 60 MIDI_FILE_BAD_FORMAT = 0xFF
Chris@148 61 } MIDIFileFormatType;
Chris@148 62
Chris@148 63 bool parseFile();
Chris@148 64 bool parseHeader(const std::string &midiHeader);
Chris@148 65 bool parseTrack(unsigned int &trackNum);
Chris@148 66
Chris@148 67 Model *loadTrack(unsigned int trackNum,
Chris@148 68 Model *existingModel = 0,
Chris@148 69 int minProgress = 0,
Chris@148 70 int progressAmount = 100) const;
Chris@148 71
Chris@148 72 bool consolidateNoteOffEvents(unsigned int track);
Chris@148 73 void updateTempoMap(unsigned int track);
Chris@148 74 void calculateTempoTimestamps();
Chris@148 75 RealTime getTimeForMIDITime(unsigned long midiTime) const;
Chris@148 76
Chris@148 77 // Internal convenience functions
Chris@148 78 //
Chris@148 79 int midiBytesToInt(const std::string &bytes);
Chris@148 80 long midiBytesToLong(const std::string &bytes);
Chris@148 81
Chris@148 82 long getNumberFromMIDIBytes(int firstByte = -1);
Chris@148 83
Chris@148 84 MIDIByte getMIDIByte();
Chris@148 85 std::string getMIDIBytes(unsigned long bytes);
Chris@148 86
Chris@148 87 bool skipToNextTrack();
Chris@148 88
Chris@148 89 int m_timingDivision; // pulses per quarter note
Chris@148 90 MIDIFileFormatType m_format;
Chris@148 91 unsigned int m_numberOfTracks;
Chris@148 92
Chris@148 93 long m_trackByteCount;
Chris@148 94 bool m_decrementCount;
Chris@148 95
Chris@148 96 std::map<int, QString> m_trackNames;
Chris@148 97 std::set<unsigned int> m_loadableTracks;
Chris@148 98 std::set<unsigned int> m_percussionTracks;
Chris@148 99 MIDIComposition m_midiComposition;
Chris@148 100 TempoMap m_tempoMap;
Chris@148 101
Chris@148 102 QString m_path;
Chris@148 103 std::ifstream *m_midiFile;
Chris@148 104 size_t m_fileSize;
Chris@148 105 QString m_error;
Chris@148 106 size_t m_mainModelSampleRate;
Chris@148 107 };
Chris@148 108
Chris@148 109
Chris@148 110 #endif // _MIDI_FILE_READER_H_