1 /*
2 Drumstick MIDI realtime input-output
3 Copyright (C) 2009-2021 Pedro Lopez-Cabanillas <plcl@users.sf.net>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifndef MIDIOUTPUT_H
20 #define MIDIOUTPUT_H
21
22 #include <QObject>
23 #include <QString>
24 #include <QStringList>
25 #include <QtPlugin>
26 #include <QSettings>
27 #include "macros.h"
28
29 /**
30 * @file rtmidioutput.h
31 * Realtime MIDI output interface
32 */
33
34 namespace drumstick { namespace rt {
35
36 /**
37 * @addtogroup RT
38 * @{
39 */
40
41 const quint8 MIDI_STD_CHANNELS = 16; ///< Standard number of MIDI channels
42 const quint8 MIDI_GM_STD_DRUM_CHANNEL = (10-1); ///< Number of the GM percussion channel
43 const quint8 MIDI_CONTROL_MSB_BANK_SELECT = 0x00; ///< MIDI Controller number for MSB Bank number
44 const quint8 MIDI_CONTROL_MSB_MAIN_VOLUME = 0x07; ///< MIDI Controller number for MSB volume
45 const quint8 MIDI_CONTROL_LSB_BANK_SELECT = 0x20; ///< MIDI Controller number for LSB Bank number
46 const quint8 MIDI_CONTROL_REVERB_SEND = 0x5b; ///< MIDI Controller number for Reverb send
47 const quint8 MIDI_CONTROL_ALL_SOUNDS_OFF = 0x78; ///< MIDI Controller number for All sounds off
48 const quint8 MIDI_CONTROL_ALL_NOTES_OFF = 0x7b; ///< MIDI Controller number for All notes off
49 const quint8 MIDI_CONTROL_RESET_CONTROLLERS = 0x79; ///< MIDI Controller number for Reset all controllers
50
51 const quint8 MIDI_STATUS_NOTEOFF = 0x80; ///< MIDI status byte for NOTE OFF messages
52 const quint8 MIDI_STATUS_NOTEON = 0x90; ///< MIDI status byte for NOTE ON messages
53 const quint8 MIDI_STATUS_KEYPRESURE = 0xa0; ///< MIDI status byte for KEY pressure messages
54 const quint8 MIDI_STATUS_CONTROLCHANGE = 0xb0; ///< MIDI status byte for CONTROL change messages
55 const quint8 MIDI_STATUS_PROGRAMCHANGE = 0xc0; ///< MIDI status byte for PROGRAM change messages
56 const quint8 MIDI_STATUS_CHANNELPRESSURE = 0xd0; ///< MIDI status byte for CHANNEL PRESSURE messages
57 const quint8 MIDI_STATUS_PITCHBEND = 0xe0; ///< MIDI status byte for PITCH bend messages
58 const quint8 MIDI_STATUS_SYSEX = 0xf0; ///< MIDI status byte for System Exclusive START messages
59 const quint8 MIDI_STATUS_ENDSYSEX = 0xf7; ///< MIDI status byte for System Exclusive END messages
60 const quint8 MIDI_STATUS_REALTIME = 0xf8; ///< Minimum value for MIDI Realtime messages status
61
62 const quint8 MIDI_STATUS_MASK = 0xf0; ///< Mask to extract the MIDI status byte from a MIDI message
63 const quint8 MIDI_CHANNEL_MASK = 0x0f; ///< Mask to extract the MIDI channel byte from a MIDI message
64
65 const quint8 MIDI_COMMON_QTRFRAME = 0xF1; ///< MIDI Quarter frame status message
66 const quint8 MIDI_COMMON_SONGPP = 0xF2; ///< MIDI Song Position status message
67 const quint8 MIDI_COMMON_SONGSELECT = 0xF3; ///< MIDI Song Select status message
68 const quint8 MIDI_COMMON_TUNEREQ = 0xF6; ///< MIDI Tune Request status message
69
70 const quint8 MIDI_REALTIME_CLOCK = 0xF8; ///< MIDI Clock status message
71 const quint8 MIDI_REALTIME_START = 0xFA; ///< MIDI Start status message
72 const quint8 MIDI_REALTIME_CONTINUE = 0xFB; ///< MIDI Continue status message
73 const quint8 MIDI_REALTIME_STOP = 0xFC; ///< MIDI Stop status message
74 const quint8 MIDI_REALTIME_SENSING = 0xFE; ///< MIDI Active Sensing status message
75 const quint8 MIDI_REALTIME_RESET = 0xFF; ///< MIDI Reset status message
76
77 /**
78 * @brief MIDI_LSB is a function to extract the least significative byte of a MIDI value
79 * @param x a MIDI integer value
80 * @return the least significative byte of the input value
81 */
MIDI_LSB(int x)82 inline int MIDI_LSB(int x)
83 {
84 return (x % 0x80);
85 }
86
87 /**
88 * @brief MIDI_MSB is a function to extract the most significative byte of a MIDI value
89 * @param x MIDI integer value
90 * @return the most significative byte of the input value
91 */
MIDI_MSB(int x)92 inline int MIDI_MSB(int x)
93 {
94 return (x / 0x80);
95 }
96
97 /**
98 * @brief MIDIConnection represents a connection identifier
99 *
100 * MIDIConnection is an alias for QPair<QString,QVariant> where the
101 * first component is a QString representing the symbolic name of the MIDI Port
102 * and the second component is a QVariant that represents the native identification
103 * of the MIDI port, which may be a string, a number, or any other data type
104 * accepted as a QVariant.
105 */
106 typedef QPair<QString,QVariant> MIDIConnection;
107
108 /**
109 * @brief MIDI OUT interface
110 */
111 class DRUMSTICK_EXPORT MIDIOutput : public QObject
112 {
113 Q_OBJECT
114
115 public:
116 /**
117 * @brief MIDIOutput constructor
118 * @param parent
119 */
QObject(parent)120 explicit MIDIOutput(QObject *parent = nullptr) : QObject(parent) {}
121 /**
122 * @brief ~MIDIOutput destructor
123 */
124 virtual ~MIDIOutput() = default;
125 /**
126 * @brief initialize
127 * @param settings
128 */
129 virtual void initialize(QSettings* settings) = 0;
130 /**
131 * @brief backendName
132 * @return plugin name
133 */
134 virtual QString backendName() = 0;
135 /**
136 * @brief publicName
137 * @return MIDI port name
138 */
139 virtual QString publicName() = 0;
140 /**
141 * @brief setPublicName
142 * @param name MIDI port name
143 */
144 virtual void setPublicName(QString name) = 0;
145 /**
146 * @brief connections
147 * @param advanced whether the advanced connections are included or not
148 * @return list of available MIDI ports
149 */
150 virtual QList<MIDIConnection> connections(bool advanced = false) = 0;
151 /**
152 * @brief setExcludedConnections
153 * @param conns
154 */
155 virtual void setExcludedConnections(QStringList conns) = 0;
156 /**
157 * @brief open the MIDI port by name
158 * @param conn the MIDI connection to be opened
159 */
160 virtual void open(const MIDIConnection& conn) = 0;
161 /**
162 * @brief close the MIDI port
163 */
164 virtual void close() = 0;
165 /**
166 * @brief currentConnection
167 * @return name of the current connection if it is opened
168 */
169 virtual MIDIConnection currentConnection() = 0;
170
171 public Q_SLOTS:
172 /**
173 * @brief sendNoteOff 0x8
174 * @param chan
175 * @param note
176 * @param vel
177 */
178 virtual void sendNoteOff(int chan, int note, int vel) = 0;
179
180 /**
181 * @brief sendNoteOn 0x9
182 * @param chan
183 * @param note
184 * @param vel
185 */
186 virtual void sendNoteOn(int chan, int note, int vel) = 0;
187
188 /**
189 * @brief sendKeyPressure 0xA
190 * @param chan
191 * @param note
192 * @param value
193 */
194 virtual void sendKeyPressure(int chan, int note, int value) = 0;
195
196 /**
197 * @brief sendController 0xB
198 * @param chan
199 * @param control
200 * @param value
201 */
202 virtual void sendController(int chan, int control, int value) = 0;
203
204 /**
205 * @brief sendProgram 0xC
206 * @param chan
207 * @param program
208 */
209 virtual void sendProgram(int chan, int program) = 0;
210
211 /**
212 * @brief sendChannelPressure 0xD
213 * @param chan
214 * @param value
215 */
216 virtual void sendChannelPressure(int chan, int value) = 0;
217
218 /**
219 * @brief sendPitchBend 0xE
220 * @param chan
221 * @param value
222 */
223 virtual void sendPitchBend(int chan, int value) = 0;
224
225 /**
226 * @brief sendSysex
227 * @param data 0xF0 ... 0xF7
228 */
229 virtual void sendSysex(const QByteArray& data) = 0;
230
231 /**
232 * @brief sendSystemMsg
233 * @param status 0xF
234 */
235 virtual void sendSystemMsg(const int status) = 0;
236 };
237
238 /** @} */
239
240 }} // namespace drumstick::rt
241
242 Q_DECLARE_INTERFACE(drumstick::rt::MIDIOutput, "net.sourceforge.drumstick.rt.MIDIOutput/2.0")
243 Q_DECLARE_METATYPE(drumstick::rt::MIDIConnection)
244
245 #endif /* MIDIOUTPUT_H */
246