/[svn]/linuxsampler/trunk/src/Sampler.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/Sampler.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1934 - (show annotations) (download)
Sun Jul 12 10:35:55 2009 UTC (14 years, 8 months ago) by schoenebeck
File size: 29754 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 library 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 library 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 library; 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 <sstream>
25
26 #include "Sampler.h"
27
28 #include "common/global_private.h"
29 #include "engines/EngineFactory.h"
30 #include "engines/EngineChannelFactory.h"
31 #include "plugins/InstrumentEditorFactory.h"
32 #include "drivers/audio/AudioOutputDeviceFactory.h"
33 #include "drivers/midi/MidiInputDeviceFactory.h"
34 #include "drivers/midi/MidiInstrumentMapper.h"
35 #include "common/Features.h"
36 #include "network/lscpserver.h"
37
38 namespace LinuxSampler {
39
40 // ******************************************************************
41 // * SamplerChannel
42
43 SamplerChannel::SamplerChannel(Sampler* pS) {
44 pSampler = pS;
45 pEngineChannel = NULL;
46 pAudioOutputDevice = NULL;
47 pMidiInputDevice = NULL;
48 iMidiPort = 0;
49 midiChannel = midi_chan_all;
50 iIndex = -1;
51 }
52
53 SamplerChannel::~SamplerChannel() {
54 if (pEngineChannel) {
55 Engine* engine = pEngineChannel->GetEngine();
56 if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(engine);
57
58 MidiInputPort* pMidiInputPort = (pEngineChannel) ? pEngineChannel->GetMidiInputPort() : __GetMidiInputDevicePort(GetMidiInputChannel());
59 if (pMidiInputPort) pMidiInputPort->Disconnect(pEngineChannel);
60 if (pEngineChannel) {
61 if (pAudioOutputDevice) pEngineChannel->DisconnectAudioOutputDevice();
62 EngineChannelFactory::Destroy(pEngineChannel);
63
64 // reconnect engine if it still exists
65 const std::set<Engine*>& engines = EngineFactory::EngineInstances();
66 if (engines.find(engine) != engines.end()) pAudioOutputDevice->Connect(engine);
67 }
68 }
69 }
70
71 void SamplerChannel::SetEngineType(String EngineType) throw (Exception) {
72 dmsg(2,("SamplerChannel: Assigning engine type..."));
73
74 if (pEngineChannel) {
75 if (!strcasecmp(pEngineChannel->EngineName().c_str(), EngineType.c_str())) {
76 dmsg(2,("OK\n"));
77 return;
78 }
79 }
80
81 fireEngineToBeChanged();
82
83 // create new engine channel
84 EngineChannel* pNewEngineChannel = EngineChannelFactory::Create(EngineType);
85 if (!pNewEngineChannel) throw Exception("Unknown engine type");
86
87 pNewEngineChannel->SetSamplerChannel(this);
88
89 // dereference midi input port.
90 MidiInputPort* pMidiInputPort = __GetMidiInputDevicePort(GetMidiInputPort());
91 // disconnect old engine channel
92 if (pEngineChannel) {
93 Engine* engine = pEngineChannel->GetEngine();
94 if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(engine);
95
96 if (pMidiInputPort) pMidiInputPort->Disconnect(pEngineChannel);
97 if (pAudioOutputDevice) pEngineChannel->DisconnectAudioOutputDevice();
98 EngineChannelFactory::Destroy(pEngineChannel);
99
100 // reconnect engine if it still exists
101 const std::set<Engine*>& engines = EngineFactory::EngineInstances();
102 if (engines.find(engine) != engines.end()) pAudioOutputDevice->Connect(engine);
103 }
104
105 // connect new engine channel
106 if (pAudioOutputDevice) {
107 pNewEngineChannel->Connect(pAudioOutputDevice);
108 pAudioOutputDevice->Connect(pNewEngineChannel->GetEngine());
109 }
110 if (pMidiInputPort) pMidiInputPort->Connect(pNewEngineChannel, GetMidiInputChannel());
111 pEngineChannel = pNewEngineChannel;
112
113 // from now on get MIDI device and port from EngineChannel object
114 this->pMidiInputDevice = NULL;
115 this->iMidiPort = 0;
116
117 pEngineChannel->StatusChanged(true);
118 fireEngineChanged();
119 dmsg(2,("OK\n"));
120 }
121
122 void SamplerChannel::SetAudioOutputDevice(AudioOutputDevice* pDevice) {
123 if(pAudioOutputDevice == pDevice) return;
124
125 // disconnect old device
126 if (pAudioOutputDevice && pEngineChannel) {
127 Engine* engine = pEngineChannel->GetEngine();
128 pAudioOutputDevice->Disconnect(engine);
129
130 pEngineChannel->DisconnectAudioOutputDevice();
131
132 // reconnect engine if it still exists
133 const std::set<Engine*>& engines = EngineFactory::EngineInstances();
134 if (engines.find(engine) != engines.end()) pAudioOutputDevice->Connect(engine);
135 }
136
137 // connect new device
138 pAudioOutputDevice = pDevice;
139 if (pEngineChannel) {
140 pEngineChannel->Connect(pAudioOutputDevice);
141 pAudioOutputDevice->Connect(pEngineChannel->GetEngine());
142 }
143 }
144
145 void SamplerChannel::SetMidiInputDevice(MidiInputDevice* pDevice) {
146 SetMidiInput(pDevice, 0, GetMidiInputChannel());
147 }
148
149 void SamplerChannel::SetMidiInputPort(int MidiPort) {
150 SetMidiInput(GetMidiInputDevice(), MidiPort, GetMidiInputChannel());
151 }
152
153 void SamplerChannel::SetMidiInputChannel(midi_chan_t MidiChannel) {
154 SetMidiInput(GetMidiInputDevice(), GetMidiInputPort(), MidiChannel);
155 }
156
157 void SamplerChannel::SetMidiInput(MidiInputDevice* pDevice, int iMidiPort, midi_chan_t MidiChannel) {
158 if (!pDevice) throw Exception("No MIDI input device assigned.");
159
160 // get old and new midi input port
161 MidiInputPort* pOldMidiInputPort = __GetMidiInputDevicePort(GetMidiInputPort());
162 MidiInputPort* pNewMidiInputPort = pDevice->GetPort(iMidiPort);
163
164 // disconnect old device port
165 if (pOldMidiInputPort && pEngineChannel) pOldMidiInputPort->Disconnect(pEngineChannel);
166 // remember new device, port and channel if not engine channel yet created
167 if (!pEngineChannel) {
168 this->pMidiInputDevice = pDevice;
169 this->iMidiPort = iMidiPort;
170 this->midiChannel = MidiChannel;
171 }
172
173 // connect new device port
174 if (pNewMidiInputPort && pEngineChannel) pNewMidiInputPort->Connect(pEngineChannel, MidiChannel);
175 // Ooops.
176 if (pNewMidiInputPort == NULL)
177 throw Exception("There is no MIDI input port with index " + ToString(iMidiPort) + ".");
178 }
179
180 EngineChannel* SamplerChannel::GetEngineChannel() {
181 return pEngineChannel;
182 }
183
184 midi_chan_t SamplerChannel::GetMidiInputChannel() {
185 if (pEngineChannel) this->midiChannel = pEngineChannel->MidiChannel();
186 return this->midiChannel;
187 }
188
189 int SamplerChannel::GetMidiInputPort() {
190 MidiInputPort* pMidiInputPort = (pEngineChannel) ? pEngineChannel->GetMidiInputPort() : NULL;
191 if (pMidiInputPort) this->iMidiPort = (int) pMidiInputPort->GetPortNumber();
192 return iMidiPort;
193 }
194
195 AudioOutputDevice* SamplerChannel::GetAudioOutputDevice() {
196 return pAudioOutputDevice;
197 }
198
199 MidiInputDevice* SamplerChannel::GetMidiInputDevice() {
200 if (pEngineChannel)
201 pMidiInputDevice = (pEngineChannel->GetMidiInputPort()) ? pEngineChannel->GetMidiInputPort()->GetDevice() : NULL;
202 return pMidiInputDevice;
203 }
204
205 uint SamplerChannel::Index() {
206 if (iIndex >= 0) return iIndex;
207
208 Sampler::SamplerChannelMap::iterator iter = pSampler->mSamplerChannels.begin();
209 for (; iter != pSampler->mSamplerChannels.end(); iter++) {
210 if (iter->second == this) {
211 iIndex = iter->first;
212 return iIndex;
213 }
214 }
215
216 throw Exception("Internal error: SamplerChannel index not found");
217 }
218
219 Sampler* SamplerChannel::GetSampler() {
220 return pSampler;
221 }
222
223 void SamplerChannel::AddEngineChangeListener(EngineChangeListener* l) {
224 llEngineChangeListeners.AddListener(l);
225 }
226
227 void SamplerChannel::RemoveEngineChangeListener(EngineChangeListener* l) {
228 llEngineChangeListeners.RemoveListener(l);
229 }
230
231 void SamplerChannel::RemoveAllEngineChangeListeners() {
232 llEngineChangeListeners.RemoveAllListeners();
233 }
234
235 void SamplerChannel::fireEngineToBeChanged() {
236 for (int i = 0; i < llEngineChangeListeners.GetListenerCount(); i++) {
237 llEngineChangeListeners.GetListener(i)->EngineToBeChanged(Index());
238 }
239 }
240
241 void SamplerChannel::fireEngineChanged() {
242 for (int i = 0; i < llEngineChangeListeners.GetListenerCount(); i++) {
243 llEngineChangeListeners.GetListener(i)->EngineChanged(Index());
244 }
245 }
246
247 MidiInputPort* SamplerChannel::__GetMidiInputDevicePort(int iMidiPort) {
248 MidiInputPort* pMidiInputPort = NULL;
249 MidiInputDevice* pMidiInputDevice = GetMidiInputDevice();
250 if (pMidiInputDevice)
251 pMidiInputPort = pMidiInputDevice->GetPort(iMidiPort);
252 return pMidiInputPort;
253 }
254
255
256
257 // ******************************************************************
258 // * Sampler
259
260 Sampler::Sampler() {
261 eventHandler.SetSampler(this);
262 uiOldTotalVoiceCount = uiOldTotalStreamCount = 0;
263 }
264
265 Sampler::~Sampler() {
266 Reset();
267 }
268
269 uint Sampler::SamplerChannels() {
270 return mSamplerChannels.size();
271 }
272
273 void Sampler::AddChannelCountListener(ChannelCountListener* l) {
274 llChannelCountListeners.AddListener(l);
275 }
276
277 void Sampler::RemoveChannelCountListener(ChannelCountListener* l) {
278 llChannelCountListeners.RemoveListener(l);
279 }
280
281 void Sampler::fireChannelCountChanged(int NewCount) {
282 for (int i = 0; i < llChannelCountListeners.GetListenerCount(); i++) {
283 llChannelCountListeners.GetListener(i)->ChannelCountChanged(NewCount);
284 }
285 }
286
287 void Sampler::fireChannelAdded(SamplerChannel* pChannel) {
288 for (int i = 0; i < llChannelCountListeners.GetListenerCount(); i++) {
289 llChannelCountListeners.GetListener(i)->ChannelAdded(pChannel);
290 }
291 }
292
293 void Sampler::fireChannelToBeRemoved(SamplerChannel* pChannel) {
294 for (int i = 0; i < llChannelCountListeners.GetListenerCount(); i++) {
295 llChannelCountListeners.GetListener(i)->ChannelToBeRemoved(pChannel);
296 }
297 }
298
299 void Sampler::AddAudioDeviceCountListener(AudioDeviceCountListener* l) {
300 llAudioDeviceCountListeners.AddListener(l);
301 }
302
303 void Sampler::RemoveAudioDeviceCountListener(AudioDeviceCountListener* l) {
304 llAudioDeviceCountListeners.RemoveListener(l);
305 }
306
307 void Sampler::fireAudioDeviceCountChanged(int NewCount) {
308 for (int i = 0; i < llAudioDeviceCountListeners.GetListenerCount(); i++) {
309 llAudioDeviceCountListeners.GetListener(i)->AudioDeviceCountChanged(NewCount);
310 }
311 }
312
313 void Sampler::AddMidiDeviceCountListener(MidiDeviceCountListener* l) {
314 llMidiDeviceCountListeners.AddListener(l);
315 }
316
317 void Sampler::RemoveMidiDeviceCountListener(MidiDeviceCountListener* l) {
318 llMidiDeviceCountListeners.RemoveListener(l);
319 }
320
321 void Sampler::fireMidiDeviceCountChanged(int NewCount) {
322 for (int i = 0; i < llMidiDeviceCountListeners.GetListenerCount(); i++) {
323 llMidiDeviceCountListeners.GetListener(i)->MidiDeviceCountChanged(NewCount);
324 }
325 }
326
327 void Sampler::fireMidiDeviceToBeDestroyed(MidiInputDevice* pDevice) {
328 for (int i = 0; i < llMidiDeviceCountListeners.GetListenerCount(); i++) {
329 llMidiDeviceCountListeners.GetListener(i)->MidiDeviceToBeDestroyed(pDevice);
330 }
331 }
332
333 void Sampler::fireMidiDeviceCreated(MidiInputDevice* pDevice) {
334 for (int i = 0; i < llMidiDeviceCountListeners.GetListenerCount(); i++) {
335 llMidiDeviceCountListeners.GetListener(i)->MidiDeviceCreated(pDevice);
336 }
337 }
338
339 void Sampler::AddVoiceCountListener(VoiceCountListener* l) {
340 llVoiceCountListeners.AddListener(l);
341 }
342
343 void Sampler::RemoveVoiceCountListener(VoiceCountListener* l) {
344 llVoiceCountListeners.RemoveListener(l);
345 }
346
347 void Sampler::fireVoiceCountChanged(int ChannelId, int NewCount) {
348 std::map<uint, uint>::iterator it = mOldVoiceCounts.find(ChannelId);
349 if (it != mOldVoiceCounts.end()) {
350 uint oldCount = it->second;
351 if (NewCount == oldCount) return;
352 }
353
354 mOldVoiceCounts[ChannelId] = NewCount;
355
356 for (int i = 0; i < llVoiceCountListeners.GetListenerCount(); i++) {
357 llVoiceCountListeners.GetListener(i)->VoiceCountChanged(ChannelId, NewCount);
358 }
359 }
360
361 void Sampler::AddStreamCountListener(StreamCountListener* l) {
362 llStreamCountListeners.AddListener(l);
363 }
364
365 void Sampler::RemoveStreamCountListener(StreamCountListener* l) {
366 llStreamCountListeners.RemoveListener(l);
367 }
368
369 void Sampler::fireStreamCountChanged(int ChannelId, int NewCount) {
370 std::map<uint, uint>::iterator it = mOldStreamCounts.find(ChannelId);
371 if (it != mOldStreamCounts.end()) {
372 uint oldCount = it->second;
373 if (NewCount == oldCount) return;
374 }
375
376 mOldStreamCounts[ChannelId] = NewCount;
377
378 for (int i = 0; i < llStreamCountListeners.GetListenerCount(); i++) {
379 llStreamCountListeners.GetListener(i)->StreamCountChanged(ChannelId, NewCount);
380 }
381 }
382
383 void Sampler::AddBufferFillListener(BufferFillListener* l) {
384 llBufferFillListeners.AddListener(l);
385 }
386
387 void Sampler::RemoveBufferFillListener(BufferFillListener* l) {
388 llBufferFillListeners.RemoveListener(l);
389 }
390
391 void Sampler::fireBufferFillChanged(int ChannelId, String FillData) {
392 for (int i = 0; i < llBufferFillListeners.GetListenerCount(); i++) {
393 llBufferFillListeners.GetListener(i)->BufferFillChanged(ChannelId, FillData);
394 }
395 }
396
397 void Sampler::AddTotalStreamCountListener(TotalStreamCountListener* l) {
398 llTotalStreamCountListeners.AddListener(l);
399 }
400
401 void Sampler::RemoveTotalStreamCountListener(TotalStreamCountListener* l) {
402 llTotalStreamCountListeners.RemoveListener(l);
403 }
404
405 void Sampler::fireTotalStreamCountChanged(int NewCount) {
406 if (NewCount == uiOldTotalStreamCount) return;
407 uiOldTotalStreamCount = NewCount;
408
409 for (int i = 0; i < llTotalStreamCountListeners.GetListenerCount(); i++) {
410 llTotalStreamCountListeners.GetListener(i)->TotalStreamCountChanged(NewCount);
411 }
412 }
413
414 void Sampler::AddTotalVoiceCountListener(TotalVoiceCountListener* l) {
415 llTotalVoiceCountListeners.AddListener(l);
416 }
417
418 void Sampler::RemoveTotalVoiceCountListener(TotalVoiceCountListener* l) {
419 llTotalVoiceCountListeners.RemoveListener(l);
420 }
421
422 void Sampler::fireTotalVoiceCountChanged(int NewCount) {
423 if (NewCount == uiOldTotalVoiceCount) return;
424 uiOldTotalVoiceCount = NewCount;
425
426 for (int i = 0; i < llTotalVoiceCountListeners.GetListenerCount(); i++) {
427 llTotalVoiceCountListeners.GetListener(i)->TotalVoiceCountChanged(NewCount);
428 }
429 }
430
431 void Sampler::AddFxSendCountListener(FxSendCountListener* l) {
432 llFxSendCountListeners.AddListener(l);
433 }
434
435 void Sampler::RemoveFxSendCountListener(FxSendCountListener* l) {
436 llFxSendCountListeners.RemoveListener(l);
437 }
438
439 void Sampler::fireFxSendCountChanged(int ChannelId, int NewCount) {
440 for (int i = 0; i < llFxSendCountListeners.GetListenerCount(); i++) {
441 llFxSendCountListeners.GetListener(i)->FxSendCountChanged(ChannelId, NewCount);
442 }
443 }
444
445 void Sampler::EventHandler::EngineToBeChanged(int ChannelId) {
446 // nothing to do here
447 }
448
449 void Sampler::EventHandler::EngineChanged(int ChannelId) {
450 EngineChannel* engineChannel = pSampler->GetSamplerChannel(ChannelId)->GetEngineChannel();
451 if(engineChannel == NULL) return;
452 engineChannel->AddFxSendCountListener(this);
453 }
454
455 void Sampler::EventHandler::FxSendCountChanged(int ChannelId, int NewCount) {
456 pSampler->fireFxSendCountChanged(ChannelId, NewCount);
457 }
458
459
460 SamplerChannel* Sampler::AddSamplerChannel() {
461 // if there's no sampler channel yet
462 if (!mSamplerChannels.size()) {
463 SamplerChannel* pChannel = new SamplerChannel(this);
464 mSamplerChannels[0] = pChannel;
465 fireChannelAdded(pChannel);
466 fireChannelCountChanged(1);
467 pChannel->AddEngineChangeListener(&eventHandler);
468 return pChannel;
469 }
470
471 // get the highest used sampler channel index
472 uint lastIndex = (--(mSamplerChannels.end()))->first;
473
474 // check if we reached the index limit
475 if (lastIndex + 1 < lastIndex) {
476 // search for an unoccupied sampler channel index starting from 0
477 for (uint i = 0; i < lastIndex; i++) {
478 if (mSamplerChannels.find(i) != mSamplerChannels.end()) continue;
479 // we found an unused index, so insert the new channel there
480 SamplerChannel* pChannel = new SamplerChannel(this);
481 mSamplerChannels[i] = pChannel;
482 fireChannelAdded(pChannel);
483 fireChannelCountChanged(SamplerChannels());
484 pChannel->AddEngineChangeListener(&eventHandler);
485 return pChannel;
486 }
487 throw Exception("Internal error: could not find unoccupied sampler channel index.");
488 }
489
490 // we have not reached the index limit so we just add the channel past the highest index
491 SamplerChannel* pChannel = new SamplerChannel(this);
492 mSamplerChannels[lastIndex + 1] = pChannel;
493 fireChannelAdded(pChannel);
494 fireChannelCountChanged(SamplerChannels());
495 pChannel->AddEngineChangeListener(&eventHandler);
496 return pChannel;
497 }
498
499 SamplerChannel* Sampler::GetSamplerChannel(uint uiSamplerChannel) {
500 return (mSamplerChannels.find(uiSamplerChannel) != mSamplerChannels.end()) ? mSamplerChannels[uiSamplerChannel] : NULL;
501 }
502
503 std::map<uint, SamplerChannel*> Sampler::GetSamplerChannels() {
504 return mSamplerChannels;
505 }
506
507 void Sampler::RemoveSamplerChannel(SamplerChannel* pSamplerChannel) {
508 SamplerChannelMap::iterator iterChan = mSamplerChannels.begin();
509 for (; iterChan != mSamplerChannels.end(); iterChan++) {
510 if (iterChan->second == pSamplerChannel) {
511 fireChannelToBeRemoved(pSamplerChannel);
512 mOldVoiceCounts.erase(pSamplerChannel->Index());
513 mOldStreamCounts.erase(pSamplerChannel->Index());
514 pSamplerChannel->RemoveAllEngineChangeListeners();
515 mSamplerChannels.erase(iterChan);
516 delete pSamplerChannel;
517 fireChannelCountChanged(SamplerChannels());
518 return;
519 }
520 }
521 }
522
523 void Sampler::RemoveSamplerChannel(uint uiSamplerChannel) {
524 SamplerChannel* pChannel = GetSamplerChannel(uiSamplerChannel);
525 if (!pChannel) return;
526 RemoveSamplerChannel(pChannel);
527 }
528
529 void Sampler::RemoveAllSamplerChannels() {
530 /*
531 * In maps iterator invalidation occurs when the iterator point
532 * to the element that is being erased. So we need to copy the map
533 * by calling GetSamplerChannels() to prevent that.
534 */
535 SamplerChannelMap chns = GetSamplerChannels();
536 SamplerChannelMap::iterator iter = chns.begin();
537 for(; iter != chns.end(); iter++) {
538 RemoveSamplerChannel(iter->second);
539 }
540 }
541
542 std::vector<String> Sampler::AvailableAudioOutputDrivers() {
543 return AudioOutputDeviceFactory::AvailableDrivers();
544 }
545
546 std::vector<String> Sampler::AvailableMidiInputDrivers() {
547 return MidiInputDeviceFactory::AvailableDrivers();
548 }
549
550 std::vector<String> Sampler::AvailableEngineTypes() {
551 return EngineFactory::AvailableEngineTypes();
552 }
553
554 AudioOutputDevice* Sampler::CreateAudioOutputDevice(String AudioDriver, std::map<String,String> Parameters) throw (Exception) {
555 // create new device
556 AudioOutputDevice* pDevice = AudioOutputDeviceFactory::Create(AudioDriver, Parameters);
557
558 fireAudioDeviceCountChanged(AudioOutputDevices());
559 return pDevice;
560 }
561
562 uint Sampler::AudioOutputDevices() {
563 return AudioOutputDeviceFactory::Devices().size();
564 }
565
566 uint Sampler::MidiInputDevices() {
567 return MidiInputDeviceFactory::Devices().size();
568 }
569
570 std::map<uint, AudioOutputDevice*> Sampler::GetAudioOutputDevices() {
571 return AudioOutputDeviceFactory::Devices();
572 }
573
574 std::map<uint, MidiInputDevice*> Sampler::GetMidiInputDevices() {
575 return MidiInputDeviceFactory::Devices();
576 }
577
578 void Sampler::DestroyAudioOutputDevice(AudioOutputDevice* pDevice) throw (Exception) {
579 if (pDevice) {
580 // check if there are still sampler engines connected to this device
581 for (SamplerChannelMap::iterator iterChan = mSamplerChannels.begin();
582 iterChan != mSamplerChannels.end(); iterChan++
583 ) if (iterChan->second->GetAudioOutputDevice() == pDevice) throw Exception("Sampler channel " + ToString(iterChan->first) + " is still connected to the audio output device.");
584
585 //TODO: should we add fireAudioDeviceToBeDestroyed() here ?
586 AudioOutputDeviceFactory::Destroy(pDevice);
587 fireAudioDeviceCountChanged(AudioOutputDevices());
588 }
589 }
590
591 void Sampler::DestroyAllAudioOutputDevices() throw (Exception) {
592 /*
593 * In maps iterator invalidation occurs when the iterator point
594 * to the element that is being erased. So we need to copy the map
595 * by calling GetAudioOutputDevices() to prevent that.
596 */
597 std::map<uint, AudioOutputDevice*> devs = GetAudioOutputDevices();
598 std::map<uint, AudioOutputDevice*>::iterator iter = devs.begin();
599 for (; iter != devs.end(); iter++) {
600 AudioOutputDevice* pDevice = iter->second;
601
602 // skip non-autonomous devices
603 if (!pDevice->isAutonomousDevice()) continue;
604
605 DestroyAudioOutputDevice(pDevice);
606 }
607 }
608
609 void Sampler::DestroyMidiInputDevice(MidiInputDevice* pDevice) throw (Exception) {
610 if (pDevice) {
611 // check if there are still sampler engines connected to this device
612 for (SamplerChannelMap::iterator iterChan = mSamplerChannels.begin();
613 iterChan != mSamplerChannels.end(); iterChan++
614 ) if (iterChan->second->GetMidiInputDevice() == pDevice) throw Exception("Sampler channel " + ToString(iterChan->first) + " is still connected to the midi input device.");
615
616 fireMidiDeviceToBeDestroyed(pDevice);
617 MidiInputDeviceFactory::Destroy(pDevice);
618 fireMidiDeviceCountChanged(MidiInputDevices());
619 }
620 }
621
622 void Sampler::DestroyAllMidiInputDevices() throw (Exception) {
623 /*
624 * In maps iterator invalidation occurs when the iterator point
625 * to the element that is being erased. So we need to copy the map
626 * by calling GetMidiInputDevices() to prevent that.
627 */
628 std::map<uint, MidiInputDevice*> devs = GetMidiInputDevices();
629 std::map<uint, MidiInputDevice*>::iterator iter = devs.begin();
630 for (; iter != devs.end(); iter++) {
631 MidiInputDevice* pDevice = iter->second;
632
633 // skip non-autonomous devices
634 if (!pDevice->isAutonomousDevice()) continue;
635
636 DestroyMidiInputDevice(pDevice);
637 }
638 }
639
640 MidiInputDevice* Sampler::CreateMidiInputDevice(String MidiDriver, std::map<String,String> Parameters) throw (Exception) {
641 // create new device
642 MidiInputDevice* pDevice = MidiInputDeviceFactory::Create(MidiDriver, Parameters, this);
643
644 fireMidiDeviceCreated(pDevice);
645 fireMidiDeviceCountChanged(MidiInputDevices());
646 return pDevice;
647 }
648
649 int Sampler::GetDiskStreamCount() {
650 int count = 0;
651 std::set<Engine*>::iterator it = EngineFactory::EngineInstances().begin();
652
653 for(; it != EngineFactory::EngineInstances().end(); it++) {
654 count += (*it)->DiskStreamCount();
655 }
656
657 return count;
658 }
659
660 int Sampler::GetVoiceCount() {
661 int count = 0;
662 std::set<Engine*>::iterator it = EngineFactory::EngineInstances().begin();
663
664 for(; it != EngineFactory::EngineInstances().end(); it++) {
665 count += (*it)->VoiceCount();
666 }
667
668 return count;
669 }
670
671 void Sampler::Reset() {
672 // delete sampler channels
673 try {
674 RemoveAllSamplerChannels();
675 }
676 catch(...) {
677 std::cerr << "Sampler::Reset(): Exception occured while trying to delete all sampler channels, exiting.\n" << std::flush;
678 exit(EXIT_FAILURE);
679 }
680
681 // delete midi input devices
682 try {
683 DestroyAllMidiInputDevices();
684 }
685 catch(...) {
686 std::cerr << "Sampler::Reset(): Exception occured while trying to delete all MIDI input devices, exiting.\n" << std::flush;
687 exit(EXIT_FAILURE);
688 }
689
690 // delete audio output devices
691 try {
692 DestroyAllAudioOutputDevices();
693 }
694 catch(...) {
695 std::cerr << "Sampler::Reset(): Exception occured while trying to delete all audio output devices, exiting.\n" << std::flush;
696 exit(EXIT_FAILURE);
697 }
698
699 // delete MIDI instrument maps
700 try {
701 MidiInstrumentMapper::RemoveAllMaps();
702 }
703 catch(...) {
704 std::cerr << "Sampler::Reset(): Exception occured while trying to delete all MIDI instrument maps, exiting.\n" << std::flush;
705 exit(EXIT_FAILURE);
706 }
707
708 // unload all instrument editor DLLs
709 InstrumentEditorFactory::ClosePlugins();
710 }
711
712 bool Sampler::EnableDenormalsAreZeroMode() {
713 Features::detect();
714 return Features::enableDenormalsAreZeroMode();
715 }
716
717 void Sampler::fireStatistics() {
718 static const LSCPEvent::event_t eventsArr[] = {
719 LSCPEvent::event_voice_count, LSCPEvent::event_stream_count,
720 LSCPEvent::event_buffer_fill, LSCPEvent::event_total_voice_count
721 };
722 static const std::list<LSCPEvent::event_t> events(eventsArr, eventsArr + 4);
723
724 if (LSCPServer::EventSubscribers(events))
725 {
726 LSCPServer::LockRTNotify();
727 std::map<uint,SamplerChannel*> channels = GetSamplerChannels();
728 std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
729 for (; iter != channels.end(); iter++) {
730 SamplerChannel* pSamplerChannel = iter->second;
731 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
732 if (!pEngineChannel) continue;
733 Engine* pEngine = pEngineChannel->GetEngine();
734 if (!pEngine) continue;
735 fireVoiceCountChanged(iter->first, pEngineChannel->GetVoiceCount());
736 fireStreamCountChanged(iter->first, pEngineChannel->GetDiskStreamCount());
737 fireBufferFillChanged(iter->first, pEngine->DiskStreamBufferFillPercentage());
738 }
739
740 fireTotalStreamCountChanged(GetDiskStreamCount());
741 fireTotalVoiceCountChanged(GetVoiceCount());
742
743 LSCPServer::UnlockRTNotify();
744 }
745 }
746
747 #if defined(WIN32)
748 static HINSTANCE dllInstance = NULL;
749
750 String Sampler::GetInstallDir() {
751 char buf[MAX_PATH + 1];
752 if (GetModuleFileName(dllInstance, buf, MAX_PATH)) {
753 String s(buf);
754 size_t n = s.rfind('\\');
755 if (n != String::npos) {
756 return s.substr(0, n);
757 }
758 }
759 return "";
760 }
761 #endif
762 } // namespace LinuxSampler
763
764 #if defined(WIN32)
765 extern "C" {
766 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
767 {
768 switch (reason) {
769 case DLL_PROCESS_ATTACH:
770 LinuxSampler::dllInstance = instance;
771 break;
772 }
773 return TRUE;
774 }
775 }
776 #endif

  ViewVC Help
Powered by ViewVC