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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1695 - (show annotations) (download) (as text)
Sat Feb 16 01:09:33 2008 UTC (16 years, 2 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 16515 byte(s)
* added new LSCP event "DEVICE_MIDI" which can be used by frontends to
  react on MIDI data arriving on certain MIDI input devices (so far only
  Note-On and Note-Off events are sent via this LSCP event)
* bumped version to 0.5.1.4cvs

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 - 2008 Christian Schoenebeck *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 ***************************************************************************/
23
24 #ifndef __LS_MIDIINPUTPORT_H__
25 #define __LS_MIDIINPUTPORT_H__
26
27 #include "../../common/global.h"
28 #include "../../common/Mutex.h"
29 #include "../../common/Exception.h"
30 #include "../DeviceParameter.h"
31 #include "midi.h"
32 #include "MidiInputDevice.h"
33 #include "../../engines/EngineChannel.h"
34 #include "../../common/SynchronizedConfig.h"
35
36 namespace LinuxSampler {
37
38 // just symbol prototyping
39 class MidiInputDevice;
40 class EngineChannel;
41 class VirtualMidiDevice;
42
43 class MidiInputPort {
44 public:
45
46 /////////////////////////////////////////////////////////////////
47 // type definitions
48
49 /** MIDI Port Parameter 'NAME'
50 *
51 * Used to assign an arbitrary name to the MIDI port.
52 */
53 class ParameterName : public DeviceRuntimeParameterString {
54 public:
55 ParameterName(MidiInputPort* pPort);
56 ParameterName(MidiInputPort* pPort, String val);
57 virtual String Description();
58 virtual bool Fix();
59 virtual std::vector<String> PossibilitiesAsString();
60 virtual void OnSetValue(String s) throw (Exception);
61 protected:
62 MidiInputPort* pPort;
63 };
64
65
66
67 /////////////////////////////////////////////////////////////////
68 // normal methods
69 // (usually not to be overriden by descendant)
70
71 /**
72 * Connect given sampler engine channel with this MIDI input
73 * device. The engine channel can either be connected to one
74 * specific MIDI channel or all MIDI channels. If an engine
75 * channel gets connected twice to this MIDI input device, then
76 * the engine's old connection will be detached (no matter on
77 * which MIDI channel).
78 *
79 * @param pEngineChannel - sampler engine
80 * @param MidiChannel - MIDI channel to connect to
81 * @throws MidiInputException if MidiChannel argument invalid
82 */
83 void Connect(EngineChannel* pEngineChannel, midi_chan_t MidiChannel);
84
85 /**
86 * Disconnect given sampler engine channel from this MIDI input
87 * device. If the given engine channel was not connected with
88 * this device, nothing happens.
89 *
90 * @param pEngineChannel - sampler engine
91 */
92 void Disconnect(EngineChannel* pEngineChannel);
93
94 /**
95 * Return MIDI device where this MIDI port belongs to.
96 */
97 MidiInputDevice* GetDevice();
98
99 /**
100 * Return port number with which this MIDI port is registered to
101 * the MIDI device.
102 */
103 uint GetPortNumber();
104
105 /**
106 * Return all parameter settings of this MIDI port.
107 */
108 std::map<String,DeviceRuntimeParameter*> PortParameters();
109
110 /**
111 * Registers that an engine wants to have sysex messages.
112 */
113 static void AddSysexListener(Engine* engine);
114
115 /**
116 * Removes engine from list of engines getting sysex
117 * messages.
118 *
119 * @returns true if engine was removed, false if it wasn't
120 * present in the list.
121 */
122 static bool RemoveSysexListener(Engine* engine);
123
124 /**
125 * Connects the given virtual MIDI device to this MIDI input
126 * device. This can be used to listen to MIDI data arriving on
127 * the MIDI input device's MIDI ports, e.g. to show an MIDI
128 * activity indicator somewhere.
129 */
130 void Connect(VirtualMidiDevice* pDevice);
131
132 /**
133 * Disconnect the previously connected virtual MIDI device.
134 */
135 void Disconnect(VirtualMidiDevice* pDevice);
136
137
138 /////////////////////////////////////////////////////////////////
139 // dispatch methods
140 // (should be called by the MidiInputDevice descendant on events)
141
142 /**
143 * Should be called by the implementing MIDI input device
144 * whenever a note on event arrived, this will cause the note on
145 * event to be forwarded to all connected engines on the
146 * corresponding MIDI channel.
147 *
148 * This method is meant for realtime rendering, this way an event
149 * is immediately created with the current system time as time
150 * stamp.
151 *
152 * @param Key - MIDI key number of the triggered key
153 * @param Velocity - MIDI velocity of the triggered key
154 * @param MidiChannel - MIDI channel on which event occured on
155 * (low level indexing, means 0..15)
156 */
157 void DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel);
158
159 /**
160 * Should be called by the implementing MIDI input device
161 * whenever a note on event arrived, this will cause the note on
162 * event to be forwarded to all connected engines on the
163 * corresponding MIDI channel.
164 *
165 * This method is meant for offline rendering and / or in case the
166 * exact fragment position of the event is already known.
167 *
168 * @param Key - MIDI key number of the triggered key
169 * @param Velocity - MIDI velocity of the triggered key
170 * @param MidiChannel - MIDI channel on which event occured on
171 * (low level indexing, means 0..15)
172 * @param FragmentPos - event's sample point position in the
173 * current audio fragment
174 */
175 void DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel, int32_t FragmentPos);
176
177 /**
178 * Should be called by the implementing MIDI input device
179 * whenever a note off event arrived, this will cause the note
180 * off event to be forwarded to all connected engines on the
181 * corresponding MIDI channel.
182 *
183 * This method is meant for realtime rendering, this way an event
184 * is immediately created with the current system time as time
185 * stamp.
186 *
187 * @param Key - MIDI key number of the released key
188 * @param Velocity - MIDI velocity of the released key
189 * @param MidiChannel - MIDI channel on which event occured on
190 * (low level indexing, means 0..15)
191 */
192 void DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel);
193
194 /**
195 * Should be called by the implementing MIDI input device
196 * whenever a note off event arrived, this will cause the note
197 * off event to be forwarded to all connected engines on the
198 * corresponding MIDI channel.
199 *
200 * This method is meant for offline rendering and / or in case the
201 * exact fragment position of the event is already known.
202 *
203 * @param Key - MIDI key number of the released key
204 * @param Velocity - MIDI velocity of the released key
205 * @param MidiChannel - MIDI channel on which event occured on
206 * (low level indexing, means 0..15)
207 * @param FragmentPos - event's sample point position in the
208 * current audio fragment
209 */
210 void DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel, int32_t FragmentPos);
211
212 /**
213 * Should be called by the implementing MIDI input device
214 * whenever a pitchbend event arrived, this will cause the
215 * pitchbend event to be forwarded to all connected engines.
216 *
217 * This method is meant for realtime rendering, this way an event
218 * is immediately created with the current system time as time
219 * stamp.
220 *
221 * @param Pitch - MIDI pitch value
222 * @param MidiChannel - MIDI channel on which event occured on
223 * (low level indexing, means 0..15)
224 */
225 void DispatchPitchbend(int Pitch, uint MidiChannel);
226
227 /**
228 * Should be called by the implementing MIDI input device
229 * whenever a pitchbend event arrived, this will cause the
230 * pitchbend event to be forwarded to all connected engines.
231 *
232 * This method is meant for offline rendering and / or in case the
233 * exact fragment position of the event is already known.
234 *
235 * @param Pitch - MIDI pitch value
236 * @param MidiChannel - MIDI channel on which event occured on
237 * (low level indexing, means 0..15)
238 * @param FragmentPos - event's sample point position in the
239 * current audio fragment
240 */
241 void DispatchPitchbend(int Pitch, uint MidiChannel, int32_t FragmentPos);
242
243 /**
244 * Should be called by the implementing MIDI input device
245 * whenever a control change event arrived, this will cause the
246 * control change event to be forwarded to all engines on the
247 * corresponding MIDI channel.
248 *
249 * This method is meant for realtime rendering, this way an event
250 * is immediately created with the current system time as time
251 * stamp.
252 *
253 * @param Controller - MIDI controller number
254 * @param Value - MIDI control change value
255 * @param MidiChannel - MIDI channel on which event occured on
256 * (low level indexing, means 0..15)
257 */
258 void DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel);
259
260 /**
261 * Should be called by the implementing MIDI input device
262 * whenever a control change event arrived, this will cause the
263 * control change event to be forwarded to all engines on the
264 * corresponding MIDI channel.
265 *
266 * This method is meant for offline rendering and / or in case the
267 * exact fragment position of the event is already known.
268 *
269 * @param Controller - MIDI controller number
270 * @param Value - MIDI control change value
271 * @param MidiChannel - MIDI channel on which event occured on
272 * (low level indexing, means 0..15)
273 * @param FragmentPos - event's sample point position in the
274 * current audio fragment
275 */
276 void DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel, int32_t FragmentPos);
277
278 /**
279 * Should be called by the implementing MIDI input device
280 * whenever a program change event arrived, this will cause the
281 * appropriate sampler channel to be connected with this MIDI
282 * device.
283 *
284 * For example consider a program change event on MIDI channel
285 * 3 for program number 18. This would cause this MIDI input
286 * device to be connected to sampler channel 18 and would cause
287 * sampler channel 18 to listen to MIDI channel 3.
288 *
289 * This is the current, general implementation of program
290 * change events. It might change in future, e.g to allow
291 * sampler engines to allow by themselfes how to act on a
292 * program change event.
293 *
294 * @param Program - sampler channel to connect to this MIDI
295 * input device
296 * @param MidiChannel - MIDI channel on which sampler channel
297 * \a Program should listen to
298 */
299 void DispatchProgramChange(uint8_t Program, uint MidiChannel);
300
301 void DispatchBankSelectMsb(uint8_t BankMsb, uint MidiChannel);
302
303 void DispatchBankSelectLsb(uint8_t BankLsb, uint MidiChannel);
304
305 /**
306 * Should be called by the implementing MIDI input device
307 * whenever a system exclusive message arrived, this will cause
308 * the message to be forwarded to all connected engines.
309 *
310 * @param pData - pointer to the sysex data
311 * @param Size - length of the sysex data (in bytes)
312 */
313 void DispatchSysex(void* pData, uint Size);
314
315 protected:
316 MidiInputDevice* pDevice;
317 int portNumber;
318 std::map<String,DeviceRuntimeParameter*> Parameters; ///< All port parameters.
319 typedef std::set<EngineChannel*> MidiChannelMap_t[17];
320 SynchronizedConfig<MidiChannelMap_t> MidiChannelMap; ///< Contains the list of connected engines for each MIDI channel, where index 0 points to the list of engines which are connected to all MIDI channels. Usually it's not necessary for the descendant to use this map, instead it should just use the Dispatch* methods.
321 SynchronizedConfig<MidiChannelMap_t>::Reader MidiChannelMapReader; ///< MIDI thread access to MidiChannelMap
322 Mutex MidiChannelMapMutex; ///< Used to protect the MidiChannelMap from being used at the same time by different threads.
323 SynchronizedConfig<std::set<Engine*> >::Reader SysexListenersReader; ///< MIDI thread access to SysexListeners
324 SynchronizedConfig<std::vector<VirtualMidiDevice*> > virtualMidiDevices;
325 SynchronizedConfig<std::vector<VirtualMidiDevice*> >::Reader virtualMidiDevicesReader;
326 Mutex virtualMidiDevicesMutex;
327
328 /**
329 * Constructor
330 */
331 MidiInputPort(MidiInputDevice* pDevice, int portNumber);
332
333 /**
334 * Destructor
335 */
336 virtual ~MidiInputPort();
337
338 friend class MidiInputDevice;
339
340 private:
341 static SynchronizedConfig<std::set<Engine*> > SysexListeners; ///< All engines that are listening to sysex messages.
342 };
343
344 } // namsepace LinuxSampler
345
346 #endif // __LS_MIDIINPUTPORT_H__

  ViewVC Help
Powered by ViewVC