Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 : #pragma once
23 :
24 : #include <vector>
25 : #include <QIODevice>
26 :
27 : #include "../midishared/midievent.h"
28 :
29 : namespace mu::iex::midi {
30 : class MidiTrack
31 : {
32 : std::multimap<int, MidiEvent> _events;
33 : int _outChannel;
34 : int _outPort;
35 : bool _drumTrack;
36 :
37 : public:
38 : MidiTrack();
39 : ~MidiTrack();
40 :
41 : bool empty() const;
42 1184 : const std::multimap<int, MidiEvent>& events() const { return _events; }
43 589 : std::multimap<int, MidiEvent>& events() { return _events; }
44 :
45 2431 : int outChannel() const { return _outChannel; }
46 : void setOutChannel(int n);
47 453 : int outPort() const { return _outPort; }
48 335 : void setOutPort(int n) { _outPort = n; }
49 :
50 2783 : bool drumTrack() const { return _drumTrack; }
51 :
52 : void insert(int tick, const MidiEvent&);
53 : void mergeNoteOnOff();
54 : };
55 :
56 : //---------------------------------------------------------
57 : // MidiFile
58 : //---------------------------------------------------------
59 :
60 : class MidiFile
61 : {
62 : QIODevice* fp;
63 : std::vector<MidiTrack> _tracks;
64 : int _division;
65 : bool _isDivisionInTps; ///< ticks per second, alternative - ticks per beat
66 : int _format; ///< midi file format (0-2)
67 : bool _noRunningStatus; ///< do not use running status on output
68 :
69 : // values used during read()
70 : int status; ///< running status
71 : int sstatus; ///< running status (not reset after meta or sysex events)
72 : int click; ///< current tick position in file
73 : qint64 curPos; ///< current file byte position
74 :
75 : void writeEvent(const MidiEvent& event);
76 :
77 : protected:
78 : // write
79 : bool write(const void*, qint64);
80 : void writeShort(int);
81 : void writeLong(int);
82 : bool writeTrack(const MidiTrack&);
83 : void putvl(unsigned);
84 8119 : void put(unsigned char c) { write(&c, 1); }
85 : void writeStatus(int type, int channel);
86 :
87 : // read
88 : void read(void*, qint64);
89 : int getvl();
90 : int readShort();
91 : int readLong();
92 : bool readEvent(MidiEvent*);
93 : bool readTrack();
94 :
95 514 : void resetRunningStatus() { status = -1; }
96 :
97 : public:
98 : MidiFile();
99 : bool read(QIODevice*);
100 : bool write(QIODevice*);
101 :
102 159 : std::vector<MidiTrack>& tracks() { return _tracks; }
103 200 : const std::vector<MidiTrack>& tracks() const { return _tracks; }
104 :
105 0 : int format() const { return _format; }
106 12 : void setFormat(int fmt) { _format = fmt; }
107 :
108 379 : int division() const { return _division; }
109 379 : bool isDivisionInTps() const { return _isDivisionInTps; }
110 12 : void setDivision(int val) { _division = val; }
111 : void separateChannel();
112 : };
113 : }
|