-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMidiClient.h
198 lines (149 loc) · 4.77 KB
/
MidiClient.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*
* MidiClient.h - base-class for MIDI clients like ALSA-sequencer-client
*
* Copyright (c) 2005-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef _MIDI_CLIENT_H
#define _MIDI_CLIENT_H
#include <QtCore/QStringList>
#include <QtCore/QVector>
#include "MidiEvent.h"
#include "MidiEventProcessor.h"
#include "tab_widget.h"
class MidiPort;
// base-class for all MIDI-clients
class MidiClient
{
public:
MidiClient();
virtual ~MidiClient();
// to be implemented by sub-classes
virtual void processOutEvent( const MidiEvent & _me,
const MidiTime & _time,
const MidiPort * _port ) = 0;
// inheriting classes can re-implement this for being able to update
// their internal port-structures etc.
virtual void applyPortMode( MidiPort * _port );
virtual void applyPortName( MidiPort * _port );
virtual void addPort( MidiPort * _port );
// re-implemented methods HAVE to call removePort() of base-class!!
virtual void removePort( MidiPort * _port );
// returns whether client works with raw-MIDI, only needs to be
// re-implemented by MidiClientRaw for returning true
virtual bool isRaw() const
{
return false;
}
// if not raw-client, return all readable/writable ports
virtual QStringList readablePorts() const
{
return QStringList();
}
virtual QStringList writablePorts() const
{
return QStringList();
}
// return name of port which specified MIDI event came from
virtual QString sourcePortName( const MidiEvent & ) const
{
return QString();
}
// (un)subscribe given MidiPort to/from destination-port
virtual void subscribeReadablePort( MidiPort * _port,
const QString & _dest,
bool _subscribe = true );
virtual void subscribeWritablePort( MidiPort * _port,
const QString & _dest,
bool _subscribe = true );
// qobject-derived classes can use this for make a slot being
// connected to signal of non-raw-MIDI-client if port-lists change
virtual void connectRPChanged( QObject *, const char * )
{
}
virtual void connectWPChanged( QObject *, const char * )
{
}
// tries to open either MIDI-driver from config-file or (if it fails)
// any other working
static MidiClient * openMidiClient();
class setupWidget : public tabWidget
{
public:
setupWidget( const QString & _caption, QWidget * _parent ) :
tabWidget( tabWidget::tr( "Settings for %1" ).arg(
tr( _caption.toAscii() ) ).toUpper(),
_parent )
{
}
virtual ~setupWidget()
{
}
virtual void saveSettings() = 0;
virtual void show()
{
parentWidget()->show();
QWidget::show();
}
} ;
protected:
QVector<MidiPort *> m_midiPorts;
} ;
const uint32_t RAW_MIDI_PARSE_BUF_SIZE = 16;
class MidiClientRaw : public MidiClient
{
public:
MidiClientRaw();
virtual ~MidiClientRaw();
// we are raw-clients for sure!
virtual bool isRaw() const
{
return true;
}
protected:
// generic raw-MIDI-parser which generates appropriate MIDI-events
void parseData( const unsigned char c );
// to be implemented by actual client-implementation
virtual void sendByte( const unsigned char c ) = 0;
private:
// this does MIDI-event-process
void processParsedEvent();
virtual void processOutEvent( const MidiEvent& event, const MidiTime& time, const MidiPort* port );
// small helper function returning length of a certain event - this
// is necessary for parsing raw-MIDI-data
static int eventLength( const unsigned char event );
// data being used for parsing
struct midiParserData
{
uint8_t m_status; // identifies the type of event, that
// is currently received ('Noteon',
// 'Pitch Bend' etc).
uint8_t m_channel; // The channel of the event that is
// received (in case of a channel event)
uint32_t m_bytes; // How many bytes have been read for
// the current event?
uint32_t m_bytesTotal; // How many bytes does the current
// event type include?
uint32_t m_buffer[RAW_MIDI_PARSE_BUF_SIZE];
// buffer for incoming data
MidiEvent m_midiEvent; // midi-event
} m_midiParseData;
} ;
#endif