/[svn]/linuxsampler/trunk/src/drivers/audio/AudioOutputDeviceFactory.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/drivers/audio/AudioOutputDeviceFactory.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2201 - (hide annotations) (download)
Thu Jul 7 19:19:09 2011 UTC (12 years, 9 months ago) by iliev
File size: 13310 byte(s)
* Fixed possible crashes due to corrupted MIDI/audio device list
  after MIDI/audio device creation failure

1 schoenebeck 200 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 persson 1889 * Copyright (C) 2005 - 2009 Christian Schoenebeck *
7 schoenebeck 200 * *
8 schoenebeck 838 * This library is free software; you can redistribute it and/or modify *
9 schoenebeck 200 * 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 schoenebeck 838 * This library is distributed in the hope that it will be useful, *
14 schoenebeck 200 * 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 schoenebeck 838 * along with this library; if not, write to the Free Software *
20 schoenebeck 200 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21     * MA 02111-1307 USA *
22     ***************************************************************************/
23    
24     #include "AudioOutputDeviceFactory.h"
25    
26 schoenebeck 1424 #include "../../common/global_private.h"
27    
28 schoenebeck 289 #if HAVE_ALSA
29     # include "AudioOutputDeviceAlsa.h"
30     #endif // HAVE_ALSA
31 schoenebeck 288
32 schoenebeck 289 #if HAVE_JACK
33     # include "AudioOutputDeviceJack.h"
34     #endif // HAVE_JACK
35    
36 schoenebeck 838 #if HAVE_ARTS
37     # include "AudioOutputDeviceArts.h"
38     #endif // HAVE_ARTS
39    
40 senoner 1481 #if HAVE_ASIO
41     # include "AudioOutputDeviceAsio.h"
42     #endif // HAVE_ASIO
43 iliev 1829
44     #if HAVE_COREAUDIO
45     # include "AudioOutputDeviceCoreAudio.h"
46     #endif // HAVE_COREAUDIO
47    
48 schoenebeck 200 namespace LinuxSampler {
49    
50     std::map<String, AudioOutputDeviceFactory::InnerFactory*> AudioOutputDeviceFactory::InnerFactories;
51     std::map<String, DeviceParameterFactory*> AudioOutputDeviceFactory::ParameterFactories;
52    
53 schoenebeck 289 #if HAVE_ALSA
54     REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDeviceAlsa);
55     /* Common parameters for now they'll have to be registered here. */
56     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterActive);
57     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterSampleRate);
58     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterChannels);
59     /* Driver specific parameters */
60     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterCard);
61     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterFragments);
62     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAlsa, ParameterFragmentSize);
63     #endif // HAVE_ALSA
64 schoenebeck 288
65 schoenebeck 289 #if HAVE_JACK
66     REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDeviceJack);
67     /* Common parameters for now they'll have to be registered here. */
68     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceJack, ParameterActive);
69 schoenebeck 1604 REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceJack, ParameterSampleRate);
70 schoenebeck 289 REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceJack, ParameterChannels);
71 schoenebeck 374 /* Driver specific parameters */
72     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceJack, ParameterName);
73 schoenebeck 289 #endif // HAVE_JACK
74    
75 schoenebeck 838 #if HAVE_ARTS
76     REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDeviceArts);
77     /* Common parameters for now they'll have to be registered here. */
78     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceArts, ParameterActive);
79     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceArts, ParameterSampleRate);
80     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceArts, ParameterChannels);
81     /* Driver specific parameters */
82     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceArts, ParameterName);
83     #endif // HAVE_ARTS
84    
85 senoner 1481 #if HAVE_ASIO
86     REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDeviceAsio);
87     /* Common parameters for now they'll have to be registered here. */
88     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAsio, ParameterActive);
89     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAsio, ParameterSampleRate);
90     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAsio, ParameterChannels);
91     /* Driver specific parameters */
92     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAsio, ParameterCard);
93     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceAsio, ParameterFragmentSize);
94     #endif // HAVE_ASIO
95    
96 iliev 1829 #if HAVE_COREAUDIO
97     REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDeviceCoreAudio);
98     /* Common parameters for now they'll have to be registered here. */
99     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceCoreAudio, ParameterActive);
100     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceCoreAudio, ParameterSampleRate);
101     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceCoreAudio, ParameterChannels);
102 iliev 1832 REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceCoreAudio, ParameterDevice);
103 iliev 1829 REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceCoreAudio, ParameterBuffers);
104     REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDeviceCoreAudio, ParameterBufferSize);
105     #endif // HAVE_COREAUDIO
106    
107 schoenebeck 1934 AudioOutputDeviceFactory::AudioOutputDeviceMap AudioOutputDeviceFactory::mAudioOutputDevices;
108    
109     /**
110     * Creates a new audio output device for the given driver name and
111     * parameters. Note, this method will also check whether it is actually
112     * allowed to create an instance of the given driver on its own and throw
113     * an Exception in case it is not allowed (this is the case for host plugin
114     * drivers like VST, AU, DSSI, LV2).
115     *
116     * @param DriverName - name of the driver of which a new device shall be created
117     * @param Parameters - device creation parameters which shall be passed to the driver's constructor
118     *
119     * @returns pointer to the new device instance
120     * @throws Exception - in case the device could not be created
121     *
122     * @see CreatePrivate()
123     */
124 schoenebeck 880 AudioOutputDevice* AudioOutputDeviceFactory::Create(String DriverName, std::map<String,String> Parameters) throw (Exception) {
125 schoenebeck 1934 if (!InnerFactories.count(DriverName))
126     throw Exception("There is no audio output driver '" + DriverName + "'.");
127     if (!InnerFactories[DriverName]->isAutonomousDriver())
128     throw Exception("You cannot directly create a new audio output device of the '" + DriverName + "' driver!");
129    
130     return CreatePrivate(DriverName, Parameters);
131     }
132    
133     /**
134     * Same as Create(), but this method won't check whether it is allowed to
135     * create an instance of the given driver on its own. This method is
136     * usually called by host plugins (e.g. VST, AU, DSSI, LV2) to actually
137     * create their respective audio output devices for the sampler. Usually
138     * one shouldn't call this method directly, but call Create() instead.
139     */
140     AudioOutputDevice* AudioOutputDeviceFactory::CreatePrivate(String DriverName, std::map<String,String> Parameters) throw (Exception) {
141 schoenebeck 880 if (!InnerFactories.count(DriverName)) throw Exception("There is no audio output driver '" + DriverName + "'.");
142 schoenebeck 1934 // let's see if we need to create parameters
143     std::map<String,DeviceCreationParameter*> thisDeviceParams;
144     DeviceParameterFactory* pParamFactory = ParameterFactories[DriverName];
145     if (pParamFactory) {
146     thisDeviceParams = pParamFactory->CreateAllParams(Parameters);
147     } else {
148     // no parameters are registered by the driver. Throw if any parameters were specified.
149     if (Parameters.size() != 0) throw Exception("Driver '" + DriverName + "' does not have any parameters.");
150     }
151    
152     // get a free device id
153     int iDeviceId = -1;
154     for (int i = 0; i >= 0; i++) { // seek for a free place starting from the beginning
155     if (!mAudioOutputDevices[i]) {
156     iDeviceId = i;
157 iliev 2201 mAudioOutputDevices.erase(i);
158 schoenebeck 1934 break;
159     }
160     }
161     if (iDeviceId < 0)
162     throw Exception("Could not retrieve free device ID!");
163    
164     // now create the device using those parameters
165 schoenebeck 200 AudioOutputDevice* pDevice = InnerFactories[DriverName]->Create(thisDeviceParams);
166 schoenebeck 1934 pDevice->setDeviceId(iDeviceId);
167     // now attach all parameters to the newely created device.
168     for (std::map<String,DeviceCreationParameter*>::iterator iter = thisDeviceParams.begin(); iter != thisDeviceParams.end(); iter++) {
169     iter->second->Attach(pDevice);
170     }
171    
172     // add new audio device to the audio device list
173     mAudioOutputDevices[iDeviceId] = pDevice;
174    
175     return pDevice;
176 schoenebeck 200 }
177    
178     std::vector<String> AudioOutputDeviceFactory::AvailableDrivers() {
179     std::vector<String> result;
180     std::map<String, InnerFactory*>::iterator iter = InnerFactories.begin();
181     while (iter != InnerFactories.end()) {
182     result.push_back(iter->first);
183     iter++;
184     }
185     return result;
186     }
187    
188     String AudioOutputDeviceFactory::AvailableDriversAsString() {
189     std::vector<String> drivers = AvailableDrivers();
190     String result;
191     std::vector<String>::iterator iter = drivers.begin();
192     for (; iter != drivers.end(); iter++) {
193     if (result != "") result += ",";
194     result += *iter;
195     }
196     return result;
197     }
198    
199 schoenebeck 880 std::map<String,DeviceCreationParameter*> AudioOutputDeviceFactory::GetAvailableDriverParameters(String DriverName) throw (Exception) {
200     if (!InnerFactories.count(DriverName)) throw Exception("There is no audio output driver '" + DriverName + "'.");
201 schoenebeck 1934 std::map<String,DeviceCreationParameter*> thisDeviceParams;
202     DeviceParameterFactory* pParamFactory = ParameterFactories[DriverName];
203     if (pParamFactory) {
204     thisDeviceParams = pParamFactory->CreateAllParams();
205     }
206 schoenebeck 200 return thisDeviceParams;
207     }
208    
209 schoenebeck 880 DeviceCreationParameter* AudioOutputDeviceFactory::GetDriverParameter(String DriverName, String ParameterName) throw (Exception) {
210 iliev 1835 if (!InnerFactories.count(DriverName)) throw Exception("There is no audio output driver '" + DriverName + "'.");
211     DeviceParameterFactory* pParamFactory = ParameterFactories[DriverName];
212     if (pParamFactory) {
213     try { return pParamFactory->Create(ParameterName); }
214     catch(Exception e) { }
215     }
216     throw Exception("Audio output driver '" + DriverName + "' does not have a parameter '" + ParameterName + "'.");
217 schoenebeck 200 }
218    
219 schoenebeck 880 String AudioOutputDeviceFactory::GetDriverDescription(String DriverName) throw (Exception) {
220     if (!InnerFactories.count(DriverName)) throw Exception("There is no audio output driver '" + DriverName + "'.");
221 schoenebeck 200 return InnerFactories[DriverName]->Description();
222     }
223    
224 schoenebeck 880 String AudioOutputDeviceFactory::GetDriverVersion(String DriverName) throw (Exception) {
225     if (!InnerFactories.count(DriverName)) throw Exception("There is no audio output driver '" + DriverName + "'.");
226 schoenebeck 200 return InnerFactories[DriverName]->Version();
227     }
228    
229 persson 1889 void AudioOutputDeviceFactory::Unregister(String DriverName) {
230     std::map<String, InnerFactory*>::iterator iter = InnerFactories.find(DriverName);
231     if (iter != InnerFactories.end()) {
232     delete iter->second;
233     InnerFactories.erase(iter);
234     }
235    
236     std::map<String, DeviceParameterFactory*>::iterator iterpf = ParameterFactories.find(DriverName);
237     if (iterpf != ParameterFactories.end()) {
238     delete iterpf->second;
239     ParameterFactories.erase(iterpf);
240     }
241     }
242    
243 schoenebeck 1934 std::map<uint, AudioOutputDevice*> AudioOutputDeviceFactory::Devices() {
244     return mAudioOutputDevices;
245     }
246    
247     /**
248     * Destroys the given device. Usually this method shouldn't be called
249     * directly, Sampler::DestroyAudioOutputDevice should be called instead,
250     * since it also takes care whether some sampler channel is still using
251     * the device, etc.
252     */
253     void AudioOutputDeviceFactory::Destroy(AudioOutputDevice* pDevice) throw (Exception) {
254     if (pDevice && !pDevice->isAutonomousDevice())
255     throw Exception("You cannot directly destroy this '" + pDevice->Driver() + "' device!");
256    
257     DestroyPrivate(pDevice);
258     }
259    
260     void AudioOutputDeviceFactory::DestroyPrivate(AudioOutputDevice* pDevice) throw (Exception) {
261     AudioOutputDeviceMap::iterator iter = mAudioOutputDevices.begin();
262     for (; iter != mAudioOutputDevices.end(); iter++) {
263     if (iter->second == pDevice) {
264     // disable device
265     pDevice->Stop();
266     // remove device from the device list
267     mAudioOutputDevices.erase(iter);
268     // destroy and free device from memory
269     delete pDevice;
270    
271     break;
272     }
273     }
274     }
275    
276 schoenebeck 200 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC