annotate data/fileio/MIDIFileReader.h @ 1310:aa1b1fc2d018 mp3-gapless

Stop reporting sync errors only when we really are at eof, i.e. after the input callback has been called again (previously we just tested whether we'd buffered up all the input, which of course we do in one go at the start)
author Chris Cannam
date Tue, 29 Nov 2016 16:45:29 +0000
parents 26cf6d5251ec
children 1c9bbbb6116a
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@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@392 64 MIDIFileImportPreferenceAcquirer *pref,
Chris@1047 65 sv_samplerate_t mainModelSampleRate);
Chris@148 66 virtual ~MIDIFileReader();
Chris@148 67
Chris@148 68 virtual bool isOK() const;
Chris@148 69 virtual QString getError() const;
Chris@148 70 virtual Model *load() const;
Chris@148 71
Chris@148 72 protected:
Chris@148 73 typedef std::vector<MIDIEvent *> MIDITrack;
Chris@148 74 typedef std::map<unsigned int, MIDITrack> MIDIComposition;
Chris@148 75 typedef std::pair<RealTime, double> TempoChange; // time, qpm
Chris@148 76 typedef std::map<unsigned long, TempoChange> TempoMap; // key is MIDI time
Chris@148 77
Chris@148 78 typedef enum {
Chris@148 79 MIDI_SINGLE_TRACK_FILE = 0x00,
Chris@148 80 MIDI_SIMULTANEOUS_TRACK_FILE = 0x01,
Chris@148 81 MIDI_SEQUENTIAL_TRACK_FILE = 0x02,
Chris@148 82 MIDI_FILE_BAD_FORMAT = 0xFF
Chris@148 83 } MIDIFileFormatType;
Chris@148 84
Chris@148 85 bool parseFile();
Chris@148 86 bool parseHeader(const std::string &midiHeader);
Chris@148 87 bool parseTrack(unsigned int &trackNum);
Chris@148 88
Chris@148 89 Model *loadTrack(unsigned int trackNum,
Chris@148 90 Model *existingModel = 0,
Chris@148 91 int minProgress = 0,
Chris@148 92 int progressAmount = 100) const;
Chris@148 93
Chris@148 94 bool consolidateNoteOffEvents(unsigned int track);
Chris@148 95 void updateTempoMap(unsigned int track);
Chris@148 96 void calculateTempoTimestamps();
Chris@148 97 RealTime getTimeForMIDITime(unsigned long midiTime) const;
Chris@148 98
Chris@148 99 // Internal convenience functions
Chris@148 100 //
Chris@148 101 int midiBytesToInt(const std::string &bytes);
Chris@148 102 long midiBytesToLong(const std::string &bytes);
Chris@148 103
Chris@148 104 long getNumberFromMIDIBytes(int firstByte = -1);
Chris@148 105
Chris@148 106 MIDIByte getMIDIByte();
Chris@148 107 std::string getMIDIBytes(unsigned long bytes);
Chris@148 108
Chris@148 109 bool skipToNextTrack();
Chris@148 110
Chris@613 111 bool m_smpte;
Chris@148 112 int m_timingDivision; // pulses per quarter note
Chris@613 113 int m_fps; // if smpte
Chris@613 114 int m_subframes; // if smpte
Chris@148 115 MIDIFileFormatType m_format;
Chris@148 116 unsigned int m_numberOfTracks;
Chris@148 117
Chris@148 118 long m_trackByteCount;
Chris@148 119 bool m_decrementCount;
Chris@148 120
Chris@148 121 std::map<int, QString> m_trackNames;
Chris@148 122 std::set<unsigned int> m_loadableTracks;
Chris@148 123 std::set<unsigned int> m_percussionTracks;
Chris@148 124 MIDIComposition m_midiComposition;
Chris@148 125 TempoMap m_tempoMap;
Chris@148 126
Chris@148 127 QString m_path;
Chris@148 128 std::ifstream *m_midiFile;
Chris@1038 129 size_t m_fileSize;
Chris@148 130 QString m_error;
Chris@1047 131 sv_samplerate_t m_mainModelSampleRate;
Chris@392 132
Chris@392 133 MIDIFileImportPreferenceAcquirer *m_acquirer;
Chris@148 134 };
Chris@148 135
Chris@148 136
Chris@148 137 #endif // _MIDI_FILE_READER_H_