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

Diff of /linuxsampler/trunk/src/drivers/audio/AudioOutputDevice.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 554 by schoenebeck, Thu May 19 19:25:14 2005 UTC revision 2137 by schoenebeck, Mon Oct 4 12:20:23 2010 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 Christian Schoenebeck                              *   *   Copyright (C) 2005 - 2010 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 23  Line 23 
23    
24  #include "AudioOutputDeviceFactory.h"  #include "AudioOutputDeviceFactory.h"
25  #include "AudioOutputDevice.h"  #include "AudioOutputDevice.h"
26    #include "../../common/global_private.h"
27    #include "../../common/IDGenerator.h"
28    
29  namespace LinuxSampler {  namespace LinuxSampler {
30    
# Line 56  namespace LinuxSampler { Line 58  namespace LinuxSampler {
58          return true;          return true;
59      }      }
60    
61      void AudioOutputDevice::ParameterActive::OnSetValue(bool b) throw (LinuxSamplerException) {      void AudioOutputDevice::ParameterActive::OnSetValue(bool b) throw (Exception) {
62          if (b) ((AudioOutputDevice*)pDevice)->Play();          if (b) ((AudioOutputDevice*)pDevice)->Play();
63          else ((AudioOutputDevice*)pDevice)->Stop();          else ((AudioOutputDevice*)pDevice)->Stop();
64      }      }
# Line 109  namespace LinuxSampler { Line 111  namespace LinuxSampler {
111          return std::vector<int>();          return std::vector<int>();
112      }      }
113    
114      void AudioOutputDevice::ParameterSampleRate::OnSetValue(int i) throw (LinuxSamplerException) {      int AudioOutputDevice::ParameterSampleRate::ValueAsInt() {
115            return (pDevice) ? (int) ((AudioOutputDevice*)pDevice)->SampleRate()
116                             : DeviceCreationParameterInt::ValueAsInt();
117        }
118    
119        void AudioOutputDevice::ParameterSampleRate::OnSetValue(int i) throw (Exception) {
120          /* cannot happen, as parameter is fix */          /* cannot happen, as parameter is fix */
121      }      }
122    
# Line 150  namespace LinuxSampler { Line 157  namespace LinuxSampler {
157      }      }
158    
159      optional<int> AudioOutputDevice::ParameterChannels::RangeMinAsInt(std::map<String,String> Parameters) {      optional<int> AudioOutputDevice::ParameterChannels::RangeMinAsInt(std::map<String,String> Parameters) {
160          return optional<int>::nothing;          return 1;
161      }      }
162    
163      optional<int> AudioOutputDevice::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) {      optional<int> AudioOutputDevice::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) {
# Line 161  namespace LinuxSampler { Line 168  namespace LinuxSampler {
168          return std::vector<int>();          return std::vector<int>();
169      }      }
170    
171      void AudioOutputDevice::ParameterChannels::OnSetValue(int i) throw (LinuxSamplerException) {      void AudioOutputDevice::ParameterChannels::OnSetValue(int i) throw (Exception) {
172          ((AudioOutputDevice*)pDevice)->AcquireChannels(i);          ((AudioOutputDevice*)pDevice)->AcquireChannels(i);
173      }      }
174    
# Line 174  namespace LinuxSampler { Line 181  namespace LinuxSampler {
181  // *************** AudioOutputDevice ***************  // *************** AudioOutputDevice ***************
182  // *  // *
183    
184      AudioOutputDevice::AudioOutputDevice(std::map<String,DeviceCreationParameter*> DriverParameters) {      AudioOutputDevice::AudioOutputDevice(std::map<String,DeviceCreationParameter*> DriverParameters)
185            : EnginesReader(Engines) {
186          this->Parameters = DriverParameters;          this->Parameters = DriverParameters;
187            EffectChainIDs = new IDGenerator();
188      }      }
189    
190      AudioOutputDevice::~AudioOutputDevice() {      AudioOutputDevice::~AudioOutputDevice() {
# Line 183  namespace LinuxSampler { Line 192  namespace LinuxSampler {
192          {          {
193              std::vector<AudioChannel*>::iterator iter = Channels.begin();              std::vector<AudioChannel*>::iterator iter = Channels.begin();
194              while (iter != Channels.end()) {              while (iter != Channels.end()) {
                 Channels.erase(iter);  
195                  delete *iter;                  delete *iter;
196                  iter++;                  iter++;
197              }              }
198                Channels.clear();
199          }          }
200    
201          // delete all device parameters          // delete all device parameters
202          {          {
203              std::map<String,DeviceCreationParameter*>::iterator iter = Parameters.begin();              std::map<String,DeviceCreationParameter*>::iterator iter = Parameters.begin();
204              while (iter != Parameters.end()) {              while (iter != Parameters.end()) {
                 Parameters.erase(iter);  
205                  delete iter->second;                  delete iter->second;
206                  iter++;                  iter++;
207              }              }
208                Parameters.clear();
209          }          }
210    
211            // delete all master effect chains
212            {
213                std::vector<EffectChain*>::iterator iter = vEffectChains.begin();
214                while (iter != vEffectChains.end()) {
215                    delete *iter;
216                    iter++;
217                }
218                vEffectChains.clear();
219            }
220            
221            delete EffectChainIDs;
222      }      }
223    
224      void AudioOutputDevice::Connect(Engine* pEngine) {      void AudioOutputDevice::Connect(Engine* pEngine) {
225          if (Engines.find(pEngine) == Engines.end()) {          std::set<Engine*>& engines = Engines.GetConfigForUpdate();
226              Engines.insert(pEngine);          if (engines.find(pEngine) == engines.end()) {
227                engines.insert(pEngine);
228                Engines.SwitchConfig().insert(pEngine);
229              // make sure the engine knows about the connection              // make sure the engine knows about the connection
230              //pEngine->Connect(this);              //pEngine->Connect(this);
231          }          }
232      }      }
233    
234      void AudioOutputDevice::Disconnect(Engine* pEngine) {      void AudioOutputDevice::Disconnect(Engine* pEngine) {
235          if (Engines.find(pEngine) != Engines.end()) { // if clause to prevent disconnect loop          std::set<Engine*>& engines = Engines.GetConfigForUpdate();
236              Engines.erase(pEngine);          if (engines.find(pEngine) != engines.end()) { // if clause to prevent disconnect loop
237                engines.erase(pEngine);
238                Engines.SwitchConfig().erase(pEngine);
239              // make sure the engine knows about the disconnection              // make sure the engine knows about the disconnection
240              //pEngine->DisconnectAudioOutputDevice();              //pEngine->DisconnectAudioOutputDevice();
241          }          }
# Line 229  namespace LinuxSampler { Line 253  namespace LinuxSampler {
253          }          }
254      }      }
255    
256        uint AudioOutputDevice::ChannelCount() {
257            return Channels.size();
258        }
259    
260      std::map<String,DeviceCreationParameter*> AudioOutputDevice::DeviceParameters() {      std::map<String,DeviceCreationParameter*> AudioOutputDevice::DeviceParameters() {
261          return Parameters;          return Parameters;
262      }      }
263    
264        EffectChain* AudioOutputDevice::AddSendEffectChain() {
265            EffectChain* pChain = new EffectChain(this, EffectChainIDs->create());
266            vEffectChains.push_back(pChain);
267            return pChain;
268        }
269    
270        void AudioOutputDevice::RemoveSendEffectChain(uint iChain) throw (Exception) {
271            if (iChain >= vEffectChains.size())
272                throw Exception(
273                    "Could not remove master effect chain " + ToString(iChain) +
274                    ", index out of bounds"
275                );
276            std::vector<EffectChain*>::iterator iter = vEffectChains.begin();
277            for (int i = 0; i < iChain; ++i) ++iter;
278            EffectChainIDs->destroy((*iter)->ID());
279            vEffectChains.erase(iter);
280        }
281    
282        EffectChain* AudioOutputDevice::SendEffectChain(uint iChain) const {
283            if (iChain >= vEffectChains.size()) return NULL;
284            return vEffectChains[iChain];
285        }
286    
287        uint AudioOutputDevice::SendEffectChainCount() const {
288            return vEffectChains.size();
289        }
290    
291        // TODO: to be removed
292        EffectChain* AudioOutputDevice::AddMasterEffectChain() {
293            return AddSendEffectChain();
294        }
295    
296        // TODO: to be removed
297        void AudioOutputDevice::RemoveMasterEffectChain(uint iChain) throw (Exception) {
298            RemoveSendEffectChain(iChain);
299        }
300    
301        // TODO: to be removed
302        EffectChain* AudioOutputDevice::MasterEffectChain(uint iChain) const {
303            return SendEffectChain(iChain);
304        }
305    
306        // TODO: to be removed
307        uint AudioOutputDevice::MasterEffectChainCount() const {
308            return SendEffectChainCount();
309        }
310    
311      int AudioOutputDevice::RenderAudio(uint Samples) {      int AudioOutputDevice::RenderAudio(uint Samples) {
312          if (Channels.empty()) return 0;          if (Channels.empty()) return 0;
313    
# Line 241  namespace LinuxSampler { Line 316  namespace LinuxSampler {
316              std::vector<AudioChannel*>::iterator iterChannels = Channels.begin();              std::vector<AudioChannel*>::iterator iterChannels = Channels.begin();
317              std::vector<AudioChannel*>::iterator end          = Channels.end();              std::vector<AudioChannel*>::iterator end          = Channels.end();
318              for (; iterChannels != end; iterChannels++)              for (; iterChannels != end; iterChannels++)
319                  (*iterChannels)->Clear(); // zero out audio buffer                  (*iterChannels)->Clear(Samples); // zero out audio buffer
320            }
321            // do the same for master effects
322            {
323                std::vector<EffectChain*>::iterator iterChains = vEffectChains.begin();
324                std::vector<EffectChain*>::iterator end        = vEffectChains.end();
325                for (; iterChains != end; ++iterChains)
326                    (*iterChains)->ClearAllChannels(); // zero out audio buffers
327          }          }
328    
329          int result = 0;          int result = 0;
330    
331          // let all connected engines render audio for the current audio fragment cycle          // let all connected engines render audio for the current audio fragment cycle
332            const std::set<Engine*>& engines = EnginesReader.Lock();
333          #if CONFIG_RT_EXCEPTIONS          #if CONFIG_RT_EXCEPTIONS
334          try          try
335          #endif // CONFIG_RT_EXCEPTIONS          #endif // CONFIG_RT_EXCEPTIONS
336          {          {
337              std::set<Engine*>::iterator iterEngine = Engines.begin();              std::set<Engine*>::iterator iterEngine = engines.begin();
338              std::set<Engine*>::iterator end        = Engines.end();              std::set<Engine*>::iterator end        = engines.end();
339              for (; iterEngine != end; iterEngine++) {              for (; iterEngine != end; iterEngine++) {
340                  int res = (*iterEngine)->RenderAudio(Samples);                  int res = (*iterEngine)->RenderAudio(Samples);
341                  if (res != 0) result = res;                  if (res != 0) result = res;
# Line 264  namespace LinuxSampler { Line 347  namespace LinuxSampler {
347              exit(EXIT_FAILURE);              exit(EXIT_FAILURE);
348          }          }
349          #endif // CONFIG_RT_EXCEPTIONS          #endif // CONFIG_RT_EXCEPTIONS
350            EnginesReader.Unlock();
351    
352            // now that the engines (might) have left fx send signals for master
353            // effects, render all master effects
354            {
355                std::vector<EffectChain*>::iterator iterChains = vEffectChains.begin();
356                std::vector<EffectChain*>::iterator end        = vEffectChains.end();
357                for (; iterChains != end; ++iterChains) {
358                    if (!(*iterChains)->EffectCount()) continue;
359                    (*iterChains)->RenderAudio(Samples);
360                    // mix the result of the last effect in the chain to the audio
361                    // output device channel(s)
362                    Effect* pLastEffect =
363                        (*iterChains)->GetEffect((*iterChains)->EffectCount() - 1);
364                    for (int iChan = 0; iChan < pLastEffect->OutputChannelCount() && iChan < ChannelCount(); ++iChan)
365                        pLastEffect->OutputChannel(iChan)->MixTo(Channel(iChan), Samples);
366                }
367            }
368    
369          return result;          return result;
370      }      }
# Line 276  namespace LinuxSampler { Line 377  namespace LinuxSampler {
377              std::vector<AudioChannel*>::iterator iterChannels = Channels.begin();              std::vector<AudioChannel*>::iterator iterChannels = Channels.begin();
378              std::vector<AudioChannel*>::iterator end          = Channels.end();              std::vector<AudioChannel*>::iterator end          = Channels.end();
379              for (; iterChannels != end; iterChannels++)              for (; iterChannels != end; iterChannels++)
380                  (*iterChannels)->Clear(); // zero out audio buffer                  (*iterChannels)->Clear(Samples); // zero out audio buffer
381          }          }
382    
383          return 0;          return 0;

Legend:
Removed from v.554  
changed lines
  Added in v.2137

  ViewVC Help
Powered by ViewVC