1 //============================================================================= 2 // MuseScore 3 // Music Composition & Notation 4 // 5 // Copyright (C) 2002-2011 Werner Schweer 6 // 7 // This program is free software; you can redistribute it and/or modify 8 // it under the terms of the GNU General Public License version 2 9 // as published by the Free Software Foundation and appearing in 10 // the file LICENCE.GPL 11 //============================================================================= 12 13 #ifndef __MIDIFILE_H__ 14 #define __MIDIFILE_H__ 15 16 #include "libmscore/sig.h" 17 #include "event.h" 18 19 namespace Ms { 20 21 const int MIDI_CHANNEL = 16; 22 23 //--------------------------------------------------------- 24 // MidiType 25 //--------------------------------------------------------- 26 27 enum class MidiType : char { 28 UNKNOWN = 0, GM = 1, GS = 2, XG = 4 29 }; 30 31 class MidiFile; 32 class Xml; 33 34 //--------------------------------------------------------- 35 // MidiTrack 36 //--------------------------------------------------------- 37 38 class MidiTrack { 39 std::multimap<int, MidiEvent> _events; 40 int _outChannel; 41 int _outPort; 42 bool _drumTrack; 43 44 protected: 45 void readXml(XmlReader&); 46 47 public: 48 MidiTrack(); 49 ~MidiTrack(); 50 51 bool empty() const; events()52 const std::multimap<int, MidiEvent>& events() const { return _events; } events()53 std::multimap<int, MidiEvent>& events() { return _events; } 54 outChannel()55 int outChannel() const { return _outChannel; } 56 void setOutChannel(int n); outPort()57 int outPort() const { return _outPort; } setOutPort(int n)58 void setOutPort(int n) { _outPort = n; } 59 drumTrack()60 bool drumTrack() const { return _drumTrack; } 61 62 void insert(int tick, const MidiEvent&); 63 void mergeNoteOnOffAndFindMidiType(MidiType *mt); 64 }; 65 66 //--------------------------------------------------------- 67 // MidiFile 68 //--------------------------------------------------------- 69 70 class MidiFile { 71 QIODevice* fp; 72 QList<MidiTrack> _tracks; 73 int _division; 74 bool _isDivisionInTps; ///< ticks per second, alternative - ticks per beat 75 int _format; ///< midi file format (0-2) 76 bool _noRunningStatus; ///< do not use running status on output 77 MidiType _midiType; 78 79 // values used during read() 80 int status; ///< running status 81 int sstatus; ///< running status (not reset after meta or sysex events) 82 int click; ///< current tick position in file 83 qint64 curPos; ///< current file byte position 84 85 void writeEvent(const MidiEvent& event); 86 87 protected: 88 // write 89 bool write(const void*, qint64); 90 void writeShort(int); 91 void writeLong(int); 92 bool writeTrack(const MidiTrack &); 93 void putvl(unsigned); put(unsigned char c)94 void put(unsigned char c) { write(&c, 1); } 95 void writeStatus(int type, int channel); 96 97 // read 98 void read(void*, qint64); 99 int getvl(); 100 int readShort(); 101 int readLong(); 102 bool readEvent(MidiEvent*); 103 bool readTrack(); 104 void skip(qint64); 105 resetRunningStatus()106 void resetRunningStatus() { status = -1; } 107 108 public: 109 MidiFile(); 110 bool read(QIODevice*); 111 bool write(QIODevice*); 112 void readXml(XmlReader&); 113 tracks()114 QList<MidiTrack>& tracks() { return _tracks; } tracks()115 const QList<MidiTrack>& tracks() const { return _tracks; } 116 midiType()117 MidiType midiType() const { return _midiType; } setMidiType(MidiType mt)118 void setMidiType(MidiType mt) { _midiType = mt; } 119 format()120 int format() const { return _format; } setFormat(int fmt)121 void setFormat(int fmt) { _format = fmt; } 122 division()123 int division() const { return _division; } isDivisionInTps()124 bool isDivisionInTps() const { return _isDivisionInTps; } setDivision(int val)125 void setDivision(int val) { _division = val; } 126 void separateChannel(); 127 }; 128 } 129 #endif 130 131