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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2198 - (hide annotations) (download)
Sun Jul 3 18:06:51 2011 UTC (12 years, 9 months ago) by iliev
File size: 14144 byte(s)
* bugfix: LSCP command "REMOVE FX_SEND EFFECT" was broken
* fixed a bug in FxSend::SetDestinationEffect
* bugfix: parent was not set when effect instance is appended
* bugfix: was able to remove effect chain while FX send is connected to it
* bugfix: was able to remove effect instance from effect chain while
  FX send is connected to that instance

1 schoenebeck 200 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 2137 * Copyright (C) 2005 - 2010 Christian Schoenebeck *
7 schoenebeck 200 * *
8     * 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 *
10     * the Free Software Foundation; either version 2 of the License, or *
11     * (at your option) any later version. *
12     * *
13     * This program 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 program; 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 "AudioOutputDeviceFactory.h"
25     #include "AudioOutputDevice.h"
26 schoenebeck 1424 #include "../../common/global_private.h"
27 schoenebeck 2135 #include "../../common/IDGenerator.h"
28 schoenebeck 200
29     namespace LinuxSampler {
30    
31 schoenebeck 226 // *************** ParameterActive ***************
32     // *
33    
34     AudioOutputDevice::ParameterActive::ParameterActive() : DeviceCreationParameterBool() {
35     InitWithDefault();
36     }
37    
38     AudioOutputDevice::ParameterActive::ParameterActive(String s) : DeviceCreationParameterBool(s) {
39     }
40    
41     String AudioOutputDevice::ParameterActive::Description() {
42     return "Enable / disable device";
43     }
44    
45     bool AudioOutputDevice::ParameterActive::Fix() {
46     return false;
47     }
48    
49     bool AudioOutputDevice::ParameterActive::Mandatory() {
50     return false;
51     }
52    
53     std::map<String,DeviceCreationParameter*> AudioOutputDevice::ParameterActive::DependsAsParameters() {
54     return std::map<String,DeviceCreationParameter*>();
55     }
56    
57     optional<bool> AudioOutputDevice::ParameterActive::DefaultAsBool(std::map<String,String> Parameters) {
58     return true;
59     }
60    
61 schoenebeck 880 void AudioOutputDevice::ParameterActive::OnSetValue(bool b) throw (Exception) {
62 schoenebeck 226 if (b) ((AudioOutputDevice*)pDevice)->Play();
63     else ((AudioOutputDevice*)pDevice)->Stop();
64     }
65    
66     String AudioOutputDevice::ParameterActive::Name() {
67     return "ACTIVE";
68     }
69    
70    
71    
72     // *************** ParameterSampleRate ***************
73     // *
74    
75     AudioOutputDevice::ParameterSampleRate::ParameterSampleRate() : DeviceCreationParameterInt() {
76     InitWithDefault();
77     }
78    
79     AudioOutputDevice::ParameterSampleRate::ParameterSampleRate(String s) : DeviceCreationParameterInt(s) {
80     }
81    
82     String AudioOutputDevice::ParameterSampleRate::Description() {
83     return "Output sample rate";
84     }
85    
86     bool AudioOutputDevice::ParameterSampleRate::Fix() {
87     return true;
88     }
89    
90     bool AudioOutputDevice::ParameterSampleRate::Mandatory() {
91     return false;
92     }
93    
94     std::map<String,DeviceCreationParameter*> AudioOutputDevice::ParameterSampleRate::DependsAsParameters() {
95     return std::map<String,DeviceCreationParameter*>();
96     }
97    
98     optional<int> AudioOutputDevice::ParameterSampleRate::DefaultAsInt(std::map<String,String> Parameters) {
99     return 44100;
100     }
101    
102     optional<int> AudioOutputDevice::ParameterSampleRate::RangeMinAsInt(std::map<String,String> Parameters) {
103     return optional<int>::nothing;
104     }
105    
106     optional<int> AudioOutputDevice::ParameterSampleRate::RangeMaxAsInt(std::map<String,String> Parameters) {
107     return optional<int>::nothing;
108     }
109    
110     std::vector<int> AudioOutputDevice::ParameterSampleRate::PossibilitiesAsInt(std::map<String,String> Parameters) {
111     return std::vector<int>();
112     }
113    
114 schoenebeck 1607 int AudioOutputDevice::ParameterSampleRate::ValueAsInt() {
115     return (pDevice) ? (int) ((AudioOutputDevice*)pDevice)->SampleRate()
116     : DeviceCreationParameterInt::ValueAsInt();
117     }
118    
119 schoenebeck 880 void AudioOutputDevice::ParameterSampleRate::OnSetValue(int i) throw (Exception) {
120 schoenebeck 226 /* cannot happen, as parameter is fix */
121     }
122    
123     String AudioOutputDevice::ParameterSampleRate::Name() {
124     return "SAMPLERATE";
125     }
126    
127    
128    
129     // *************** ParameterChannels ***************
130     // *
131    
132     AudioOutputDevice::ParameterChannels::ParameterChannels() : DeviceCreationParameterInt() {
133     InitWithDefault();
134     }
135    
136     AudioOutputDevice::ParameterChannels::ParameterChannels(String s) : DeviceCreationParameterInt(s) {
137     }
138    
139     String AudioOutputDevice::ParameterChannels::Description() {
140     return "Number of output channels";
141     }
142    
143     bool AudioOutputDevice::ParameterChannels::Fix() {
144     return false;
145     }
146    
147     bool AudioOutputDevice::ParameterChannels::Mandatory() {
148     return false;
149     }
150    
151     std::map<String,DeviceCreationParameter*> AudioOutputDevice::ParameterChannels::DependsAsParameters() {
152     return std::map<String,DeviceCreationParameter*>();
153     }
154    
155     optional<int> AudioOutputDevice::ParameterChannels::DefaultAsInt(std::map<String,String> Parameters) {
156     return 2;
157     }
158    
159     optional<int> AudioOutputDevice::ParameterChannels::RangeMinAsInt(std::map<String,String> Parameters) {
160 iliev 1305 return 1;
161 schoenebeck 226 }
162    
163     optional<int> AudioOutputDevice::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) {
164 schoenebeck 1599 return optional<int>::nothing;
165 schoenebeck 226 }
166    
167     std::vector<int> AudioOutputDevice::ParameterChannels::PossibilitiesAsInt(std::map<String,String> Parameters) {
168     return std::vector<int>();
169     }
170    
171 schoenebeck 880 void AudioOutputDevice::ParameterChannels::OnSetValue(int i) throw (Exception) {
172 schoenebeck 226 ((AudioOutputDevice*)pDevice)->AcquireChannels(i);
173     }
174    
175     String AudioOutputDevice::ParameterChannels::Name() {
176     return "CHANNELS";
177     }
178    
179    
180    
181     // *************** AudioOutputDevice ***************
182     // *
183    
184 persson 846 AudioOutputDevice::AudioOutputDevice(std::map<String,DeviceCreationParameter*> DriverParameters)
185     : EnginesReader(Engines) {
186 schoenebeck 200 this->Parameters = DriverParameters;
187 schoenebeck 2135 EffectChainIDs = new IDGenerator();
188 schoenebeck 200 }
189    
190     AudioOutputDevice::~AudioOutputDevice() {
191 schoenebeck 226 // delete all audio channels
192     {
193     std::vector<AudioChannel*>::iterator iter = Channels.begin();
194     while (iter != Channels.end()) {
195     delete *iter;
196     iter++;
197     }
198 persson 836 Channels.clear();
199 schoenebeck 200 }
200 schoenebeck 226
201     // delete all device parameters
202     {
203     std::map<String,DeviceCreationParameter*>::iterator iter = Parameters.begin();
204     while (iter != Parameters.end()) {
205     delete iter->second;
206     iter++;
207     }
208 persson 835 Parameters.clear();
209 schoenebeck 226 }
210 schoenebeck 1722
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 schoenebeck 2135
221     delete EffectChainIDs;
222 schoenebeck 200 }
223    
224 schoenebeck 412 void AudioOutputDevice::Connect(Engine* pEngine) {
225 persson 840 std::set<Engine*>& engines = Engines.GetConfigForUpdate();
226     if (engines.find(pEngine) == engines.end()) {
227     engines.insert(pEngine);
228     Engines.SwitchConfig().insert(pEngine);
229 schoenebeck 412 // make sure the engine knows about the connection
230     //pEngine->Connect(this);
231 schoenebeck 200 }
232     }
233    
234 schoenebeck 412 void AudioOutputDevice::Disconnect(Engine* pEngine) {
235 persson 840 std::set<Engine*>& engines = Engines.GetConfigForUpdate();
236     if (engines.find(pEngine) != engines.end()) { // if clause to prevent disconnect loop
237     engines.erase(pEngine);
238     Engines.SwitchConfig().erase(pEngine);
239 schoenebeck 412 // make sure the engine knows about the disconnection
240     //pEngine->DisconnectAudioOutputDevice();
241 schoenebeck 200 }
242     }
243    
244     AudioChannel* AudioOutputDevice::Channel(uint ChannelIndex) {
245     return (ChannelIndex < Channels.size()) ? Channels[ChannelIndex] : NULL;
246     }
247    
248 schoenebeck 226 void AudioOutputDevice::AcquireChannels(uint Channels) {
249     if (Channels > this->Channels.size()) {
250     for (int c = this->Channels.size(); c < Channels; c++) {
251     this->Channels.push_back(CreateChannel(c));
252     }
253     }
254     }
255    
256 schoenebeck 1001 uint AudioOutputDevice::ChannelCount() {
257     return Channels.size();
258     }
259    
260 schoenebeck 200 std::map<String,DeviceCreationParameter*> AudioOutputDevice::DeviceParameters() {
261     return Parameters;
262     }
263    
264 schoenebeck 2137 EffectChain* AudioOutputDevice::AddSendEffectChain() {
265 schoenebeck 2135 EffectChain* pChain = new EffectChain(this, EffectChainIDs->create());
266 schoenebeck 1722 vEffectChains.push_back(pChain);
267     return pChain;
268     }
269    
270 schoenebeck 2137 void AudioOutputDevice::RemoveSendEffectChain(uint iChain) throw (Exception) {
271 schoenebeck 1722 if (iChain >= vEffectChains.size())
272     throw Exception(
273 iliev 2198 "Could not remove send effect chain " + ToString(iChain) +
274 schoenebeck 1722 ", index out of bounds"
275     );
276     std::vector<EffectChain*>::iterator iter = vEffectChains.begin();
277     for (int i = 0; i < iChain; ++i) ++iter;
278 schoenebeck 2135 EffectChainIDs->destroy((*iter)->ID());
279 schoenebeck 1722 vEffectChains.erase(iter);
280     }
281    
282 schoenebeck 2137 EffectChain* AudioOutputDevice::SendEffectChain(uint iChain) const {
283 schoenebeck 1722 if (iChain >= vEffectChains.size()) return NULL;
284     return vEffectChains[iChain];
285     }
286    
287 iliev 2198 EffectChain* AudioOutputDevice::SendEffectChainByID(uint iChainID) const {
288     for (int i = 0; i < SendEffectChainCount(); i++) {
289     if (SendEffectChain(i)->ID() == iChainID) return SendEffectChain(i);
290     }
291    
292     return NULL;
293     }
294    
295 schoenebeck 2137 uint AudioOutputDevice::SendEffectChainCount() const {
296 schoenebeck 1722 return vEffectChains.size();
297     }
298    
299 schoenebeck 2137 // TODO: to be removed
300     EffectChain* AudioOutputDevice::AddMasterEffectChain() {
301     return AddSendEffectChain();
302     }
303    
304     // TODO: to be removed
305     void AudioOutputDevice::RemoveMasterEffectChain(uint iChain) throw (Exception) {
306     RemoveSendEffectChain(iChain);
307     }
308    
309     // TODO: to be removed
310     EffectChain* AudioOutputDevice::MasterEffectChain(uint iChain) const {
311     return SendEffectChain(iChain);
312     }
313    
314     // TODO: to be removed
315     uint AudioOutputDevice::MasterEffectChainCount() const {
316     return SendEffectChainCount();
317     }
318    
319 schoenebeck 200 int AudioOutputDevice::RenderAudio(uint Samples) {
320     if (Channels.empty()) return 0;
321    
322     // reset all channels with silence
323     {
324     std::vector<AudioChannel*>::iterator iterChannels = Channels.begin();
325     std::vector<AudioChannel*>::iterator end = Channels.end();
326     for (; iterChannels != end; iterChannels++)
327 persson 1748 (*iterChannels)->Clear(Samples); // zero out audio buffer
328 schoenebeck 200 }
329 schoenebeck 1722 // do the same for master effects
330     {
331     std::vector<EffectChain*>::iterator iterChains = vEffectChains.begin();
332     std::vector<EffectChain*>::iterator end = vEffectChains.end();
333     for (; iterChains != end; ++iterChains)
334     (*iterChains)->ClearAllChannels(); // zero out audio buffers
335     }
336 schoenebeck 200
337     int result = 0;
338    
339     // let all connected engines render audio for the current audio fragment cycle
340 persson 846 const std::set<Engine*>& engines = EnginesReader.Lock();
341 schoenebeck 554 #if CONFIG_RT_EXCEPTIONS
342 schoenebeck 272 try
343 schoenebeck 554 #endif // CONFIG_RT_EXCEPTIONS
344 schoenebeck 200 {
345 persson 840 std::set<Engine*>::iterator iterEngine = engines.begin();
346     std::set<Engine*>::iterator end = engines.end();
347 schoenebeck 412 for (; iterEngine != end; iterEngine++) {
348     int res = (*iterEngine)->RenderAudio(Samples);
349 schoenebeck 200 if (res != 0) result = res;
350     }
351     }
352 schoenebeck 554 #if CONFIG_RT_EXCEPTIONS
353 schoenebeck 272 catch (std::runtime_error se) {
354     std::cerr << "std::runtime_error: " << se.what() << std::endl << std::flush;
355     exit(EXIT_FAILURE);
356     }
357 schoenebeck 554 #endif // CONFIG_RT_EXCEPTIONS
358 schoenebeck 1722 EnginesReader.Unlock();
359 schoenebeck 200
360 schoenebeck 1722 // now that the engines (might) have left fx send signals for master
361     // effects, render all master effects
362     {
363     std::vector<EffectChain*>::iterator iterChains = vEffectChains.begin();
364     std::vector<EffectChain*>::iterator end = vEffectChains.end();
365     for (; iterChains != end; ++iterChains) {
366     if (!(*iterChains)->EffectCount()) continue;
367     (*iterChains)->RenderAudio(Samples);
368     // mix the result of the last effect in the chain to the audio
369     // output device channel(s)
370     Effect* pLastEffect =
371     (*iterChains)->GetEffect((*iterChains)->EffectCount() - 1);
372     for (int iChan = 0; iChan < pLastEffect->OutputChannelCount() && iChan < ChannelCount(); ++iChan)
373     pLastEffect->OutputChannel(iChan)->MixTo(Channel(iChan), Samples);
374     }
375     }
376    
377 schoenebeck 200 return result;
378     }
379    
380     int AudioOutputDevice::RenderSilence(uint Samples) {
381     if (Channels.empty()) return 0;
382    
383     // reset all channels with silence
384     {
385     std::vector<AudioChannel*>::iterator iterChannels = Channels.begin();
386     std::vector<AudioChannel*>::iterator end = Channels.end();
387     for (; iterChannels != end; iterChannels++)
388 persson 1748 (*iterChannels)->Clear(Samples); // zero out audio buffer
389 schoenebeck 200 }
390    
391     return 0;
392     }
393    
394     } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC