/[svn]/linuxsampler/trunk/src/drivers/midi/VirtualMidiDevice.h
ViewVC logotype

Contents of /linuxsampler/trunk/src/drivers/midi/VirtualMidiDevice.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3986 - (show annotations) (download) (as text)
Wed Aug 4 18:04:12 2021 UTC (15 months, 3 weeks ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 8892 byte(s)
* VirtualMidiDevice: add method Reset() which is e.g. intended to be used
  in "panic" / MIDI "all sound off" / MIDI "all note off" situations.

1 /*
2 Copyright (C) 2008 - 2021 Christian Schoenebeck
3 */
4
5 #ifndef LS_VIRTUALMIDIDEVICE_H
6 #define LS_VIRTUALMIDIDEVICE_H
7
8 #include "../../common/global.h"
9
10 namespace LinuxSampler {
11
12 /**
13 * Light-weight MIDI interface (for MIDI in & out) intended to be used by
14 * pure software MIDI "devices", that is e.g. a graphical virtual MIDI
15 * keyboard in an instrument editor or in a sampler frontend. This class
16 * should not be used for regular MIDI input device drivers for the sampler.
17 * This primitive interface by design doesn't care about jitter, fast event
18 * delivery or masses and masses of events in a short time!
19 */
20 class VirtualMidiDevice {
21 public:
22 enum event_type_t {
23 EVENT_TYPE_NOTEON = 1,
24 EVENT_TYPE_NOTEOFF = 2,
25 EVENT_TYPE_CC = 3,
26 EVENT_TYPE_PITCHBEND,
27 EVENT_TYPE_PROGRAM,
28 EVENT_TYPE_CHPRESSURE,
29 };
30
31 struct event_t {
32 event_type_t Type;
33 uint8_t Arg1; ///< Depends on @c Type (e.g. key number for note on/off events).
34 uint8_t Arg2; ///< Depends on @c Type (e.g. velocity for note on/off events).
35 };
36
37 /////////////////////////////////////////////////////////////////
38 // Device methods
39 // (called by the VirtualMidiDevice implementation)
40
41 /**
42 * Sends a MIDI @e note @e on event to the sampler.
43 *
44 * @returns true on success, false if internal FIFO full
45 * (or provided values invalid)
46 */
47 bool SendNoteOnToSampler(uint8_t Key, uint8_t Velocity);
48
49 /**
50 * Sends a MIDI @e note @e off event to the sampler.
51 *
52 * @returns true on success, false if internal FIFO full
53 * (or provided values invalid)
54 */
55 bool SendNoteOffToSampler(uint8_t Key, uint8_t Velocity);
56
57 /**
58 * Sends a MIDI @e Control @e Change event to the sampler.
59 *
60 * @returns true on success, false if internal FIFO full
61 * (or provided values invalid)
62 */
63 bool SendCCToSampler(uint8_t Controller, uint8_t Value);
64
65 /**
66 * Sends a MIDI @e Channel @e Pressure (aftertouch) event to the sampler.
67 *
68 * @returns true on success, false if internal FIFO full
69 * (or provided value invalid)
70 */
71 bool SendChannelPressureToSampler(uint8_t Pressure);
72
73 /**
74 * Sends a MIDI @e Pitch @e Bend event to the sampler.
75 *
76 * @param Pitch - MIDI pitch value (-8192 ... +8191)
77 *
78 * @returns true on success, false if internal FIFO full
79 * (or provided pitch value out of valid range)
80 */
81 bool SendPitchBendToSampler(int Pitch);
82
83 /**
84 * Sends a MIDI @e Program @e Change event to the sampler.
85 *
86 * If you want to change the sound bank, call SendCCToSampler() (with
87 * controller = 0 for bank select MSB and/or controller = 32 for bank select
88 * LSB) before calling this method.
89 *
90 * @param Program - MIDI program number
91 *
92 * @returns true on success, false if internal FIFO full
93 * (or provided value invalid)
94 */
95 bool SendProgramChangeToSampler(uint8_t Program);
96
97 /**
98 * Can be called by the virtual MIDI device to check whether a new note
99 * on or note off MIDI event arrived to the sampler during the last
100 * call to this method. So this is a asynchronously, "polling" based
101 * communication mechanism, which works in conjunction with the
102 * NoteIsActive() method call.
103 */
104 bool NotesChanged();
105
106 /**
107 * Can be called by the virtual MIDI device to check whether a new note
108 * on or note off MIDI event arrived to the sampler for @a Key during
109 * the last call to this method. So this is a asynchronously,
110 * "polling" based communication mechanism, which works in
111 * conjunction with the NoteIsActive() method call.
112 */
113 bool NoteChanged(uint8_t Key);
114
115 /**
116 * Can be called by the virtual MIDI device to check which key / note
117 * is currently active by the sampler, e.g. to highlight the
118 * respective keys on a graphical virtual keyboard.
119 *
120 * @see NotesChanged(), NoteChanged()
121 */
122 bool NoteIsActive(uint8_t Key);
123
124 /**
125 * Returns the velocity of the @e last note on event. No FIFO is used!
126 */
127 uint8_t NoteOnVelocity(uint8_t Key);
128
129 /**
130 * Returns the velocity of the @e last note off event. No FIFO is used!
131 */
132 uint8_t NoteOffVelocity(uint8_t Key);
133
134 /**
135 * Can be called by the virtual MIDI device to check whether a Control
136 * Change MIDI event arrived to the sampler during the last
137 * call to this method. So this is a asynchronously, "polling" based
138 * communication mechanism, which works in conjunction with the
139 * ControllerValue() method call.
140 */
141 bool ControllersChanged();
142
143 /**
144 * Can be called by the virtual MIDI device to check whether a Control
145 * Change MIDI event arrived to the sampler for @a Controller during
146 * the last call to this method. So this is a asynchronously,
147 * "polling" based communication mechanism, which works in
148 * conjunction with the ControllerValue() method call.
149 */
150 bool ControllerChanged(uint8_t Controller);
151
152 /**
153 * Returns the value of the @e last Control Change event. No FIFO is used!
154 */
155 uint8_t ControllerValue(uint8_t Controller);
156
157 /////////////////////////////////////////////////////////////////
158 // Sampler methods
159 // (usually only called by the Sampler)
160
161 /**
162 * Informs the virtual MIDI device that a @e note @e on event occured
163 * (e.g. caused by a MIDI keyboard connected to the sampler).
164 * Communication acts asynchronously, that is this method call doesn't
165 * lock in any way and returns immediately. It is thus realtime safe.
166 *
167 * @e Note: this method is usually only called by the sampler.
168 *
169 * @see ActiveNotesChanged(), NoteIsActive()
170 */
171 void SendNoteOnToDevice(uint8_t Key, uint8_t Velocity);
172
173 /**
174 * Informs the virtual MIDI device that a @e note @e off event occured
175 * (e.g. caused by a MIDI keyboard connected to the sampler).
176 * Communication acts asynchronously, that is this method call doesn't
177 * lock in any way and returns immediately. It is thus realtime safe.
178 *
179 * @e Note: this method is usually only called by the sampler.
180 *
181 * @see ActiveNotesChanged(), NoteIsActive()
182 */
183 void SendNoteOffToDevice(uint8_t Key, uint8_t Velocity);
184
185 /**
186 * Informs the virtual MIDI device that a @e Control @e Change event
187 * occured (e.g. caused by a MIDI keyboard connected to the sampler).
188 * Communication acts asynchronously, that is this method call doesn't
189 * lock in any way and returns immediately. It is thus realtime safe.
190 *
191 * @e Note: this method is usually only called by the sampler.
192 *
193 * @see ControllersChanged(), ControllerValue()
194 */
195 void SendCCToDevice(uint8_t Controller, uint8_t Value);
196
197 /**
198 * Gets the next pending MIDI event from the virtual MIDI device by
199 * using a lockfree FIFO.
200 *
201 * @e Note: this method is usually only called by the sampler.
202 *
203 * @param Event - destination for writing the next event to
204 * @returns true on success, false if no event pending
205 */
206 bool GetMidiEventFromDevice(event_t& Event);
207
208 /////////////////////////////////////////////////////////////////
209 // General Purpose Methods
210
211 /**
212 * Adjusts the internal event buffer to cover at least the given
213 * amount of MIDI events. This might be useful, since the internal
214 * event buffer is by default quite small (i.e. just 12 events).
215 *
216 * This method is not thread safe! Any operations upon this device
217 * have to be stopped before calling this method!
218 */
219 void SetMaxEvents(int n);
220
221 /**
222 * Intended to be called on "panic" / all notes off situations. Calling this
223 * method will reset all internal atomic flags, such that the state reflects
224 * that no note is currently active (its key pressed down).
225 *
226 * Only exception: this method currently does not reset the internal
227 * ring buffer which is used to transmit MIDI events to the sampler.
228 *
229 * Also note that this method is not fully concurrency safe. That means
230 * since only flags are reset, calling this method means no harm, but it
231 * might conflict with MIDI events etc and thus still cause hanging notes
232 * durcing such a specific concurrency conflict. Or in other words: the
233 * user might need to trigger the "panic" button multiple times.
234 */
235 void Reset();
236
237 /**
238 * Constructor
239 */
240 VirtualMidiDevice();
241
242 /**
243 * Destructor
244 */
245 virtual ~VirtualMidiDevice();
246
247 private:
248 struct private_data_t;
249 private_data_t* const p;
250 };
251
252 } // namespace LinuxSampler
253
254 #endif // LS_VIRTUALMIDIDEVICE_H

  ViewVC Help
Powered by ViewVC