/[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 1934 - (show annotations) (download)
Sun Jul 12 10:35:55 2009 UTC (14 years, 9 months ago) by schoenebeck
File size: 11166 byte(s)
* bugfix: don't allow to create or destroy audio devices and MIDI devices
  of host plugin implementations (e.g VST, AU, DSSI, LV2) on their own,
  as they only exist in the context of the plugin instance and would
  otherwise crash the application

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

  ViewVC Help
Powered by ViewVC