/[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 3054 - (hide annotations) (download)
Thu Dec 15 12:47:45 2016 UTC (7 years, 4 months ago) by schoenebeck
File size: 15010 byte(s)
* Fixed numerous compiler warnings.
* Bumped version (2.0.0.svn32).

1 schoenebeck 200 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 3054 * Copyright (C) 2005 - 2016 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 schoenebeck 2410
244     void AudioOutputDevice::ReconnectAll() {
245     // copy by value, not by reference here !
246     std::set<Engine*> engines = Engines.GetConfigForUpdate();
247     {
248     std::set<Engine*>::iterator iterEngine = engines.begin();
249     std::set<Engine*>::iterator end = engines.end();
250     for (; iterEngine != end; iterEngine++) {
251     (*iterEngine)->ReconnectAudioOutputDevice();
252     }
253     }
254 schoenebeck 2412
255     // update all effects as well
256     for (std::vector<EffectChain*>::iterator it = vEffectChains.begin();
257     it != vEffectChains.end(); ++it)
258     {
259     EffectChain* pChain = *it;
260     pChain->Reconnect(this);
261     }
262 schoenebeck 2410 }
263 schoenebeck 200
264     AudioChannel* AudioOutputDevice::Channel(uint ChannelIndex) {
265     return (ChannelIndex < Channels.size()) ? Channels[ChannelIndex] : NULL;
266     }
267    
268 schoenebeck 226 void AudioOutputDevice::AcquireChannels(uint Channels) {
269     if (Channels > this->Channels.size()) {
270 schoenebeck 3054 for (size_t c = this->Channels.size(); c < Channels; c++) {
271     this->Channels.push_back(CreateChannel(uint(c)));
272 schoenebeck 226 }
273     }
274     }
275    
276 schoenebeck 1001 uint AudioOutputDevice::ChannelCount() {
277 schoenebeck 3054 return (uint) Channels.size();
278 schoenebeck 1001 }
279    
280 schoenebeck 200 std::map<String,DeviceCreationParameter*> AudioOutputDevice::DeviceParameters() {
281     return Parameters;
282     }
283    
284 schoenebeck 2137 EffectChain* AudioOutputDevice::AddSendEffectChain() {
285 schoenebeck 2135 EffectChain* pChain = new EffectChain(this, EffectChainIDs->create());
286 schoenebeck 1722 vEffectChains.push_back(pChain);
287     return pChain;
288     }
289    
290 schoenebeck 2137 void AudioOutputDevice::RemoveSendEffectChain(uint iChain) throw (Exception) {
291 schoenebeck 1722 if (iChain >= vEffectChains.size())
292     throw Exception(
293 iliev 2198 "Could not remove send effect chain " + ToString(iChain) +
294 schoenebeck 1722 ", index out of bounds"
295     );
296     std::vector<EffectChain*>::iterator iter = vEffectChains.begin();
297     for (int i = 0; i < iChain; ++i) ++iter;
298 schoenebeck 2135 EffectChainIDs->destroy((*iter)->ID());
299 schoenebeck 1722 vEffectChains.erase(iter);
300     }
301    
302 schoenebeck 2137 EffectChain* AudioOutputDevice::SendEffectChain(uint iChain) const {
303 schoenebeck 1722 if (iChain >= vEffectChains.size()) return NULL;
304     return vEffectChains[iChain];
305     }
306    
307 iliev 2198 EffectChain* AudioOutputDevice::SendEffectChainByID(uint iChainID) const {
308     for (int i = 0; i < SendEffectChainCount(); i++) {
309     if (SendEffectChain(i)->ID() == iChainID) return SendEffectChain(i);
310     }
311    
312     return NULL;
313     }
314    
315 schoenebeck 2137 uint AudioOutputDevice::SendEffectChainCount() const {
316 schoenebeck 3054 return (uint) vEffectChains.size();
317 schoenebeck 1722 }
318    
319 schoenebeck 2137 // TODO: to be removed
320     EffectChain* AudioOutputDevice::AddMasterEffectChain() {
321     return AddSendEffectChain();
322     }
323    
324     // TODO: to be removed
325     void AudioOutputDevice::RemoveMasterEffectChain(uint iChain) throw (Exception) {
326     RemoveSendEffectChain(iChain);
327     }
328    
329     // TODO: to be removed
330     EffectChain* AudioOutputDevice::MasterEffectChain(uint iChain) const {
331     return SendEffectChain(iChain);
332     }
333    
334     // TODO: to be removed
335     uint AudioOutputDevice::MasterEffectChainCount() const {
336     return SendEffectChainCount();
337     }
338 schoenebeck 2410
339     float AudioOutputDevice::latency() {
340     return float(MaxSamplesPerCycle()) / float(SampleRate());
341     }
342 schoenebeck 2137
343 schoenebeck 200 int AudioOutputDevice::RenderAudio(uint Samples) {
344     if (Channels.empty()) return 0;
345    
346     // reset all channels with silence
347     {
348     std::vector<AudioChannel*>::iterator iterChannels = Channels.begin();
349     std::vector<AudioChannel*>::iterator end = Channels.end();
350     for (; iterChannels != end; iterChannels++)
351 persson 1748 (*iterChannels)->Clear(Samples); // zero out audio buffer
352 schoenebeck 200 }
353 schoenebeck 1722 // do the same for 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     (*iterChains)->ClearAllChannels(); // zero out audio buffers
359     }
360 schoenebeck 200
361     int result = 0;
362    
363     // let all connected engines render audio for the current audio fragment cycle
364 persson 846 const std::set<Engine*>& engines = EnginesReader.Lock();
365 schoenebeck 554 #if CONFIG_RT_EXCEPTIONS
366 schoenebeck 272 try
367 schoenebeck 554 #endif // CONFIG_RT_EXCEPTIONS
368 schoenebeck 200 {
369 persson 840 std::set<Engine*>::iterator iterEngine = engines.begin();
370     std::set<Engine*>::iterator end = engines.end();
371 schoenebeck 412 for (; iterEngine != end; iterEngine++) {
372     int res = (*iterEngine)->RenderAudio(Samples);
373 schoenebeck 200 if (res != 0) result = res;
374     }
375     }
376 schoenebeck 554 #if CONFIG_RT_EXCEPTIONS
377 schoenebeck 272 catch (std::runtime_error se) {
378     std::cerr << "std::runtime_error: " << se.what() << std::endl << std::flush;
379     exit(EXIT_FAILURE);
380     }
381 schoenebeck 554 #endif // CONFIG_RT_EXCEPTIONS
382 schoenebeck 1722 EnginesReader.Unlock();
383 schoenebeck 200
384 schoenebeck 1722 // now that the engines (might) have left fx send signals for master
385     // effects, render all master effects
386     {
387     std::vector<EffectChain*>::iterator iterChains = vEffectChains.begin();
388     std::vector<EffectChain*>::iterator end = vEffectChains.end();
389     for (; iterChains != end; ++iterChains) {
390     if (!(*iterChains)->EffectCount()) continue;
391     (*iterChains)->RenderAudio(Samples);
392     // mix the result of the last effect in the chain to the audio
393     // output device channel(s)
394     Effect* pLastEffect =
395     (*iterChains)->GetEffect((*iterChains)->EffectCount() - 1);
396     for (int iChan = 0; iChan < pLastEffect->OutputChannelCount() && iChan < ChannelCount(); ++iChan)
397     pLastEffect->OutputChannel(iChan)->MixTo(Channel(iChan), Samples);
398     }
399     }
400    
401 schoenebeck 200 return result;
402     }
403    
404     int AudioOutputDevice::RenderSilence(uint Samples) {
405     if (Channels.empty()) return 0;
406    
407     // reset all channels with silence
408     {
409     std::vector<AudioChannel*>::iterator iterChannels = Channels.begin();
410     std::vector<AudioChannel*>::iterator end = Channels.end();
411     for (; iterChannels != end; iterChannels++)
412 persson 1748 (*iterChannels)->Clear(Samples); // zero out audio buffer
413 schoenebeck 200 }
414    
415     return 0;
416     }
417    
418     } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC