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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1934 - (hide annotations) (download)
Sun Jul 12 10:35:55 2009 UTC (14 years, 10 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 schoenebeck 201 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 1934 * Copyright (C) 2005 - 2009 Christian Schoenebeck *
7 schoenebeck 201 * *
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 schoenebeck 1424 #include "../../common/global_private.h"
27    
28 schoenebeck 289 #if HAVE_ALSA
29     # include "MidiInputDeviceAlsa.h"
30     #endif // HAVE_ALSA
31 schoenebeck 288
32 wylder 817 #if HAVE_COREMIDI
33 schoenebeck 361 # include "MidiInputDeviceCoreMidi.h"
34     #endif // HAVE_CORE_MIDI
35    
36     #if HAVE_MIDISHARE
37     # include "MidiInputDeviceMidiShare.h"
38     #endif // HAVE_MIDISHARE
39    
40 senoner 1481 #if HAVE_MME_MIDI
41     # include "MidiInputDeviceMme.h"
42     #endif // HAVE_MME_MIDI
43 persson 1651
44     #if HAVE_JACK_MIDI
45     # include "MidiInputDeviceJack.h"
46     #endif // HAVE_JACK_MIDI
47    
48 schoenebeck 201 namespace LinuxSampler {
49    
50     std::map<String, MidiInputDeviceFactory::InnerFactory*> MidiInputDeviceFactory::InnerFactories;
51     std::map<String, DeviceParameterFactory*> MidiInputDeviceFactory::ParameterFactories;
52    
53 schoenebeck 289 #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 schoenebeck 288
60 wylder 817 #if HAVE_COREMIDI
61 schoenebeck 361 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 wylder 817 #endif // HAVE_COREMIDI
66 schoenebeck 361
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 senoner 1481 #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 persson 1651 #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 schoenebeck 1934 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 schoenebeck 880 MidiInputDevice* MidiInputDeviceFactory::Create(String DriverName, std::map<String,String> Parameters, Sampler* pSampler) throw (Exception) {
109 schoenebeck 1934 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 schoenebeck 880 if (!InnerFactories.count(DriverName)) throw Exception("There is no midi input driver '" + DriverName + "'.");
126 schoenebeck 1934 // 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 schoenebeck 201 }
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 schoenebeck 880 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 schoenebeck 1934 std::map<String,DeviceCreationParameter*> thisDeviceParams;
185     DeviceParameterFactory* pParamFactory = ParameterFactories[DriverName];
186     if (pParamFactory) {
187     thisDeviceParams = pParamFactory->CreateAllParams();
188     }
189     return thisDeviceParams;
190 schoenebeck 201 }
191    
192 schoenebeck 880 DeviceCreationParameter* MidiInputDeviceFactory::GetDriverParameter(String DriverName, String ParameterName) throw (Exception) {
193 iliev 1835 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 schoenebeck 201 }
201    
202 schoenebeck 880 String MidiInputDeviceFactory::GetDriverDescription(String DriverName) throw (Exception) {
203     if (!InnerFactories.count(DriverName)) throw Exception("There is no midi input driver '" + DriverName + "'.");
204 schoenebeck 201 return InnerFactories[DriverName]->Description();
205     }
206    
207 schoenebeck 880 String MidiInputDeviceFactory::GetDriverVersion(String DriverName) throw (Exception) {
208     if (!InnerFactories.count(DriverName)) throw Exception("There is no midi input driver '" + DriverName + "'.");
209 schoenebeck 201 return InnerFactories[DriverName]->Version();
210     }
211    
212 schoenebeck 1934 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 schoenebeck 201 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC