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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1934 - (hide annotations) (download)
Sun Jul 12 10:35:55 2009 UTC (14 years, 9 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 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 61 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 persson 1897 * Copyright (C) 2005 - 2009 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 schoenebeck 1424 #include "common/global_private.h"
29 iliev 778 #include "engines/EngineFactory.h"
30 schoenebeck 411 #include "engines/EngineChannelFactory.h"
31 schoenebeck 1375 #include "plugins/InstrumentEditorFactory.h"
32 schoenebeck 203 #include "drivers/audio/AudioOutputDeviceFactory.h"
33     #include "drivers/midi/MidiInputDeviceFactory.h"
34 schoenebeck 1008 #include "drivers/midi/MidiInstrumentMapper.h"
35 schoenebeck 1723 #include "common/Features.h"
36 persson 1765 #include "network/lscpserver.h"
37 schoenebeck 53
38     namespace LinuxSampler {
39    
40     // ******************************************************************
41     // * SamplerChannel
42    
43     SamplerChannel::SamplerChannel(Sampler* pS) {
44     pSampler = pS;
45 schoenebeck 411 pEngineChannel = NULL;
46 schoenebeck 675 pAudioOutputDevice = NULL;
47 capela 159 pMidiInputDevice = NULL;
48 schoenebeck 675 iMidiPort = 0;
49     midiChannel = midi_chan_all;
50 schoenebeck 53 iIndex = -1;
51     }
52    
53     SamplerChannel::~SamplerChannel() {
54 schoenebeck 411 if (pEngineChannel) {
55 persson 840 Engine* engine = pEngineChannel->GetEngine();
56     if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(engine);
57    
58 schoenebeck 675 MidiInputPort* pMidiInputPort = (pEngineChannel) ? pEngineChannel->GetMidiInputPort() : __GetMidiInputDevicePort(GetMidiInputChannel());
59 schoenebeck 411 if (pMidiInputPort) pMidiInputPort->Disconnect(pEngineChannel);
60 schoenebeck 420 if (pEngineChannel) {
61     if (pAudioOutputDevice) pEngineChannel->DisconnectAudioOutputDevice();
62 schoenebeck 660 EngineChannelFactory::Destroy(pEngineChannel);
63 persson 840
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 schoenebeck 420 }
68 schoenebeck 53 }
69     }
70    
71 schoenebeck 880 void SamplerChannel::SetEngineType(String EngineType) throw (Exception) {
72 schoenebeck 411 dmsg(2,("SamplerChannel: Assigning engine type..."));
73 schoenebeck 1934
74 iliev 1283 if (pEngineChannel) {
75     if (!strcasecmp(pEngineChannel->EngineName().c_str(), EngineType.c_str())) {
76     dmsg(2,("OK\n"));
77     return;
78     }
79     }
80 schoenebeck 53
81 schoenebeck 1686 fireEngineToBeChanged();
82    
83 schoenebeck 411 // create new engine channel
84     EngineChannel* pNewEngineChannel = EngineChannelFactory::Create(EngineType);
85 schoenebeck 880 if (!pNewEngineChannel) throw Exception("Unknown engine type");
86 schoenebeck 53
87 iliev 1761 pNewEngineChannel->SetSamplerChannel(this);
88 schoenebeck 660
89 capela 159 // dereference midi input port.
90 schoenebeck 675 MidiInputPort* pMidiInputPort = __GetMidiInputDevicePort(GetMidiInputPort());
91     // disconnect old engine channel
92 schoenebeck 411 if (pEngineChannel) {
93 persson 840 Engine* engine = pEngineChannel->GetEngine();
94     if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(engine);
95    
96 schoenebeck 411 if (pMidiInputPort) pMidiInputPort->Disconnect(pEngineChannel);
97 schoenebeck 412 if (pAudioOutputDevice) pEngineChannel->DisconnectAudioOutputDevice();
98 schoenebeck 660 EngineChannelFactory::Destroy(pEngineChannel);
99 persson 840
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 schoenebeck 53 }
104    
105 schoenebeck 411 // connect new engine channel
106 schoenebeck 412 if (pAudioOutputDevice) {
107     pNewEngineChannel->Connect(pAudioOutputDevice);
108     pAudioOutputDevice->Connect(pNewEngineChannel->GetEngine());
109     }
110 persson 846 if (pMidiInputPort) pMidiInputPort->Connect(pNewEngineChannel, GetMidiInputChannel());
111 schoenebeck 675 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 iliev 730 pEngineChannel->StatusChanged(true);
118 iliev 1130 fireEngineChanged();
119 schoenebeck 64 dmsg(2,("OK\n"));
120 schoenebeck 53 }
121    
122 schoenebeck 123 void SamplerChannel::SetAudioOutputDevice(AudioOutputDevice* pDevice) {
123 iliev 960 if(pAudioOutputDevice == pDevice) return;
124    
125 schoenebeck 53 // disconnect old device
126 persson 840 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 schoenebeck 53 // connect new device
138     pAudioOutputDevice = pDevice;
139 schoenebeck 412 if (pEngineChannel) {
140     pEngineChannel->Connect(pAudioOutputDevice);
141     pAudioOutputDevice->Connect(pEngineChannel->GetEngine());
142     }
143 schoenebeck 53 }
144    
145 capela 159 void SamplerChannel::SetMidiInputDevice(MidiInputDevice* pDevice) {
146 schoenebeck 675 SetMidiInput(pDevice, 0, GetMidiInputChannel());
147 capela 159 }
148 schoenebeck 203
149 capela 159 void SamplerChannel::SetMidiInputPort(int MidiPort) {
150 schoenebeck 675 SetMidiInput(GetMidiInputDevice(), MidiPort, GetMidiInputChannel());
151 capela 159 }
152 schoenebeck 203
153 schoenebeck 675 void SamplerChannel::SetMidiInputChannel(midi_chan_t MidiChannel) {
154     SetMidiInput(GetMidiInputDevice(), GetMidiInputPort(), MidiChannel);
155 capela 159 }
156 schoenebeck 203
157 schoenebeck 675 void SamplerChannel::SetMidiInput(MidiInputDevice* pDevice, int iMidiPort, midi_chan_t MidiChannel) {
158 schoenebeck 880 if (!pDevice) throw Exception("No MIDI input device assigned.");
159 schoenebeck 675
160     // get old and new midi input port
161     MidiInputPort* pOldMidiInputPort = __GetMidiInputDevicePort(GetMidiInputPort());
162     MidiInputPort* pNewMidiInputPort = pDevice->GetPort(iMidiPort);
163    
164 capela 159 // disconnect old device port
165 schoenebeck 675 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 capela 159 // connect new device port
174 schoenebeck 675 if (pNewMidiInputPort && pEngineChannel) pNewMidiInputPort->Connect(pEngineChannel, MidiChannel);
175 capela 159 // Ooops.
176 schoenebeck 675 if (pNewMidiInputPort == NULL)
177 schoenebeck 880 throw Exception("There is no MIDI input port with index " + ToString(iMidiPort) + ".");
178 schoenebeck 53 }
179    
180 schoenebeck 411 EngineChannel* SamplerChannel::GetEngineChannel() {
181     return pEngineChannel;
182 schoenebeck 53 }
183    
184 schoenebeck 675 midi_chan_t SamplerChannel::GetMidiInputChannel() {
185     if (pEngineChannel) this->midiChannel = pEngineChannel->MidiChannel();
186 capela 159 return this->midiChannel;
187 schoenebeck 53 }
188    
189 capela 159 int SamplerChannel::GetMidiInputPort() {
190 schoenebeck 675 MidiInputPort* pMidiInputPort = (pEngineChannel) ? pEngineChannel->GetMidiInputPort() : NULL;
191     if (pMidiInputPort) this->iMidiPort = (int) pMidiInputPort->GetPortNumber();
192     return iMidiPort;
193 capela 159 }
194    
195 schoenebeck 53 AudioOutputDevice* SamplerChannel::GetAudioOutputDevice() {
196     return pAudioOutputDevice;
197     }
198    
199 senkov 155 MidiInputDevice* SamplerChannel::GetMidiInputDevice() {
200 schoenebeck 675 if (pEngineChannel)
201     pMidiInputDevice = (pEngineChannel->GetMidiInputPort()) ? pEngineChannel->GetMidiInputPort()->GetDevice() : NULL;
202 capela 159 return pMidiInputDevice;
203 senkov 155 }
204    
205 schoenebeck 53 uint SamplerChannel::Index() {
206     if (iIndex >= 0) return iIndex;
207    
208 schoenebeck 209 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 schoenebeck 53 }
214     }
215    
216 schoenebeck 880 throw Exception("Internal error: SamplerChannel index not found");
217 schoenebeck 53 }
218    
219 iliev 1761 Sampler* SamplerChannel::GetSampler() {
220     return pSampler;
221     }
222    
223 iliev 1130 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 schoenebeck 1686 void SamplerChannel::fireEngineToBeChanged() {
236     for (int i = 0; i < llEngineChangeListeners.GetListenerCount(); i++) {
237     llEngineChangeListeners.GetListener(i)->EngineToBeChanged(Index());
238     }
239     }
240    
241 iliev 1130 void SamplerChannel::fireEngineChanged() {
242     for (int i = 0; i < llEngineChangeListeners.GetListenerCount(); i++) {
243     llEngineChangeListeners.GetListener(i)->EngineChanged(Index());
244     }
245     }
246    
247 schoenebeck 675 MidiInputPort* SamplerChannel::__GetMidiInputDevicePort(int iMidiPort) {
248 schoenebeck 221 MidiInputPort* pMidiInputPort = NULL;
249 schoenebeck 675 MidiInputDevice* pMidiInputDevice = GetMidiInputDevice();
250 capela 159 if (pMidiInputDevice)
251 schoenebeck 221 pMidiInputPort = pMidiInputDevice->GetPort(iMidiPort);
252 capela 159 return pMidiInputPort;
253     }
254 schoenebeck 53
255 schoenebeck 212
256    
257 schoenebeck 53 // ******************************************************************
258     // * Sampler
259    
260     Sampler::Sampler() {
261 iliev 1130 eventHandler.SetSampler(this);
262 iliev 1789 uiOldTotalVoiceCount = uiOldTotalStreamCount = 0;
263 schoenebeck 53 }
264    
265     Sampler::~Sampler() {
266 schoenebeck 212 Reset();
267 schoenebeck 53 }
268    
269     uint Sampler::SamplerChannels() {
270 schoenebeck 209 return mSamplerChannels.size();
271 schoenebeck 53 }
272    
273 iliev 1130 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 schoenebeck 1686 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 iliev 1130 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 schoenebeck 1695 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 iliev 1130 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 iliev 1789 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 iliev 1130 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 iliev 1789 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 iliev 1130 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 iliev 1541 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 iliev 1789 if (NewCount == uiOldTotalStreamCount) return;
407     uiOldTotalStreamCount = NewCount;
408    
409 iliev 1541 for (int i = 0; i < llTotalStreamCountListeners.GetListenerCount(); i++) {
410     llTotalStreamCountListeners.GetListener(i)->TotalStreamCountChanged(NewCount);
411     }
412     }
413    
414 iliev 1130 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 iliev 1789 if (NewCount == uiOldTotalVoiceCount) return;
424     uiOldTotalVoiceCount = NewCount;
425    
426 iliev 1130 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 schoenebeck 1686 void Sampler::EventHandler::EngineToBeChanged(int ChannelId) {
446     // nothing to do here
447     }
448    
449 iliev 1130 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 schoenebeck 53 SamplerChannel* Sampler::AddSamplerChannel() {
461 schoenebeck 209 // if there's no sampler channel yet
462     if (!mSamplerChannels.size()) {
463     SamplerChannel* pChannel = new SamplerChannel(this);
464     mSamplerChannels[0] = pChannel;
465 schoenebeck 1686 fireChannelAdded(pChannel);
466 iliev 1130 fireChannelCountChanged(1);
467     pChannel->AddEngineChangeListener(&eventHandler);
468 schoenebeck 209 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 schoenebeck 1686 fireChannelAdded(pChannel);
483 iliev 1130 fireChannelCountChanged(SamplerChannels());
484     pChannel->AddEngineChangeListener(&eventHandler);
485 schoenebeck 209 return pChannel;
486     }
487 schoenebeck 880 throw Exception("Internal error: could not find unoccupied sampler channel index.");
488 schoenebeck 209 }
489    
490     // we have not reached the index limit so we just add the channel past the highest index
491 schoenebeck 53 SamplerChannel* pChannel = new SamplerChannel(this);
492 schoenebeck 209 mSamplerChannels[lastIndex + 1] = pChannel;
493 schoenebeck 1686 fireChannelAdded(pChannel);
494 iliev 1130 fireChannelCountChanged(SamplerChannels());
495     pChannel->AddEngineChangeListener(&eventHandler);
496 schoenebeck 53 return pChannel;
497     }
498    
499     SamplerChannel* Sampler::GetSamplerChannel(uint uiSamplerChannel) {
500 schoenebeck 209 return (mSamplerChannels.find(uiSamplerChannel) != mSamplerChannels.end()) ? mSamplerChannels[uiSamplerChannel] : NULL;
501 schoenebeck 53 }
502    
503 schoenebeck 209 std::map<uint, SamplerChannel*> Sampler::GetSamplerChannels() {
504     return mSamplerChannels;
505     }
506    
507 schoenebeck 53 void Sampler::RemoveSamplerChannel(SamplerChannel* pSamplerChannel) {
508 schoenebeck 209 SamplerChannelMap::iterator iterChan = mSamplerChannels.begin();
509     for (; iterChan != mSamplerChannels.end(); iterChan++) {
510     if (iterChan->second == pSamplerChannel) {
511 schoenebeck 1686 fireChannelToBeRemoved(pSamplerChannel);
512 iliev 1789 mOldVoiceCounts.erase(pSamplerChannel->Index());
513     mOldStreamCounts.erase(pSamplerChannel->Index());
514 iliev 1130 pSamplerChannel->RemoveAllEngineChangeListeners();
515 schoenebeck 209 mSamplerChannels.erase(iterChan);
516 schoenebeck 53 delete pSamplerChannel;
517 iliev 1130 fireChannelCountChanged(SamplerChannels());
518 schoenebeck 53 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 iliev 1835 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 schoenebeck 123 std::vector<String> Sampler::AvailableAudioOutputDrivers() {
543     return AudioOutputDeviceFactory::AvailableDrivers();
544     }
545 schoenebeck 53
546 schoenebeck 900 std::vector<String> Sampler::AvailableMidiInputDrivers() {
547     return MidiInputDeviceFactory::AvailableDrivers();
548     }
549    
550     std::vector<String> Sampler::AvailableEngineTypes() {
551     return EngineFactory::AvailableEngineTypes();
552     }
553    
554 schoenebeck 880 AudioOutputDevice* Sampler::CreateAudioOutputDevice(String AudioDriver, std::map<String,String> Parameters) throw (Exception) {
555 schoenebeck 53 // create new device
556 schoenebeck 123 AudioOutputDevice* pDevice = AudioOutputDeviceFactory::Create(AudioDriver, Parameters);
557 schoenebeck 53
558 iliev 1130 fireAudioDeviceCountChanged(AudioOutputDevices());
559 schoenebeck 53 return pDevice;
560     }
561    
562 schoenebeck 123 uint Sampler::AudioOutputDevices() {
563 schoenebeck 1934 return AudioOutputDeviceFactory::Devices().size();
564 schoenebeck 53 }
565    
566 senkov 155 uint Sampler::MidiInputDevices() {
567 schoenebeck 1934 return MidiInputDeviceFactory::Devices().size();
568 senkov 155 }
569    
570 schoenebeck 123 std::map<uint, AudioOutputDevice*> Sampler::GetAudioOutputDevices() {
571 schoenebeck 1934 return AudioOutputDeviceFactory::Devices();
572 schoenebeck 123 }
573    
574 senkov 155 std::map<uint, MidiInputDevice*> Sampler::GetMidiInputDevices() {
575 schoenebeck 1934 return MidiInputDeviceFactory::Devices();
576 senkov 155 }
577    
578 schoenebeck 880 void Sampler::DestroyAudioOutputDevice(AudioOutputDevice* pDevice) throw (Exception) {
579 schoenebeck 1934 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 schoenebeck 123
585 schoenebeck 1934 //TODO: should we add fireAudioDeviceToBeDestroyed() here ?
586     AudioOutputDeviceFactory::Destroy(pDevice);
587     fireAudioDeviceCountChanged(AudioOutputDevices());
588 schoenebeck 123 }
589     }
590    
591 iliev 1835 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 schoenebeck 1934 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 iliev 1835 }
607     }
608    
609 schoenebeck 880 void Sampler::DestroyMidiInputDevice(MidiInputDevice* pDevice) throw (Exception) {
610 schoenebeck 1934 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 schoenebeck 53
616 schoenebeck 1934 fireMidiDeviceToBeDestroyed(pDevice);
617     MidiInputDeviceFactory::Destroy(pDevice);
618     fireMidiDeviceCountChanged(MidiInputDevices());
619 schoenebeck 53 }
620 senkov 155 }
621 schoenebeck 53
622 iliev 1835 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 schoenebeck 1934 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 iliev 1835 }
638     }
639    
640 schoenebeck 880 MidiInputDevice* Sampler::CreateMidiInputDevice(String MidiDriver, std::map<String,String> Parameters) throw (Exception) {
641 senkov 155 // create new device
642 schoenebeck 551 MidiInputDevice* pDevice = MidiInputDeviceFactory::Create(MidiDriver, Parameters, this);
643 senkov 155
644 schoenebeck 1695 fireMidiDeviceCreated(pDevice);
645 iliev 1130 fireMidiDeviceCountChanged(MidiInputDevices());
646 schoenebeck 53 return pDevice;
647     }
648    
649 iliev 1541 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 iliev 778 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 schoenebeck 212 void Sampler::Reset() {
672     // delete sampler channels
673     try {
674 schoenebeck 1934 RemoveAllSamplerChannels();
675 schoenebeck 212 }
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 schoenebeck 1934 DestroyAllMidiInputDevices();
684 schoenebeck 212 }
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 schoenebeck 1934 DestroyAllAudioOutputDevices();
693 schoenebeck 212 }
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 schoenebeck 1008
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 schoenebeck 1212
708     // unload all instrument editor DLLs
709     InstrumentEditorFactory::ClosePlugins();
710 schoenebeck 212 }
711    
712 schoenebeck 1723 bool Sampler::EnableDenormalsAreZeroMode() {
713     Features::detect();
714     return Features::enableDenormalsAreZeroMode();
715     }
716    
717 persson 1765 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 schoenebeck 1934
740 iliev 1789 fireTotalStreamCountChanged(GetDiskStreamCount());
741     fireTotalVoiceCountChanged(GetVoiceCount());
742    
743 persson 1765 LSCPServer::UnlockRTNotify();
744     }
745     }
746    
747 persson 1897 #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 schoenebeck 53 } // namespace LinuxSampler
763 persson 1897
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