/[svn]/linuxsampler/branches/release1_0_0/src/Sampler.cpp
ViewVC logotype

Contents of /linuxsampler/branches/release1_0_0/src/Sampler.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC