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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1283 - (hide annotations) (download)
Fri Aug 10 15:06:11 2007 UTC (16 years, 8 months ago) by iliev
File size: 23616 byte(s)
* fixed a crash which occurs when reassigning the same engine
  on a sampler channel with connected MIDI device

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 61 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 1008 * Copyright (C) 2005 - 2007 Christian Schoenebeck *
7 schoenebeck 53 * *
8 schoenebeck 1008 * This library is free software; you can redistribute it and/or modify *
9 schoenebeck 53 * 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 1008 * This library is distributed in the hope that it will be useful, *
14 schoenebeck 53 * 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 1008 * along with this library; if not, write to the Free Software *
20 schoenebeck 53 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21     * MA 02111-1307 USA *
22     ***************************************************************************/
23    
24 schoenebeck 123 #include <sstream>
25    
26 schoenebeck 53 #include "Sampler.h"
27    
28 iliev 778 #include "engines/EngineFactory.h"
29 schoenebeck 411 #include "engines/EngineChannelFactory.h"
30 schoenebeck 1212 #include "engines/InstrumentEditorFactory.h"
31 schoenebeck 203 #include "drivers/audio/AudioOutputDeviceFactory.h"
32     #include "drivers/midi/MidiInputDeviceFactory.h"
33 schoenebeck 1008 #include "drivers/midi/MidiInstrumentMapper.h"
34 schoenebeck 53
35     namespace LinuxSampler {
36    
37     // ******************************************************************
38     // * SamplerChannel
39    
40     SamplerChannel::SamplerChannel(Sampler* pS) {
41     pSampler = pS;
42 schoenebeck 411 pEngineChannel = NULL;
43 schoenebeck 675 pAudioOutputDevice = NULL;
44 capela 159 pMidiInputDevice = NULL;
45 schoenebeck 675 iMidiPort = 0;
46     midiChannel = midi_chan_all;
47 schoenebeck 53 iIndex = -1;
48     }
49    
50     SamplerChannel::~SamplerChannel() {
51 schoenebeck 411 if (pEngineChannel) {
52 persson 840 Engine* engine = pEngineChannel->GetEngine();
53     if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(engine);
54    
55 schoenebeck 675 MidiInputPort* pMidiInputPort = (pEngineChannel) ? pEngineChannel->GetMidiInputPort() : __GetMidiInputDevicePort(GetMidiInputChannel());
56 schoenebeck 411 if (pMidiInputPort) pMidiInputPort->Disconnect(pEngineChannel);
57 schoenebeck 420 if (pEngineChannel) {
58     if (pAudioOutputDevice) pEngineChannel->DisconnectAudioOutputDevice();
59 schoenebeck 660 EngineChannelFactory::Destroy(pEngineChannel);
60 persson 840
61     // reconnect engine if it still exists
62     const std::set<Engine*>& engines = EngineFactory::EngineInstances();
63     if (engines.find(engine) != engines.end()) pAudioOutputDevice->Connect(engine);
64 schoenebeck 420 }
65 schoenebeck 53 }
66     }
67    
68 schoenebeck 880 void SamplerChannel::SetEngineType(String EngineType) throw (Exception) {
69 schoenebeck 411 dmsg(2,("SamplerChannel: Assigning engine type..."));
70 iliev 1283
71     if (pEngineChannel) {
72     if (!strcasecmp(pEngineChannel->EngineName().c_str(), EngineType.c_str())) {
73     dmsg(2,("OK\n"));
74     return;
75     }
76     }
77 schoenebeck 53
78 schoenebeck 411 // create new engine channel
79     EngineChannel* pNewEngineChannel = EngineChannelFactory::Create(EngineType);
80 schoenebeck 880 if (!pNewEngineChannel) throw Exception("Unknown engine type");
81 schoenebeck 53
82 schoenebeck 660 //FIXME: hack to allow fast retrieval of engine channel's sampler channel index
83     pNewEngineChannel->iSamplerChannelIndex = Index();
84    
85 capela 159 // dereference midi input port.
86 schoenebeck 675 MidiInputPort* pMidiInputPort = __GetMidiInputDevicePort(GetMidiInputPort());
87     // disconnect old engine channel
88 schoenebeck 411 if (pEngineChannel) {
89 persson 840 Engine* engine = pEngineChannel->GetEngine();
90     if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(engine);
91    
92 schoenebeck 411 if (pMidiInputPort) pMidiInputPort->Disconnect(pEngineChannel);
93 schoenebeck 412 if (pAudioOutputDevice) pEngineChannel->DisconnectAudioOutputDevice();
94 schoenebeck 660 EngineChannelFactory::Destroy(pEngineChannel);
95 persson 840
96     // reconnect engine if it still exists
97     const std::set<Engine*>& engines = EngineFactory::EngineInstances();
98     if (engines.find(engine) != engines.end()) pAudioOutputDevice->Connect(engine);
99 schoenebeck 53 }
100    
101 schoenebeck 411 // connect new engine channel
102 schoenebeck 412 if (pAudioOutputDevice) {
103     pNewEngineChannel->Connect(pAudioOutputDevice);
104     pAudioOutputDevice->Connect(pNewEngineChannel->GetEngine());
105     }
106 persson 846 if (pMidiInputPort) pMidiInputPort->Connect(pNewEngineChannel, GetMidiInputChannel());
107 schoenebeck 675 pEngineChannel = pNewEngineChannel;
108    
109     // from now on get MIDI device and port from EngineChannel object
110     this->pMidiInputDevice = NULL;
111     this->iMidiPort = 0;
112    
113 iliev 730 pEngineChannel->StatusChanged(true);
114 iliev 1130 fireEngineChanged();
115 schoenebeck 64 dmsg(2,("OK\n"));
116 schoenebeck 53 }
117    
118 schoenebeck 123 void SamplerChannel::SetAudioOutputDevice(AudioOutputDevice* pDevice) {
119 iliev 960 if(pAudioOutputDevice == pDevice) return;
120    
121 schoenebeck 53 // disconnect old device
122 persson 840 if (pAudioOutputDevice && pEngineChannel) {
123     Engine* engine = pEngineChannel->GetEngine();
124     pAudioOutputDevice->Disconnect(engine);
125    
126     pEngineChannel->DisconnectAudioOutputDevice();
127    
128     // reconnect engine if it still exists
129     const std::set<Engine*>& engines = EngineFactory::EngineInstances();
130     if (engines.find(engine) != engines.end()) pAudioOutputDevice->Connect(engine);
131     }
132    
133 schoenebeck 53 // connect new device
134     pAudioOutputDevice = pDevice;
135 schoenebeck 412 if (pEngineChannel) {
136     pEngineChannel->Connect(pAudioOutputDevice);
137     pAudioOutputDevice->Connect(pEngineChannel->GetEngine());
138     }
139 schoenebeck 53 }
140    
141 capela 159 void SamplerChannel::SetMidiInputDevice(MidiInputDevice* pDevice) {
142 schoenebeck 675 SetMidiInput(pDevice, 0, GetMidiInputChannel());
143 capela 159 }
144 schoenebeck 203
145 capela 159 void SamplerChannel::SetMidiInputPort(int MidiPort) {
146 schoenebeck 675 SetMidiInput(GetMidiInputDevice(), MidiPort, GetMidiInputChannel());
147 capela 159 }
148 schoenebeck 203
149 schoenebeck 675 void SamplerChannel::SetMidiInputChannel(midi_chan_t MidiChannel) {
150     SetMidiInput(GetMidiInputDevice(), GetMidiInputPort(), MidiChannel);
151 capela 159 }
152 schoenebeck 203
153 schoenebeck 675 void SamplerChannel::SetMidiInput(MidiInputDevice* pDevice, int iMidiPort, midi_chan_t MidiChannel) {
154 schoenebeck 880 if (!pDevice) throw Exception("No MIDI input device assigned.");
155 schoenebeck 675
156     // get old and new midi input port
157     MidiInputPort* pOldMidiInputPort = __GetMidiInputDevicePort(GetMidiInputPort());
158     MidiInputPort* pNewMidiInputPort = pDevice->GetPort(iMidiPort);
159    
160 capela 159 // disconnect old device port
161 schoenebeck 675 if (pOldMidiInputPort && pEngineChannel) pOldMidiInputPort->Disconnect(pEngineChannel);
162     // remember new device, port and channel if not engine channel yet created
163     if (!pEngineChannel) {
164     this->pMidiInputDevice = pDevice;
165     this->iMidiPort = iMidiPort;
166     this->midiChannel = MidiChannel;
167     }
168    
169 capela 159 // connect new device port
170 schoenebeck 675 if (pNewMidiInputPort && pEngineChannel) pNewMidiInputPort->Connect(pEngineChannel, MidiChannel);
171 capela 159 // Ooops.
172 schoenebeck 675 if (pNewMidiInputPort == NULL)
173 schoenebeck 880 throw Exception("There is no MIDI input port with index " + ToString(iMidiPort) + ".");
174 schoenebeck 53 }
175    
176 schoenebeck 411 EngineChannel* SamplerChannel::GetEngineChannel() {
177     return pEngineChannel;
178 schoenebeck 53 }
179    
180 schoenebeck 675 midi_chan_t SamplerChannel::GetMidiInputChannel() {
181     if (pEngineChannel) this->midiChannel = pEngineChannel->MidiChannel();
182 capela 159 return this->midiChannel;
183 schoenebeck 53 }
184    
185 capela 159 int SamplerChannel::GetMidiInputPort() {
186 schoenebeck 675 MidiInputPort* pMidiInputPort = (pEngineChannel) ? pEngineChannel->GetMidiInputPort() : NULL;
187     if (pMidiInputPort) this->iMidiPort = (int) pMidiInputPort->GetPortNumber();
188     return iMidiPort;
189 capela 159 }
190    
191 schoenebeck 53 AudioOutputDevice* SamplerChannel::GetAudioOutputDevice() {
192     return pAudioOutputDevice;
193     }
194    
195 senkov 155 MidiInputDevice* SamplerChannel::GetMidiInputDevice() {
196 schoenebeck 675 if (pEngineChannel)
197     pMidiInputDevice = (pEngineChannel->GetMidiInputPort()) ? pEngineChannel->GetMidiInputPort()->GetDevice() : NULL;
198 capela 159 return pMidiInputDevice;
199 senkov 155 }
200    
201 schoenebeck 53 uint SamplerChannel::Index() {
202     if (iIndex >= 0) return iIndex;
203    
204 schoenebeck 209 Sampler::SamplerChannelMap::iterator iter = pSampler->mSamplerChannels.begin();
205     for (; iter != pSampler->mSamplerChannels.end(); iter++) {
206     if (iter->second == this) {
207     iIndex = iter->first;
208     return iIndex;
209 schoenebeck 53 }
210     }
211    
212 schoenebeck 880 throw Exception("Internal error: SamplerChannel index not found");
213 schoenebeck 53 }
214    
215 iliev 1130 void SamplerChannel::AddEngineChangeListener(EngineChangeListener* l) {
216     llEngineChangeListeners.AddListener(l);
217     }
218    
219     void SamplerChannel::RemoveEngineChangeListener(EngineChangeListener* l) {
220     llEngineChangeListeners.RemoveListener(l);
221     }
222    
223     void SamplerChannel::RemoveAllEngineChangeListeners() {
224     llEngineChangeListeners.RemoveAllListeners();
225     }
226    
227     void SamplerChannel::fireEngineChanged() {
228     for (int i = 0; i < llEngineChangeListeners.GetListenerCount(); i++) {
229     llEngineChangeListeners.GetListener(i)->EngineChanged(Index());
230     }
231     }
232    
233 schoenebeck 675 MidiInputPort* SamplerChannel::__GetMidiInputDevicePort(int iMidiPort) {
234 schoenebeck 221 MidiInputPort* pMidiInputPort = NULL;
235 schoenebeck 675 MidiInputDevice* pMidiInputDevice = GetMidiInputDevice();
236 capela 159 if (pMidiInputDevice)
237 schoenebeck 221 pMidiInputPort = pMidiInputDevice->GetPort(iMidiPort);
238 capela 159 return pMidiInputPort;
239     }
240 schoenebeck 53
241 schoenebeck 212
242    
243 schoenebeck 53 // ******************************************************************
244     // * Sampler
245    
246     Sampler::Sampler() {
247 iliev 1130 eventHandler.SetSampler(this);
248 schoenebeck 53 }
249    
250     Sampler::~Sampler() {
251 schoenebeck 212 Reset();
252 schoenebeck 53 }
253    
254     uint Sampler::SamplerChannels() {
255 schoenebeck 209 return mSamplerChannels.size();
256 schoenebeck 53 }
257    
258 iliev 1130 void Sampler::AddChannelCountListener(ChannelCountListener* l) {
259     llChannelCountListeners.AddListener(l);
260     }
261    
262     void Sampler::RemoveChannelCountListener(ChannelCountListener* l) {
263     llChannelCountListeners.RemoveListener(l);
264     }
265    
266     void Sampler::fireChannelCountChanged(int NewCount) {
267     for (int i = 0; i < llChannelCountListeners.GetListenerCount(); i++) {
268     llChannelCountListeners.GetListener(i)->ChannelCountChanged(NewCount);
269     }
270     }
271    
272     void Sampler::AddAudioDeviceCountListener(AudioDeviceCountListener* l) {
273     llAudioDeviceCountListeners.AddListener(l);
274     }
275    
276     void Sampler::RemoveAudioDeviceCountListener(AudioDeviceCountListener* l) {
277     llAudioDeviceCountListeners.RemoveListener(l);
278     }
279    
280     void Sampler::fireAudioDeviceCountChanged(int NewCount) {
281     for (int i = 0; i < llAudioDeviceCountListeners.GetListenerCount(); i++) {
282     llAudioDeviceCountListeners.GetListener(i)->AudioDeviceCountChanged(NewCount);
283     }
284     }
285    
286     void Sampler::AddMidiDeviceCountListener(MidiDeviceCountListener* l) {
287     llMidiDeviceCountListeners.AddListener(l);
288     }
289    
290     void Sampler::RemoveMidiDeviceCountListener(MidiDeviceCountListener* l) {
291     llMidiDeviceCountListeners.RemoveListener(l);
292     }
293    
294     void Sampler::fireMidiDeviceCountChanged(int NewCount) {
295     for (int i = 0; i < llMidiDeviceCountListeners.GetListenerCount(); i++) {
296     llMidiDeviceCountListeners.GetListener(i)->MidiDeviceCountChanged(NewCount);
297     }
298     }
299    
300     void Sampler::AddVoiceCountListener(VoiceCountListener* l) {
301     llVoiceCountListeners.AddListener(l);
302     }
303    
304     void Sampler::RemoveVoiceCountListener(VoiceCountListener* l) {
305     llVoiceCountListeners.RemoveListener(l);
306     }
307    
308     void Sampler::fireVoiceCountChanged(int ChannelId, int NewCount) {
309     for (int i = 0; i < llVoiceCountListeners.GetListenerCount(); i++) {
310     llVoiceCountListeners.GetListener(i)->VoiceCountChanged(ChannelId, NewCount);
311     }
312     }
313    
314     void Sampler::AddStreamCountListener(StreamCountListener* l) {
315     llStreamCountListeners.AddListener(l);
316     }
317    
318     void Sampler::RemoveStreamCountListener(StreamCountListener* l) {
319     llStreamCountListeners.RemoveListener(l);
320     }
321    
322     void Sampler::fireStreamCountChanged(int ChannelId, int NewCount) {
323     for (int i = 0; i < llStreamCountListeners.GetListenerCount(); i++) {
324     llStreamCountListeners.GetListener(i)->StreamCountChanged(ChannelId, NewCount);
325     }
326     }
327    
328     void Sampler::AddBufferFillListener(BufferFillListener* l) {
329     llBufferFillListeners.AddListener(l);
330     }
331    
332     void Sampler::RemoveBufferFillListener(BufferFillListener* l) {
333     llBufferFillListeners.RemoveListener(l);
334     }
335    
336     void Sampler::fireBufferFillChanged(int ChannelId, String FillData) {
337     for (int i = 0; i < llBufferFillListeners.GetListenerCount(); i++) {
338     llBufferFillListeners.GetListener(i)->BufferFillChanged(ChannelId, FillData);
339     }
340     }
341    
342     void Sampler::AddTotalVoiceCountListener(TotalVoiceCountListener* l) {
343     llTotalVoiceCountListeners.AddListener(l);
344     }
345    
346     void Sampler::RemoveTotalVoiceCountListener(TotalVoiceCountListener* l) {
347     llTotalVoiceCountListeners.RemoveListener(l);
348     }
349    
350     void Sampler::fireTotalVoiceCountChanged(int NewCount) {
351     for (int i = 0; i < llTotalVoiceCountListeners.GetListenerCount(); i++) {
352     llTotalVoiceCountListeners.GetListener(i)->TotalVoiceCountChanged(NewCount);
353     }
354     }
355    
356     void Sampler::AddFxSendCountListener(FxSendCountListener* l) {
357     llFxSendCountListeners.AddListener(l);
358     }
359    
360     void Sampler::RemoveFxSendCountListener(FxSendCountListener* l) {
361     llFxSendCountListeners.RemoveListener(l);
362     }
363    
364     void Sampler::fireFxSendCountChanged(int ChannelId, int NewCount) {
365     for (int i = 0; i < llFxSendCountListeners.GetListenerCount(); i++) {
366     llFxSendCountListeners.GetListener(i)->FxSendCountChanged(ChannelId, NewCount);
367     }
368     }
369    
370     void Sampler::EventHandler::EngineChanged(int ChannelId) {
371     EngineChannel* engineChannel = pSampler->GetSamplerChannel(ChannelId)->GetEngineChannel();
372     if(engineChannel == NULL) return;
373     engineChannel->AddFxSendCountListener(this);
374     }
375    
376     void Sampler::EventHandler::FxSendCountChanged(int ChannelId, int NewCount) {
377     pSampler->fireFxSendCountChanged(ChannelId, NewCount);
378     }
379    
380    
381 schoenebeck 53 SamplerChannel* Sampler::AddSamplerChannel() {
382 schoenebeck 209 // if there's no sampler channel yet
383     if (!mSamplerChannels.size()) {
384     SamplerChannel* pChannel = new SamplerChannel(this);
385     mSamplerChannels[0] = pChannel;
386 iliev 1130 fireChannelCountChanged(1);
387     pChannel->AddEngineChangeListener(&eventHandler);
388 schoenebeck 209 return pChannel;
389     }
390    
391     // get the highest used sampler channel index
392     uint lastIndex = (--(mSamplerChannels.end()))->first;
393    
394     // check if we reached the index limit
395     if (lastIndex + 1 < lastIndex) {
396     // search for an unoccupied sampler channel index starting from 0
397     for (uint i = 0; i < lastIndex; i++) {
398     if (mSamplerChannels.find(i) != mSamplerChannels.end()) continue;
399     // we found an unused index, so insert the new channel there
400     SamplerChannel* pChannel = new SamplerChannel(this);
401     mSamplerChannels[i] = pChannel;
402 iliev 1130 fireChannelCountChanged(SamplerChannels());
403     pChannel->AddEngineChangeListener(&eventHandler);
404 schoenebeck 209 return pChannel;
405     }
406 schoenebeck 880 throw Exception("Internal error: could not find unoccupied sampler channel index.");
407 schoenebeck 209 }
408    
409     // we have not reached the index limit so we just add the channel past the highest index
410 schoenebeck 53 SamplerChannel* pChannel = new SamplerChannel(this);
411 schoenebeck 209 mSamplerChannels[lastIndex + 1] = pChannel;
412 iliev 1130 fireChannelCountChanged(SamplerChannels());
413     pChannel->AddEngineChangeListener(&eventHandler);
414 schoenebeck 53 return pChannel;
415     }
416    
417     SamplerChannel* Sampler::GetSamplerChannel(uint uiSamplerChannel) {
418 schoenebeck 209 return (mSamplerChannels.find(uiSamplerChannel) != mSamplerChannels.end()) ? mSamplerChannels[uiSamplerChannel] : NULL;
419 schoenebeck 53 }
420    
421 schoenebeck 209 std::map<uint, SamplerChannel*> Sampler::GetSamplerChannels() {
422     return mSamplerChannels;
423     }
424    
425 schoenebeck 53 void Sampler::RemoveSamplerChannel(SamplerChannel* pSamplerChannel) {
426 schoenebeck 209 SamplerChannelMap::iterator iterChan = mSamplerChannels.begin();
427     for (; iterChan != mSamplerChannels.end(); iterChan++) {
428     if (iterChan->second == pSamplerChannel) {
429 iliev 1130 pSamplerChannel->RemoveAllEngineChangeListeners();
430 schoenebeck 209 mSamplerChannels.erase(iterChan);
431 schoenebeck 53 delete pSamplerChannel;
432 iliev 1130 fireChannelCountChanged(SamplerChannels());
433 schoenebeck 53 return;
434     }
435     }
436     }
437    
438     void Sampler::RemoveSamplerChannel(uint uiSamplerChannel) {
439     SamplerChannel* pChannel = GetSamplerChannel(uiSamplerChannel);
440     if (!pChannel) return;
441     RemoveSamplerChannel(pChannel);
442     }
443    
444 schoenebeck 123 std::vector<String> Sampler::AvailableAudioOutputDrivers() {
445     return AudioOutputDeviceFactory::AvailableDrivers();
446     }
447 schoenebeck 53
448 schoenebeck 900 std::vector<String> Sampler::AvailableMidiInputDrivers() {
449     return MidiInputDeviceFactory::AvailableDrivers();
450     }
451    
452     std::vector<String> Sampler::AvailableEngineTypes() {
453     return EngineFactory::AvailableEngineTypes();
454     }
455    
456 schoenebeck 880 AudioOutputDevice* Sampler::CreateAudioOutputDevice(String AudioDriver, std::map<String,String> Parameters) throw (Exception) {
457 schoenebeck 53 // create new device
458 schoenebeck 123 AudioOutputDevice* pDevice = AudioOutputDeviceFactory::Create(AudioDriver, Parameters);
459 schoenebeck 53
460 schoenebeck 64 // add new audio device to the audio device list
461 schoenebeck 123 for (uint i = 0; ; i++) { // seek for a free place starting from the beginning
462     if (!mAudioOutputDevices[i]) {
463     mAudioOutputDevices[i] = pDevice;
464     break;
465     }
466     }
467 schoenebeck 64
468 iliev 1130 fireAudioDeviceCountChanged(AudioOutputDevices());
469 schoenebeck 53 return pDevice;
470     }
471    
472 schoenebeck 123 uint Sampler::AudioOutputDevices() {
473     return mAudioOutputDevices.size();
474 schoenebeck 53 }
475    
476 senkov 155 uint Sampler::MidiInputDevices() {
477     return mMidiInputDevices.size();
478     }
479    
480 schoenebeck 123 std::map<uint, AudioOutputDevice*> Sampler::GetAudioOutputDevices() {
481     return mAudioOutputDevices;
482     }
483    
484 senkov 155 std::map<uint, MidiInputDevice*> Sampler::GetMidiInputDevices() {
485     return mMidiInputDevices;
486     }
487    
488 schoenebeck 880 void Sampler::DestroyAudioOutputDevice(AudioOutputDevice* pDevice) throw (Exception) {
489 schoenebeck 123 AudioOutputDeviceMap::iterator iter = mAudioOutputDevices.begin();
490     for (; iter != mAudioOutputDevices.end(); iter++) {
491     if (iter->second == pDevice) {
492     // check if there are still sampler engines connected to this device
493     for (uint i = 0; i < SamplerChannels(); i++)
494 schoenebeck 880 if (GetSamplerChannel(i)->GetAudioOutputDevice() == pDevice) throw Exception("Sampler channel " + ToString(i) + " is still connected to the audio output device.");
495 schoenebeck 123
496     // disable device
497     pDevice->Stop();
498    
499 persson 837 // remove device from the device list
500     mAudioOutputDevices.erase(iter);
501    
502 schoenebeck 123 // destroy and free device from memory
503     delete pDevice;
504 persson 837
505 iliev 1130 fireAudioDeviceCountChanged(AudioOutputDevices());
506 persson 837 break;
507 schoenebeck 123 }
508     }
509     }
510    
511 schoenebeck 880 void Sampler::DestroyMidiInputDevice(MidiInputDevice* pDevice) throw (Exception) {
512 senkov 155 MidiInputDeviceMap::iterator iter = mMidiInputDevices.begin();
513     for (; iter != mMidiInputDevices.end(); iter++) {
514     if (iter->second == pDevice) {
515     // check if there are still sampler engines connected to this device
516     for (uint i = 0; i < SamplerChannels(); i++)
517 schoenebeck 880 if (GetSamplerChannel(i)->GetMidiInputDevice() == pDevice) throw Exception("Sampler channel " + ToString(i) + " is still connected to the midi input device.");
518 schoenebeck 53
519 senkov 155 // disable device
520     pDevice->StopListen();
521    
522 persson 837 // remove device from the device list
523     mMidiInputDevices.erase(iter);
524    
525 senkov 155 // destroy and free device from memory
526     delete pDevice;
527 persson 837
528 iliev 1130 fireMidiDeviceCountChanged(MidiInputDevices());
529 persson 837 break;
530 senkov 155 }
531 schoenebeck 53 }
532 senkov 155 }
533 schoenebeck 53
534 schoenebeck 880 MidiInputDevice* Sampler::CreateMidiInputDevice(String MidiDriver, std::map<String,String> Parameters) throw (Exception) {
535 senkov 155 // create new device
536 schoenebeck 551 MidiInputDevice* pDevice = MidiInputDeviceFactory::Create(MidiDriver, Parameters, this);
537 senkov 155
538     // add new device to the midi device list
539     for (uint i = 0; ; i++) { // seek for a free place starting from the beginning
540     if (!mMidiInputDevices[i]) {
541     mMidiInputDevices[i] = pDevice;
542     break;
543     }
544     }
545 schoenebeck 64
546 iliev 1130 fireMidiDeviceCountChanged(MidiInputDevices());
547 schoenebeck 53 return pDevice;
548     }
549    
550 iliev 778 int Sampler::GetVoiceCount() {
551     int count = 0;
552     std::set<Engine*>::iterator it = EngineFactory::EngineInstances().begin();
553    
554     for(; it != EngineFactory::EngineInstances().end(); it++) {
555     count += (*it)->VoiceCount();
556     }
557    
558     return count;
559     }
560    
561 schoenebeck 212 void Sampler::Reset() {
562     // delete sampler channels
563     try {
564 senkov 329 while (true) {
565     SamplerChannelMap::iterator iter = mSamplerChannels.begin();
566     if (iter == mSamplerChannels.end()) break;
567     RemoveSamplerChannel(iter->second);
568 schoenebeck 212 }
569     }
570     catch(...) {
571     std::cerr << "Sampler::Reset(): Exception occured while trying to delete all sampler channels, exiting.\n" << std::flush;
572     exit(EXIT_FAILURE);
573     }
574    
575     // delete midi input devices
576     try {
577 senkov 329 while (true) {
578     MidiInputDeviceMap::iterator iter = mMidiInputDevices.begin();
579     if (iter == mMidiInputDevices.end()) break;
580     DestroyMidiInputDevice(iter->second);
581 schoenebeck 212 }
582     }
583     catch(...) {
584     std::cerr << "Sampler::Reset(): Exception occured while trying to delete all MIDI input devices, exiting.\n" << std::flush;
585     exit(EXIT_FAILURE);
586     }
587    
588     // delete audio output devices
589     try {
590 senkov 329 while (true) {
591     AudioOutputDeviceMap::iterator iter = mAudioOutputDevices.begin();
592     if (iter == mAudioOutputDevices.end()) break;
593     DestroyAudioOutputDevice(iter->second);
594 schoenebeck 212 }
595     }
596     catch(...) {
597     std::cerr << "Sampler::Reset(): Exception occured while trying to delete all audio output devices, exiting.\n" << std::flush;
598     exit(EXIT_FAILURE);
599     }
600 schoenebeck 1008
601     // delete MIDI instrument maps
602     try {
603     MidiInstrumentMapper::RemoveAllMaps();
604     }
605     catch(...) {
606     std::cerr << "Sampler::Reset(): Exception occured while trying to delete all MIDI instrument maps, exiting.\n" << std::flush;
607     exit(EXIT_FAILURE);
608     }
609 schoenebeck 1212
610     // unload all instrument editor DLLs
611     InstrumentEditorFactory::ClosePlugins();
612 schoenebeck 212 }
613    
614 schoenebeck 53 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC