hydrogen 1.2.6
MidiCommon.cpp
Go to the documentation of this file.
1/*
2 * Hydrogen
3 * Copyright(c) 2008-2025 The hydrogen development team [hydrogen-devel@lists.sourceforge.net]
4 *
5 * http://www.hydrogen-music.org
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 as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY, without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see https://www.gnu.org/licenses
19 *
20 */
21
22#include <core/IO/MidiCommon.h>
23
24namespace H2Core
25{
26
29 m_nData1 = -1;
30 m_nData2 = -1;
31 m_nChannel = -1;
32 m_sysexData.clear();
33}
34
35void MidiMessage::setType( int nStatusByte ) {
36
37 if ( nStatusByte >= 128 && nStatusByte < 144 ) {
38 m_nChannel = nStatusByte - 128;
40 }
41 else if ( nStatusByte >= 144 && nStatusByte < 160 ) {
42 m_nChannel = nStatusByte - 144;
44 }
45 else if ( nStatusByte >= 160 && nStatusByte < 176 ) {
46 m_nChannel = nStatusByte - 160;
48 }
49 else if ( nStatusByte >= 176 && nStatusByte < 192 ) {
50 m_nChannel = nStatusByte - 176;
52 }
53 else if ( nStatusByte >= 192 && nStatusByte < 208 ) {
54 m_nChannel = nStatusByte - 192;
56 }
57 else if ( nStatusByte >= 208 && nStatusByte < 224 ) {
58 m_nChannel = nStatusByte - 208;
60 }
61 else if ( nStatusByte >= 224 && nStatusByte < 240 ) {
62 m_nChannel = nStatusByte - 224;
64 }
65 // System Common Messages
66 else if ( nStatusByte == 240 ) {
67 m_nChannel = nStatusByte - 224;
69 }
70 else if ( nStatusByte == 241 ) {
72 }
73 else if ( nStatusByte == 242 ) {
75 }
76 else if ( nStatusByte == 243 ) {
78 }
79 // 244, 245 are undefined/reserved
80 else if ( nStatusByte == 246 ) {
82 }
83 // 247 indicates the end of a SysEx (240) message
84 // System Realtime Messages
85 else if ( nStatusByte == 248 ) {
87 }
88 // 249 is undefined/reserved
89 else if ( nStatusByte == 250 ) {
91 }
92 else if ( nStatusByte == 251 ) {
94 }
95 else if ( nStatusByte == 252 ) {
97 }
98 // 253 is undefined/reserved
99 else if ( nStatusByte == 254 ) {
101 }
102 else if ( nStatusByte == 255 ) {
104 }
105}
106
107QString MidiMessage::toQString( const QString& sPrefix, bool bShort ) const {
108
109 QString s = Base::sPrintIndention;
110 QString sOutput;
111 if ( ! bShort ) {
112 sOutput = QString( "%1[MidiMessage]\n" ).arg( sPrefix )
113 .append( QString( "%1%2m_type: %3\n" )
115 .append( QString( "%1%2m_nData1: %3\n" )
116 .arg( m_nData1 ) )
117 .append( QString( "%1%2m_nData2: %3\n" )
118 .arg( m_nData2 ) )
119 .append( QString( "%1%2m_nChannel: %3\n" )
120 .arg( m_nChannel ) )
121 .append( QString( "%1%2m_sysexData: [" ) );
122 bool bIsFirst = true;
123 for ( const auto& dd : m_sysexData ) {
124 if ( bIsFirst ) {
125 sOutput.append( QString( "%1" ).arg( dd ) );
126 bIsFirst = false;
127 }
128 else {
129 sOutput.append( QString( " %1" ).arg( dd ) );
130 }
131 }
132 sOutput.append( "]" );
133 }
134 else {
135 sOutput = QString( "[MidiMessage] " )
136 .append( QString( "m_type: %1" ).arg( MidiMessage::TypeToQString( m_type ) ) )
137 .append( QString( ", m_nData1: %1" ).arg( m_nData1 ) )
138 .append( QString( ", m_nData2: %1" ).arg( m_nData2 ) )
139 .append( QString( ", m_nChannel: %1" ).arg( m_nChannel ) )
140 .append( QString( ", m_sysexData: [" ) );
141 bool bIsFirst = true;
142 for ( const auto& dd : m_sysexData ) {
143 if ( bIsFirst ) {
144 sOutput.append( QString( "%1" ).arg( dd ) );
145 bIsFirst = false;
146 }
147 else {
148 sOutput.append( QString( " %1" ).arg( dd ) );
149 }
150 }
151 sOutput.append( "]" );
152 }
153
154 return sOutput;
155}
156
158 QString sType;
159 switch( type ) {
161 sType = "SYSEX";
162 break;
164 sType = "NOTE_ON";
165 break;
167 sType = "NOTE_OFF";
168 break;
170 sType = "POLYPHONIC_KEY_PRESSURE";
171 break;
173 sType = "CONTROL_CHANGE";
174 break;
176 sType = "PROGRAM_CHANGE";
177 break;
179 sType = "CHANNEL_PRESSURE";
180 break;
182 sType = "PITCH_WHEEL";
183 break;
185 sType = "START";
186 break;
188 sType = "CONTINUE";
189 break;
191 sType = "STOP";
192 break;
194 sType = "SONG_POS";
195 break;
197 sType = "QUARTER_FRAME";
198 break;
200 sType = "SONG_SELECT";
201 break;
203 sType = "TUNE_REQUEST";
204 break;
206 sType = "TIMING_CLOCK";
207 break;
209 sType = "ACTIVE_SENSING";
210 break;
212 sType = "RESET";
213 break;
215 default:
216 sType = "Unknown MIDI message type";
217 }
218
219 return std::move( sType );
220}
221
223 QString sEvent;
224
225 switch ( event ) {
226 case Event::Note:
227 sEvent = "NOTE";
228 break;
229 case Event::CC:
230 sEvent = "CC";
231 break;
232 case Event::PC:
233 sEvent = "PROGRAM_CHANGE";
234 break;
235 case Event::MmcStop:
236 sEvent = "MMC_STOP";
237 break;
238 case Event::MmcPlay:
239 sEvent = "MMC_PLAY";
240 break;
241 case Event::MmcPause:
242 sEvent = "MMC_PAUSE";
243 break;
245 sEvent = "MMC_DEFERRED_PLAY";
246 break;
247 case Event::MmcRewind:
248 sEvent = "MMC_REWIND";
249 break;
251 sEvent = "MMC_FAST_FORWARD";
252 break;
254 sEvent = "MMC_RECORD_STROBE";
255 break;
257 sEvent = "MMC_RECORD_EXIT";
258 break;
260 sEvent = "MMC_RECORD_READY";
261 break;
262 case Event::Null:
263 default:
264 sEvent = "";
265 }
266
267 return std::move( sEvent );
268}
269
271 if ( sEvent == "NOTE" ) {
272 return Event::Note;
273 }
274 else if ( sEvent == "CC" ) {
275 return Event::CC;
276 }
277 else if ( sEvent == "PROGRAM_CHANGE" ) {
278 return Event::PC;
279 }
280 else if ( sEvent == "MMC_STOP" ) {
281 return Event::MmcStop;
282 }
283 else if ( sEvent == "MMC_PLAY" ) {
284 return Event::MmcPlay;
285 }
286 else if ( sEvent == "MMC_PAUSE" ) {
287 return Event::MmcPause;
288 }
289 else if ( sEvent == "MMC_DEFERRED_PLAY" ) {
291 }
292 else if ( sEvent == "MMC_FAST_FORWARD" ) {
294 }
295 else if ( sEvent == "MMC_REWIND" ) {
296 return Event::MmcRewind;
297 }
298 else if ( sEvent == "MMC_RECORD_STROBE" ) {
300 }
301 else if ( sEvent == "MMC_RECORD_EXIT" ) {
303 }
304 else if ( sEvent == "MMC_RECORD_READY" ) {
306 }
307 else {
308 return Event::Null;
309 }
310}
311
330};
331
static QString sPrintIndention
String used to format the debugging string output of some core classes.
Definition Object.h:127
MidiMessageType m_type
Definition MidiCommon.h:93
QString toQString(const QString &sPrefix="", bool bShort=true) const
Formatted string version for debugging purposes.
static QStringList getEventList()
Retrieve the string representation for all available Event.
Event
Subset of incoming MIDI events that will be handled by Hydrogen.
Definition MidiCommon.h:66
void setType(int nStatusByte)
Derives and set m_type (and if applicable m_nChannel) using the statusByte of an incoming MIDI messag...
static QString TypeToQString(MidiMessageType type)
MidiMessageType
All possible types of incoming MIDI messages.
Definition MidiCommon.h:41
std::vector< unsigned char > m_sysexData
Definition MidiCommon.h:97
static QString EventToQString(Event event)
void clear()
Reset message.
static Event QStringToEvent(const QString &sEvent)