annotate data/fileio/MIDIFileReader.h @ 1728:a47a23c824ac

Merge
author Chris Cannam
date Wed, 22 May 2019 15:37:44 +0100
parents c01cbe41aeb5
children
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 This is a modified version of a source file from the
Chris@148 17 Rosegarden MIDI and audio sequencer and notation editor.
Chris@148 18 This file copyright 2000-2006 Richard Bown and Chris Cannam.
Chris@148 19 */
Chris@148 20
Chris@1359 21 #ifndef SV_MIDI_FILE_READER_H
Chris@1359 22 #define SV_MIDI_FILE_READER_H
Chris@148 23
Chris@148 24 #include "DataFileReader.h"
Chris@148 25 #include "base/RealTime.h"
Chris@148 26
Chris@148 27 #include <map>
Chris@148 28 #include <set>
Chris@148 29 #include <vector>
Chris@148 30
Chris@148 31 #include <QObject>
Chris@148 32
Chris@148 33 class MIDIEvent;
Chris@1491 34 class ProgressReporter;
Chris@148 35
Chris@301 36 typedef unsigned char MIDIByte;
Chris@301 37
Chris@392 38 class MIDIFileImportPreferenceAcquirer // welcome to our grand marble foyer
Chris@392 39 {
Chris@392 40 public:
Chris@392 41 enum TrackPreference {
Chris@392 42 ImportNothing,
Chris@392 43 ImportSingleTrack,
Chris@392 44 MergeAllTracks,
Chris@392 45 MergeAllNonPercussionTracks
Chris@392 46 };
Chris@392 47
Chris@392 48 virtual ~MIDIFileImportPreferenceAcquirer() { }
Chris@392 49
Chris@392 50 virtual TrackPreference getTrackImportPreference
Chris@392 51 (QStringList trackNames, bool haveSomePercussion,
Chris@392 52 QString &singleTrack) const = 0;
Chris@392 53
Chris@392 54 virtual void showError(QString error) = 0;
Chris@392 55 };
Chris@392 56
Chris@392 57
Chris@248 58 class MIDIFileReader : public DataFileReader
Chris@148 59 {
Chris@247 60 Q_OBJECT
Chris@247 61
Chris@148 62 public:
Chris@392 63 MIDIFileReader(QString path,
Chris@1359 64 MIDIFileImportPreferenceAcquirer *pref, // may be null
Chris@1491 65 sv_samplerate_t mainModelSampleRate,
Chris@1491 66 ProgressReporter *reporter = 0);
Chris@148 67 virtual ~MIDIFileReader();
Chris@148 68
Chris@1580 69 bool isOK() const override;
Chris@1580 70 QString getError() const override;
Chris@1580 71 Model *load() const override;
Chris@148 72
Chris@148 73 protected:
Chris@148 74 typedef std::vector<MIDIEvent *> MIDITrack;
Chris@148 75 typedef std::map<unsigned int, MIDITrack> MIDIComposition;
Chris@148 76 typedef std::pair<RealTime, double> TempoChange; // time, qpm
Chris@148 77 typedef std::map<unsigned long, TempoChange> TempoMap; // key is MIDI time
Chris@148 78
Chris@148 79 typedef enum {
Chris@1429 80 MIDI_SINGLE_TRACK_FILE = 0x00,
Chris@1429 81 MIDI_SIMULTANEOUS_TRACK_FILE = 0x01,
Chris@1429 82 MIDI_SEQUENTIAL_TRACK_FILE = 0x02,
Chris@1429 83 MIDI_FILE_BAD_FORMAT = 0xFF
Chris@148 84 } MIDIFileFormatType;
Chris@148 85
Chris@148 86 bool parseFile();
Chris@148 87 bool parseHeader(const std::string &midiHeader);
Chris@148 88 bool parseTrack(unsigned int &trackNum);
Chris@148 89
Chris@148 90 Model *loadTrack(unsigned int trackNum,
Chris@1429 91 Model *existingModel = 0,
Chris@1429 92 int minProgress = 0,
Chris@1429 93 int progressAmount = 100) const;
Chris@148 94
Chris@148 95 bool consolidateNoteOffEvents(unsigned int track);
Chris@148 96 void updateTempoMap(unsigned int track);
Chris@148 97 void calculateTempoTimestamps();
Chris@148 98 RealTime getTimeForMIDITime(unsigned long midiTime) const;
Chris@148 99
Chris@148 100 // Internal convenience functions
Chris@148 101 //
Chris@148 102 int midiBytesToInt(const std::string &bytes);
Chris@148 103 long midiBytesToLong(const std::string &bytes);
Chris@148 104
Chris@148 105 long getNumberFromMIDIBytes(int firstByte = -1);
Chris@148 106
Chris@148 107 MIDIByte getMIDIByte();
Chris@148 108 std::string getMIDIBytes(unsigned long bytes);
Chris@148 109
Chris@148 110 bool skipToNextTrack();
Chris@148 111
Chris@613 112 bool m_smpte;
Chris@148 113 int m_timingDivision; // pulses per quarter note
Chris@613 114 int m_fps; // if smpte
Chris@613 115 int m_subframes; // if smpte
Chris@148 116 MIDIFileFormatType m_format;
Chris@148 117 unsigned int m_numberOfTracks;
Chris@148 118
Chris@148 119 long m_trackByteCount;
Chris@148 120 bool m_decrementCount;
Chris@148 121
Chris@148 122 std::map<int, QString> m_trackNames;
Chris@148 123 std::set<unsigned int> m_loadableTracks;
Chris@148 124 std::set<unsigned int> m_percussionTracks;
Chris@148 125 MIDIComposition m_midiComposition;
Chris@148 126 TempoMap m_tempoMap;
Chris@148 127
Chris@148 128 QString m_path;
Chris@148 129 std::ifstream *m_midiFile;
Chris@1038 130 size_t m_fileSize;
Chris@148 131 QString m_error;
Chris@1047 132 sv_samplerate_t m_mainModelSampleRate;
Chris@392 133
Chris@392 134 MIDIFileImportPreferenceAcquirer *m_acquirer;
Chris@148 135 };
Chris@148 136
Chris@148 137
Chris@148 138 #endif // _MIDI_FILE_READER_H_