/[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 2137 - (hide annotations) (download)
Mon Oct 4 12:20:23 2010 UTC (13 years, 5 months ago) by schoenebeck
File size: 13888 byte(s)
* revised previously added new LSCP commands regarding effect handling:
  renamed "master effects" to "send effects", since this is the actual
  correct common term for those effects
* also corrected the names regarding "send effects" in the respective
  methods of the "FxSsnd" class and "AudioOutputDevice" class of the
  sampler's C++ API, the old methods are still available but marked as
  deprecated and scheduled for removal
* added LSCP command "SET FX_SEND SEND_EFFECT <sampler_channel>
  <fx_send_id> <effect_chain> <chain_pos>"
* added LSCP command "REMOVE FX_SEND SEND_EFFECT <sampler_channel>
  <fx_send_id>"
* added a list of common known LADSPA paths (for Windows and POSIX) which
  will be automatically checked for being used as LADSPA plugin directory
  (if the user did not set the LADSPA_PATH environment variable explicitly)
* bumped version to 1.0.0.cvs8

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     "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 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 schoenebeck 2137 uint AudioOutputDevice::SendEffectChainCount() const {
288 schoenebeck 1722 return vEffectChains.size();
289     }
290    
291 schoenebeck 2137 // 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 schoenebeck 200 int AudioOutputDevice::RenderAudio(uint Samples) {
312     if (Channels.empty()) return 0;
313    
314     // reset all channels with silence
315     {
316     std::vector<AudioChannel*>::iterator iterChannels = Channels.begin();
317     std::vector<AudioChannel*>::iterator end = Channels.end();
318     for (; iterChannels != end; iterChannels++)
319 persson 1748 (*iterChannels)->Clear(Samples); // zero out audio buffer
320 schoenebeck 200 }
321 schoenebeck 1722 // 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 schoenebeck 200
329     int result = 0;
330    
331     // let all connected engines render audio for the current audio fragment cycle
332 persson 846 const std::set<Engine*>& engines = EnginesReader.Lock();
333 schoenebeck 554 #if CONFIG_RT_EXCEPTIONS
334 schoenebeck 272 try
335 schoenebeck 554 #endif // CONFIG_RT_EXCEPTIONS
336 schoenebeck 200 {
337 persson 840 std::set<Engine*>::iterator iterEngine = engines.begin();
338     std::set<Engine*>::iterator end = engines.end();
339 schoenebeck 412 for (; iterEngine != end; iterEngine++) {
340     int res = (*iterEngine)->RenderAudio(Samples);
341 schoenebeck 200 if (res != 0) result = res;
342     }
343     }
344 schoenebeck 554 #if CONFIG_RT_EXCEPTIONS
345 schoenebeck 272 catch (std::runtime_error se) {
346     std::cerr << "std::runtime_error: " << se.what() << std::endl << std::flush;
347     exit(EXIT_FAILURE);
348     }
349 schoenebeck 554 #endif // CONFIG_RT_EXCEPTIONS
350 schoenebeck 1722 EnginesReader.Unlock();
351 schoenebeck 200
352 schoenebeck 1722 // 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 schoenebeck 200 return result;
370     }
371    
372     int AudioOutputDevice::RenderSilence(uint Samples) {
373     if (Channels.empty()) return 0;
374    
375     // reset all channels with silence
376     {
377     std::vector<AudioChannel*>::iterator iterChannels = Channels.begin();
378     std::vector<AudioChannel*>::iterator end = Channels.end();
379     for (; iterChannels != end; iterChannels++)
380 persson 1748 (*iterChannels)->Clear(Samples); // zero out audio buffer
381 schoenebeck 200 }
382    
383     return 0;
384     }
385    
386     } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC