/[svn]/linuxsampler/trunk/src/mididriver/MidiInputDevice.h
ViewVC logotype

Contents of /linuxsampler/trunk/src/mididriver/MidiInputDevice.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 153 - (show annotations) (download) (as text)
Mon Jun 28 04:21:11 2004 UTC (19 years, 9 months ago) by senkov
File MIME type: text/x-c++hdr
File size: 13699 byte(s)
* Updated MIDI infrastructure similar to what was previously
done with the AUDIO
* Implemented Alsa driver using new infrastructure
* TODO: MacOS drivers!

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
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, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #ifndef __LS_MIDIINPUTDEVICE_H__
24 #define __LS_MIDIINPUTDEVICE_H__
25
26 #include <stdexcept>
27 #include <set>
28 #include <map>
29 #include <vector>
30
31 #include "../common/global.h"
32 #include "../common/LinuxSamplerException.h"
33 #include "../drivers/DeviceParameter.h"
34 #include "../engines/common/Engine.h"
35
36 namespace LinuxSampler {
37
38 // just symbol prototyping
39 class Engine;
40
41 /** Abstract base class for MIDI input drivers in LinuxSampler
42 *
43 * This class will be derived by specialized classes which implement the
44 * connection to a specific MIDI input system (e.g. Alsa Sequencer,
45 * CoreMIDI). The MidiInputDevice desendant should just call the
46 * appropriate (protected) Dispatch* method here when an MIDI event
47 * occured. The dispatch* methods here will automatically forward the
48 * MIDI event to the appropriate, connected sampler engines.
49 */
50 class MidiInputDevice {
51 public:
52
53 /////////////////////////////////////////////////////////////////
54 // type definitions
55
56 class ParameterActive : public DeviceCreationParameterBool {
57 public:
58 ParameterActive(MidiInputDevice *pDevice) {this->pDevice = pDevice; InitWithDefault(); }
59 ParameterActive(MidiInputDevice* pDevice, String active) throw (LinuxSamplerException) : DeviceCreationParameterBool(active) { this->pDevice = pDevice; }
60 virtual String Description() { return "Enable / disable device"; }
61 virtual bool Fix() { return false; }
62 virtual bool Mandatory() { return false; }
63 virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() { return std::map<String,DeviceCreationParameter*>(); }
64 virtual optional<bool> DefaultAsBool(std::map<String,String> Parameters) { return true; }
65 virtual void OnSetValue(bool b) throw (LinuxSamplerException) { if (b) pDevice->Listen(); else pDevice->StopListen(); }
66 protected:
67 MidiInputDevice* pDevice;
68 };
69
70 class ParameterPorts : public DeviceCreationParameterInt {
71 public:
72 ParameterPorts(MidiInputDevice* pDevice) { this->pDevice = pDevice; InitWithDefault();}
73 ParameterPorts(MidiInputDevice* pDevice, String val) throw (LinuxSamplerException) : DeviceCreationParameterInt(val) { this->pDevice = pDevice; }
74 virtual String Description() { return "Number of ports"; }
75 virtual bool Fix() { return false; }
76 virtual bool Mandatory() { return false; }
77 virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() { return std::map<String,DeviceCreationParameter*>(); }
78 virtual optional<int> DefaultAsInt(std::map<String,String> Parameters) { return 0; }
79 virtual optional<int> RangeMinAsInt(std::map<String,String> Parameters) { return optional<int>::nothing; }
80 virtual optional<int> RangeMaxAsInt(std::map<String,String> Parameters) { return optional<int>::nothing; }
81 virtual std::vector<int> PossibilitiesAsInt(std::map<String,String> Parameters) { return std::vector<int>(); }
82 virtual void OnSetValue(int i) throw (LinuxSamplerException) { pDevice->AcquirePorts(i); }
83 protected:
84 MidiInputDevice* pDevice;
85 };
86
87 class MidiInputPort {
88
89 public:
90 /**
91 * MIDI channels
92 */
93 enum midi_chan_t {
94 midi_chan_all = 0,
95 midi_chan_1 = 1,
96 midi_chan_2 = 2,
97 midi_chan_3 = 3,
98 midi_chan_4 = 4,
99 midi_chan_5 = 5,
100 midi_chan_6 = 6,
101 midi_chan_7 = 7,
102 midi_chan_8 = 8,
103 midi_chan_9 = 9,
104 midi_chan_10 = 10,
105 midi_chan_11 = 11,
106 midi_chan_12 = 12,
107 midi_chan_13 = 13,
108 midi_chan_14 = 14,
109 midi_chan_15 = 15,
110 midi_chan_16 = 16
111 };
112
113 class ParameterName : public DeviceCreationParameterString {
114 public:
115 ParameterName(MidiInputPort* pPort) { this->pPort = pPort; InitWithDefault();}
116 ParameterName(MidiInputPort* pPort, String val) : DeviceCreationParameterString(val) { this->pPort = pPort; }
117 virtual String Description() { return "Name for this port"; }
118 virtual bool Fix() { return false; }
119 virtual bool Mandatory() { return false; }
120 virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() { return std::map<String,DeviceCreationParameter*>(); }
121 virtual optional<String> Default(std::map<String,String> Parameters) { return ""; }
122 virtual std::vector<String> PossibilitiesAsString(std::map<String,String> Parameters) { return std::vector<String>(); }
123 virtual void OnSetValue(String s) throw (LinuxSamplerException) { return; /* FIXME: Nothing to do here */ }
124 protected:
125 MidiInputPort * pPort;
126 };
127
128 /////////////////////////////////////////////////////////////////
129 // normal methods
130 // (usually not to be overriden by descendant)
131
132 /**
133 * Connect given sampler engine with this MIDI input device.
134 * The engine can either be connected to one specific MIDI
135 * channel or all MIDI channels. If an engine gets connected
136 * twice to this MIDI input device, then the engine's old
137 * connection will be detached (no matter on which MIDI channel).
138 *
139 * @param pEngine - sampler engine
140 * @param MidiChannel - MIDI channel to connect to
141 * @throws MidiInputException if MidiChannel argument invalid
142 */
143 void Connect(Engine* pEngine, midi_chan_t MidiChannel);
144
145 /**
146 * Disconnect given sampler engine from this MIDI input device.
147 *
148 * @param pEngine - sampler engine
149 */
150 void Disconnect(Engine* pEngine);
151
152 static std::map<String,DeviceCreationParameter*> AvailableParameters();
153 std::map<String,DeviceCreationParameter*> DeviceParameters();
154 MidiInputDevice* GetDevice();
155 uint GetPortNumber();
156
157 /////////////////////////////////////////////////////////////////
158 // dispatch methods
159 // (should be called by the MidiInputDevice descendant on events)
160
161 /**
162 * Should be called by the implementing MIDI input device
163 * whenever a note on event arrived, this will cause the note on
164 * event to be forwarded to all connected engines on the
165 * corresponding MIDI channel.
166 *
167 * @param Key - MIDI key number of the triggered key
168 * @param Velocity - MIDI velocity of the triggered key
169 * @param MidiChannel - MIDI channel on which event occured on
170 */
171 void DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel);
172
173 /**
174 * Should be called by the implementing MIDI input device
175 * whenever a note off event arrived, this will cause the note
176 * off event to be forwarded to all connected engines on the
177 * corresponding MIDI channel.
178 *
179 * @param Key - MIDI key number of the released key
180 * @param Velocity - MIDI velocity of the released key
181 * @param MidiChannel - MIDI channel on which event occured on
182 */
183 void DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel);
184
185 /**
186 * Should be called by the implementing MIDI input device
187 * whenever a pitchbend event arrived, this will cause the
188 * pitchbend event to be forwarded to all connected engines.
189 *
190 * @param Pitch - MIDI pitch value
191 * @param MidiChannel - MIDI channel on which event occured on
192 */
193 void DispatchPitchbend(int Pitch, uint MidiChannel);
194
195 /**
196 * Should be called by the implementing MIDI input device
197 * whenever a control change event arrived, this will cause the
198 * control change event to be forwarded to all engines on the
199 * corresponding MIDI channel.
200 *
201 * @param Controller - MIDI controller number
202 * @param Value - MIDI control change value
203 * @param MidiChannel - MIDI channel on which event occured on
204 */
205 void DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel);
206
207 protected:
208 MidiInputPort(MidiInputDevice* pDevice, int portNumber) { this->pDevice = pDevice; this->portNumber = portNumber;}
209 MidiInputDevice* pDevice;
210 int portNumber;
211 std::map<String,DeviceCreationParameter*> Parameters; ///< All port parameters.
212 std::set<Engine*> MidiChannelMap[17]; ///< 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.
213 virtual ~MidiInputPort();
214
215 friend class MidiInputDevice;
216
217 private:
218 static std::map<String,DeviceCreationParameter*> CreateAvailableParameters();
219 };
220
221 /**
222 * Return midi port
223 */
224 MidiInputPort* GetPort(int i) { return Ports[i]; }
225
226 /**
227 * Create new Midi port
228 * This will be called by AcquirePorts
229 * Each individual device must implement this.
230 */
231 virtual MidiInputPort* CreateMidiPort( void ) = 0;
232
233 template <class Parameter_T>
234 class OptionalParameter {
235 public:
236 static Parameter_T* New(MidiInputDevice* pDevice, String val) { if (val == "") return (new Parameter_T(pDevice)); return (new Parameter_T(pDevice, val)); }
237 };
238
239 static std::map<String,DeviceCreationParameter*> AvailableParameters();
240 std::map<String,DeviceCreationParameter*> DeviceParameters();
241
242 /////////////////////////////////////////////////////////////////
243 // abstract methods
244 // (these have to be implemented by the descendant)
245
246 /**
247 * Start listen to MIDI input events on the MIDI input port.
248 * The MIDIInputPort descendant should forward all MIDI input
249 * events by calling the appropriate (protected) Dispatch*
250 * method of class MidiInputPort.
251 */
252 virtual void Listen() = 0;
253
254 /**
255 * Stop to listen to MIDI input events on the MIDI input port.
256 * After this method was called, the MidiInputPort descendant
257 * should ignore all MIDI input events.
258 */
259 virtual void StopListen() = 0;
260
261 /**
262 * Return device driver name
263 */
264 virtual String Driver() = 0;
265
266 protected:
267 std::map<String,DeviceCreationParameter*> Parameters; ///< All device parameters.
268 std::map<int,MidiInputPort*> Ports;
269
270 MidiInputDevice(std::map<String,DeviceCreationParameter*> DriverParameters);
271
272 virtual ~MidiInputDevice();
273
274
275 friend class Sampler; // allow Sampler class to destroy midi devices
276
277 private:
278 static std::map<String,DeviceCreationParameter*> CreateAvailableParameters();
279
280 /**
281 * Set number of MIDI ports required by the engine
282 * This can either do nothing, create more ports
283 * or destroy ports depenging on the parameter
284 * and how many ports already exist on this driver.
285 *
286 * @param Ports - number of ports to be left on this driver after this call.
287 */
288 void AcquirePorts(uint Ports);
289 };
290
291 /**
292 * Midi input exception that should be thrown by the MidiInputDevice
293 * descendants in case initialization of the MIDI input system failed
294 * (which should be done in the constructor of the MidiInputDevice
295 * descendant).
296 */
297 class MidiInputException : public LinuxSamplerException {
298 public:
299 MidiInputException(const std::string& msg) : LinuxSamplerException(msg) {}
300 };
301 }
302
303 #endif // __LS_MIDIINPUTDEVICE_H__

  ViewVC Help
Powered by ViewVC