/[svn]/linuxsampler/trunk/src/drivers/midi/MidiInputDeviceFactory.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/drivers/midi/MidiInputDeviceFactory.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1993 - (show annotations) (download)
Sun Aug 30 11:27:35 2009 UTC (14 years, 7 months ago) by schoenebeck
File size: 11281 byte(s)
* ALSA MIDI driver supports now "NAME" device parameter, for overriding
  the ALSA sequencer client name

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 - 2009 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 #include "MidiInputDeviceFactory.h"
25
26 #include "../../common/global_private.h"
27
28 #if HAVE_ALSA
29 # include "MidiInputDeviceAlsa.h"
30 #endif // HAVE_ALSA
31
32 #if HAVE_COREMIDI
33 # include "MidiInputDeviceCoreMidi.h"
34 #endif // HAVE_CORE_MIDI
35
36 #if HAVE_MIDISHARE
37 # include "MidiInputDeviceMidiShare.h"
38 #endif // HAVE_MIDISHARE
39
40 #if HAVE_MME_MIDI
41 # include "MidiInputDeviceMme.h"
42 #endif // HAVE_MME_MIDI
43
44 #if HAVE_JACK_MIDI
45 # include "MidiInputDeviceJack.h"
46 #endif // HAVE_JACK_MIDI
47
48 namespace LinuxSampler {
49
50 std::map<String, MidiInputDeviceFactory::InnerFactory*> MidiInputDeviceFactory::InnerFactories;
51 std::map<String, DeviceParameterFactory*> MidiInputDeviceFactory::ParameterFactories;
52
53 #if HAVE_ALSA
54 REGISTER_MIDI_INPUT_DRIVER(MidiInputDeviceAlsa);
55 /* Common parameters */
56 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceAlsa, ParameterActive);
57 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceAlsa, ParameterPorts);
58 /* Driver specific parameters */
59 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceAlsa, ParameterName);
60 #endif // HAVE_ALSA
61
62 #if HAVE_COREMIDI
63 REGISTER_MIDI_INPUT_DRIVER(MidiInputDeviceCoreMidi);
64 /* Common parameters */
65 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceCoreMidi, ParameterActive);
66 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceCoreMidi, ParameterPorts);
67 #endif // HAVE_COREMIDI
68
69 #if HAVE_MIDISHARE
70 REGISTER_MIDI_INPUT_DRIVER(MidiInputDeviceMidiShare);
71 /* Common parameters */
72 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceMidiShare, ParameterActive);
73 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceMidiShare, ParameterPorts);
74 #endif // HAVE_MIDISHARE
75
76 #if HAVE_MME_MIDI
77 REGISTER_MIDI_INPUT_DRIVER(MidiInputDeviceMme);
78 /* Common parameters */
79 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceMme, ParameterActive);
80 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceMme, ParameterPorts);
81 #endif // HAVE_MME_MIDI
82
83 #if HAVE_JACK_MIDI
84 REGISTER_MIDI_INPUT_DRIVER(MidiInputDeviceJack);
85 /* Common parameters */
86 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceJack, ParameterActive);
87 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceJack, ParameterPorts);
88 /* Driver specific parameters */
89 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceJack, ParameterName);
90 #endif // HAVE_JACK_MIDI
91
92 MidiInputDeviceFactory::MidiInputDeviceMap MidiInputDeviceFactory::mMidiInputDevices;
93
94 /**
95 * Creates a new MIDI input device for the given driver name and
96 * parameters. Note, this method will also check whether it is actually
97 * allowed to create an instance of the given driver on its own and throw
98 * an Exception in case it is not allowed (this is the case for host plugin
99 * drivers like VST, AU, DSSI, LV2).
100 *
101 * @param DriverName - name of the driver of which a new device shall be created
102 * @param Parameters - device creation parameters which shall be passed to the driver's constructor
103 * @param pSampler - the sampler instance
104 *
105 * @returns pointer to the new device instance
106 * @throws Exception - in case the device could not be created
107 *
108 * @see CreatePrivate()
109 */
110 MidiInputDevice* MidiInputDeviceFactory::Create(String DriverName, std::map<String,String> Parameters, Sampler* pSampler) throw (Exception) {
111 if (!InnerFactories.count(DriverName))
112 throw Exception("There is no midi input driver '" + DriverName + "'.");
113 if (!InnerFactories[DriverName]->isAutonomousDriver())
114 throw Exception("You cannot directly create a new MIDI input device of the '" + DriverName + "' driver!");
115
116 return CreatePrivate(DriverName, Parameters, pSampler);
117 }
118
119 /**
120 * Same as Create(), but this method won't check whether it is allowed to
121 * create an instance of the given driver on its own. This method is
122 * usually called by host plugins (e.g. VST, AU, DSSI, LV2) to actually
123 * create their respective MIDI input devices for the sampler. Usually one
124 * shouldn't call this method directly, but call Create() instead.
125 */
126 MidiInputDevice* MidiInputDeviceFactory::CreatePrivate(String DriverName, std::map<String,String> Parameters, Sampler* pSampler) throw (Exception) {
127 if (!InnerFactories.count(DriverName)) throw Exception("There is no midi input driver '" + DriverName + "'.");
128 // let's see if we need to create parameters
129 std::map<String,DeviceCreationParameter*> thisDeviceParams;
130 DeviceParameterFactory* pParamFactory = ParameterFactories[DriverName];
131 if (pParamFactory) {
132 thisDeviceParams = pParamFactory->CreateAllParams(Parameters);
133 } else {
134 // no parameters are registered by the driver. Throw if any parameters were specified.
135 if (Parameters.size() != 0) throw Exception("Driver '" + DriverName + "' does not have any parameters.");
136 }
137
138 // get a free device id
139 int iDeviceId = -1;
140 for (int i = 0; i >= 0; i++) { // seek for a free place starting from the beginning
141 if (!mMidiInputDevices[i]) {
142 iDeviceId = i;
143 break;
144 }
145 }
146 if (iDeviceId < 0)
147 throw Exception("Could not retrieve free device ID!");
148
149 // now create the device using those parameters
150 MidiInputDevice* pDevice = InnerFactories[DriverName]->Create(thisDeviceParams, pSampler);
151 pDevice->setDeviceId(iDeviceId);
152 // now attach all parameters to the newely created device.
153 for (std::map<String,DeviceCreationParameter*>::iterator iter = thisDeviceParams.begin(); iter != thisDeviceParams.end(); iter++) {
154 iter->second->Attach(pDevice);
155 }
156
157 // add new audio device to the audio device list
158 mMidiInputDevices[iDeviceId] = pDevice;
159
160 return pDevice;
161 }
162
163 std::vector<String> MidiInputDeviceFactory::AvailableDrivers() {
164 std::vector<String> result;
165 std::map<String, InnerFactory*>::iterator iter = InnerFactories.begin();
166 while (iter != InnerFactories.end()) {
167 result.push_back(iter->first);
168 iter++;
169 }
170 return result;
171 }
172
173 String MidiInputDeviceFactory::AvailableDriversAsString() {
174 std::vector<String> drivers = AvailableDrivers();
175 String result;
176 std::vector<String>::iterator iter = drivers.begin();
177 for (; iter != drivers.end(); iter++) {
178 if (result != "") result += ",";
179 result += *iter;
180 }
181 return result;
182 }
183
184 std::map<String,DeviceCreationParameter*> MidiInputDeviceFactory::GetAvailableDriverParameters(String DriverName) throw (Exception) {
185 if (!InnerFactories.count(DriverName)) throw Exception("There is no midi input driver '" + DriverName + "'.");
186 std::map<String,DeviceCreationParameter*> thisDeviceParams;
187 DeviceParameterFactory* pParamFactory = ParameterFactories[DriverName];
188 if (pParamFactory) {
189 thisDeviceParams = pParamFactory->CreateAllParams();
190 }
191 return thisDeviceParams;
192 }
193
194 DeviceCreationParameter* MidiInputDeviceFactory::GetDriverParameter(String DriverName, String ParameterName) throw (Exception) {
195 if (!InnerFactories.count(DriverName)) throw Exception("There is no midi input driver '" + DriverName + "'.");
196 DeviceParameterFactory* pParamFactory = ParameterFactories[DriverName];
197 if (pParamFactory) {
198 try { return pParamFactory->Create(ParameterName); }
199 catch(Exception e) { }
200 }
201 throw Exception("Midi input driver '" + DriverName + "' does not have a parameter '" + ParameterName + "'.");
202 }
203
204 String MidiInputDeviceFactory::GetDriverDescription(String DriverName) throw (Exception) {
205 if (!InnerFactories.count(DriverName)) throw Exception("There is no midi input driver '" + DriverName + "'.");
206 return InnerFactories[DriverName]->Description();
207 }
208
209 String MidiInputDeviceFactory::GetDriverVersion(String DriverName) throw (Exception) {
210 if (!InnerFactories.count(DriverName)) throw Exception("There is no midi input driver '" + DriverName + "'.");
211 return InnerFactories[DriverName]->Version();
212 }
213
214 std::map<uint, MidiInputDevice*> MidiInputDeviceFactory::Devices() {
215 return mMidiInputDevices;
216 }
217
218 /**
219 * Destroys the given device. Usually this method shouldn't be called
220 * directly, Sampler::DestroyMidiInputDevice should be called instead,
221 * since it also takes care whether some sampler channel is still using
222 * the device, etc.
223 */
224 void MidiInputDeviceFactory::Destroy(MidiInputDevice* pDevice) throw (Exception) {
225 if (pDevice && !pDevice->isAutonomousDevice())
226 throw Exception("You cannot directly destroy this '" + pDevice->Driver() + "' device!");
227
228 DestroyPrivate(pDevice);
229 }
230
231 void MidiInputDeviceFactory::DestroyPrivate(MidiInputDevice* pDevice) throw (Exception) {
232 MidiInputDeviceMap::iterator iter = mMidiInputDevices.begin();
233 for (; iter != mMidiInputDevices.end(); iter++) {
234 if (iter->second == pDevice) {
235 // disable device
236 pDevice->StopListen();
237
238 // remove device from the device list
239 mMidiInputDevices.erase(iter);
240
241 // destroy and free device from memory
242 delete pDevice;
243
244 break;
245 }
246 }
247 }
248
249 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC