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) 2022 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 :
23 : #ifndef MU_ENGRAVING_COMPAT_MIDICOREEVENT_H
24 : #define MU_ENGRAVING_COMPAT_MIDICOREEVENT_H
25 :
26 : #include <cstdint>
27 :
28 : #include "global/allocator.h"
29 :
30 : namespace mu::engraving {
31 : struct PitchWheelSpecs {
32 : //! @note amplitude of the pitch wheel in semitones
33 : uint16_t mAmplitude{ 12 };
34 :
35 : //! @note absolute limit of the wheel pitch value (thus, pitch shift can be set using values from {-mLimit, mLimit} interval
36 : uint16_t mLimit { 8192 };
37 :
38 : //! @note step of pith wheel in ticks
39 : uint16_t mStep { 10 };
40 : };
41 :
42 : //---------------------------------------------------------
43 : // Event types
44 : //---------------------------------------------------------
45 :
46 : enum EventType {
47 : ME_INVALID = 0,
48 : ME_NOTEOFF = 0x80,
49 : ME_NOTEON = 0x90,
50 : ME_POLYAFTER = 0xa0,
51 : ME_CONTROLLER = 0xb0, //! Control change message
52 : ME_PROGRAM = 0xc0, //! Program change message
53 : ME_AFTERTOUCH = 0xd0, //! Channel pressure message
54 : ME_PITCHBEND = 0xe0,
55 : ME_SYSEX = 0xf0,
56 : ME_META = 0xff,
57 : ME_SONGPOS = 0xf2,
58 : ME_ENDSYSEX = 0xf7,
59 : ME_CLOCK = 0xf8,
60 : ME_START = 0xfa,
61 : ME_CONTINUE = 0xfb,
62 : ME_STOP = 0xfc,
63 : ME_SENSE = 0xfe, // active sense (used by yamaha)
64 :
65 : ME_NOTE = 0x1,
66 : ME_CHORD = 0x2,
67 : ME_TICK1 = 0x3, // metronome tick akzent
68 : ME_TICK2 = 0x4, // metronome tick
69 : ME_EOT = 0x5
70 : };
71 :
72 : //---------------------------------------------------------
73 : // Midi Meta Events
74 : //---------------------------------------------------------
75 :
76 : enum {
77 : META_SEQUENCE_NUMBER = 0,
78 : META_TEXT = 1,
79 : META_COPYRIGHT = 2,
80 : META_TRACK_NAME = 3,
81 : META_INSTRUMENT_NAME = 4,
82 : META_LYRIC = 5,
83 : META_MARKER = 6,
84 : META_CUE_POINT = 7,
85 : META_PROGRAM_NAME = 8, // MIDI Meta Events 8 and 9 were defined as above by the MMA in 1998
86 : META_DEVICE_NAME = 9, // It is therefore necessary to redefine MuseScore's private meta events
87 : META_TRACK_COMMENT = 0xf, // Using the block starting 0x10 seems sensible as that is currently clear
88 : META_TITLE = 0x10, // mscore extension
89 : META_SUBTITLE = 0x11, // mscore extension
90 : META_COMPOSER = 0x12, // mscore extension
91 : META_TRANSLATOR = 0x13, // mscore extension
92 : META_POET = 0x14, // mscore extension
93 : META_PORT_CHANGE = 0x21,
94 : META_CHANNEL_PREFIX = 0x22,
95 : META_EOT = 0x2f, // end of track
96 : META_TEMPO = 0x51,
97 : META_TIME_SIGNATURE = 0x58,
98 : META_KEY_SIGNATURE = 0x59,
99 : META_SPECIFIC = 0x7F // sequencer specific
100 : };
101 :
102 : //---------------------------------------------------------
103 : // Midi Controller
104 : //---------------------------------------------------------
105 :
106 : enum CntrType {
107 : CTRL_HBANK = 0x00,
108 : CTRL_LBANK = 0x20,
109 :
110 : CTRL_HDATA = 0x06,
111 : CTRL_LDATA = 0x26,
112 :
113 : CTRL_HNRPN = 0x63,
114 : CTRL_LNRPN = 0x62,
115 :
116 : CTRL_HRPN = 0x65,
117 : CTRL_LRPN = 0x64,
118 :
119 : CTRL_MODULATION = 0x01,
120 : CTRL_BREATH = 0x02,
121 : CTRL_FOOT = 0x04,
122 : CTRL_PORTAMENTO_TIME_MSB = 0x05,
123 : CTRL_VOLUME = 0x07,
124 : CTRL_PANPOT = 0x0a,
125 : CTRL_EXPRESSION = 0x0b,
126 : CTRL_PORTAMENTO_TIME_LSB = 0x25,
127 : CTRL_SUSTAIN = 0x40,
128 : CTRL_PORTAMENTO = 0x41,
129 : CTRL_SOSTENUTO = 0x42,
130 : CTRL_SOFT_PEDAL = 0x43,
131 : CTRL_HARMONIC_CONTENT = 0x47,
132 : CTRL_RELEASE_TIME = 0x48,
133 : CTRL_ATTACK_TIME = 0x49,
134 :
135 : CTRL_BRIGHTNESS = 0x4a,
136 : CTRL_PORTAMENTO_CONTROL = 0x54,
137 : CTRL_REVERB_SEND = 0x5b,
138 : CTRL_CHORUS_SEND = 0x5d,
139 : CTRL_VARIATION_SEND = 0x5e,
140 :
141 : CTRL_ALL_SOUNDS_OFF = 0x78, // 120
142 : CTRL_RESET_ALL_CTRL = 0x79, // 121
143 : CTRL_LOCAL_OFF = 0x7a, // 122
144 : CTRL_ALL_NOTES_OFF = 0x7b, // 123
145 :
146 : // special midi events are mapped to internal
147 : // controller
148 : //
149 : CTRL_PROGRAM = 0x81,
150 : /* = 0x82,*/
151 : CTRL_PRESS = 0x83,
152 : CTRL_POLYAFTER = 0x84
153 : };
154 :
155 : //---------------------------------------------------------
156 : // MidiCoreEvent
157 : //---------------------------------------------------------
158 :
159 : class MidiCoreEvent
160 : {
161 : OBJECT_ALLOCATOR(engraving, MidiCoreEvent)
162 : protected:
163 : uint8_t _type = 0;
164 : uint8_t _channel = 0;
165 : uint8_t _a = 0;
166 : uint8_t _b = 0;
167 :
168 : public:
169 148487 : MidiCoreEvent() {}
170 4573 : MidiCoreEvent(uint8_t t, uint8_t c, uint8_t a, uint8_t b)
171 4573 : : _type(t), _channel(c), _a(a), _b(b) {}
172 :
173 : void set(uint8_t t, uint8_t c, uint8_t a, uint8_t b)
174 : {
175 : _type = t;
176 : _channel = c;
177 : _a = a;
178 : _b = b;
179 : }
180 :
181 77808 : uint8_t type() const { return _type; }
182 9438 : void setType(uint8_t t) { _type = t; }
183 15487 : uint8_t channel() const { return _channel; }
184 3093 : void setChannel(uint8_t c) { _channel = c; }
185 :
186 57209 : uint8_t dataA() const { return _a; }
187 7461 : uint8_t pitch() const { return _a; }
188 7923 : uint8_t controller() const { return _a; }
189 :
190 3450 : void setDataA(int v) { _a = static_cast<uint8_t>(v); }
191 3 : void setPitch(int v) { _a = static_cast<uint8_t>(v); }
192 1383 : void setController(int v) { _a = static_cast<uint8_t>(v); }
193 :
194 14273 : uint8_t dataB() const { return _b; }
195 7048 : uint8_t velo() const { return _b; }
196 5304 : uint8_t value() const { return _b; }
197 :
198 3450 : void setDataB(int v) { _b = static_cast<uint8_t>(v); }
199 506 : void setVelo(int v) { _b = static_cast<uint8_t>(v); }
200 1510 : void setValue(int v) { _b = static_cast<uint8_t>(v); }
201 :
202 : void setData(int a, int b) { _a = static_cast<uint8_t>(a); _b = static_cast<uint8_t>(b); }
203 10722 : void setData(int t, int a, int b) { _type = static_cast<uint8_t>(t); _a = static_cast<uint8_t>(a); _b = static_cast<uint8_t>(b); }
204 :
205 3784 : bool isChannelEvent() const
206 : {
207 3784 : switch (_type) {
208 3325 : case ME_NOTEOFF:
209 : case ME_NOTEON:
210 : case ME_POLYAFTER:
211 : case ME_CONTROLLER:
212 : case ME_PROGRAM:
213 : case ME_AFTERTOUCH:
214 : case ME_PITCHBEND:
215 : case ME_NOTE:
216 : case ME_CHORD:
217 3325 : return true;
218 459 : default:
219 459 : break;
220 : }
221 :
222 459 : return false;
223 : }
224 :
225 1 : bool operator==(const MidiCoreEvent& e) const
226 : {
227 1 : return e._type == _type && e._channel == _channel && e._a == _a && e._b == _b;
228 : }
229 :
230 : uint32_t toPackage() const
231 : {
232 : union {
233 : unsigned char data_as_bytes[4];
234 : uint32_t data_as_uint32 = 0;
235 : } u;
236 :
237 : switch (type()) {
238 : case EventType::ME_NOTEOFF:
239 : u.data_as_bytes[0] = 0x80 | channel();
240 : u.data_as_bytes[1] = static_cast<unsigned char>(pitch());
241 : u.data_as_bytes[2] = 0;
242 : u.data_as_bytes[3] = 0;
243 : break;
244 :
245 : case EventType::ME_NOTEON:
246 : u.data_as_bytes[0] = 0x90 | channel();
247 : u.data_as_bytes[1] = static_cast<unsigned char>(pitch());
248 : u.data_as_bytes[2] = static_cast<unsigned char>(velo());
249 : u.data_as_bytes[3] = 0;
250 : break;
251 :
252 : case EventType::ME_CONTROLLER:
253 : u.data_as_bytes[0] = 0xB0 | channel();
254 : u.data_as_bytes[1] = static_cast<unsigned char>(controller());
255 : u.data_as_bytes[2] = static_cast<unsigned char>(value());
256 : u.data_as_bytes[3] = 0;
257 : break;
258 :
259 : case EventType::ME_PROGRAM:
260 : u.data_as_bytes[0] = 0xC0 | channel();
261 : u.data_as_bytes[1] = static_cast<unsigned char>(value());
262 : u.data_as_bytes[2] = 0;
263 : u.data_as_bytes[3] = 0;
264 : break;
265 :
266 : case EventType::ME_PITCHBEND:
267 : u.data_as_bytes[0] = 0xE0 | channel();
268 : u.data_as_bytes[1] = pitch() & 0x7F;
269 : u.data_as_bytes[2] = static_cast<unsigned char>(pitch() >> 7);
270 : u.data_as_bytes[3] = 0;
271 : break;
272 :
273 : default:
274 : break;
275 : }
276 : return u.data_as_uint32;
277 : }
278 : };
279 : }
280 : #endif
|