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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3054 - (show 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 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 - 2016 Christian Schoenebeck *
7 * *
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 #include "../../common/global_private.h"
27 #include "../../common/IDGenerator.h"
28
29 namespace LinuxSampler {
30
31 // *************** 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 void AudioOutputDevice::ParameterActive::OnSetValue(bool b) throw (Exception) {
62 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 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 */
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 return 1;
161 }
162
163 optional<int> AudioOutputDevice::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) {
164 return optional<int>::nothing;
165 }
166
167 std::vector<int> AudioOutputDevice::ParameterChannels::PossibilitiesAsInt(std::map<String,String> Parameters) {
168 return std::vector<int>();
169 }
170
171 void AudioOutputDevice::ParameterChannels::OnSetValue(int i) throw (Exception) {
172 ((AudioOutputDevice*)pDevice)->AcquireChannels(i);
173 }
174
175 String AudioOutputDevice::ParameterChannels::Name() {
176 return "CHANNELS";
177 }
178
179
180
181 // *************** AudioOutputDevice ***************
182 // *
183
184 AudioOutputDevice::AudioOutputDevice(std::map<String,DeviceCreationParameter*> DriverParameters)
185 : EnginesReader(Engines) {
186 this->Parameters = DriverParameters;
187 EffectChainIDs = new IDGenerator();
188 }
189
190 AudioOutputDevice::~AudioOutputDevice() {
191 // 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 Channels.clear();
199 }
200
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 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) {
225 std::set<Engine*>& engines = Engines.GetConfigForUpdate();
226 if (engines.find(pEngine) == engines.end()) {
227 engines.insert(pEngine);
228 Engines.SwitchConfig().insert(pEngine);
229 // make sure the engine knows about the connection
230 //pEngine->Connect(this);
231 }
232 }
233
234 void AudioOutputDevice::Disconnect(Engine* pEngine) {
235 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 // make sure the engine knows about the disconnection
240 //pEngine->DisconnectAudioOutputDevice();
241 }
242 }
243
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
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 }
263
264 AudioChannel* AudioOutputDevice::Channel(uint ChannelIndex) {
265 return (ChannelIndex < Channels.size()) ? Channels[ChannelIndex] : NULL;
266 }
267
268 void AudioOutputDevice::AcquireChannels(uint Channels) {
269 if (Channels > this->Channels.size()) {
270 for (size_t c = this->Channels.size(); c < Channels; c++) {
271 this->Channels.push_back(CreateChannel(uint(c)));
272 }
273 }
274 }
275
276 uint AudioOutputDevice::ChannelCount() {
277 return (uint) Channels.size();
278 }
279
280 std::map<String,DeviceCreationParameter*> AudioOutputDevice::DeviceParameters() {
281 return Parameters;
282 }
283
284 EffectChain* AudioOutputDevice::AddSendEffectChain() {
285 EffectChain* pChain = new EffectChain(this, EffectChainIDs->create());
286 vEffectChains.push_back(pChain);
287 return pChain;
288 }
289
290 void AudioOutputDevice::RemoveSendEffectChain(uint iChain) throw (Exception) {
291 if (iChain >= vEffectChains.size())
292 throw Exception(
293 "Could not remove send effect chain " + ToString(iChain) +
294 ", index out of bounds"
295 );
296 std::vector<EffectChain*>::iterator iter = vEffectChains.begin();
297 for (int i = 0; i < iChain; ++i) ++iter;
298 EffectChainIDs->destroy((*iter)->ID());
299 vEffectChains.erase(iter);
300 }
301
302 EffectChain* AudioOutputDevice::SendEffectChain(uint iChain) const {
303 if (iChain >= vEffectChains.size()) return NULL;
304 return vEffectChains[iChain];
305 }
306
307 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 uint AudioOutputDevice::SendEffectChainCount() const {
316 return (uint) vEffectChains.size();
317 }
318
319 // 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
339 float AudioOutputDevice::latency() {
340 return float(MaxSamplesPerCycle()) / float(SampleRate());
341 }
342
343 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 (*iterChannels)->Clear(Samples); // zero out audio buffer
352 }
353 // 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
361 int result = 0;
362
363 // let all connected engines render audio for the current audio fragment cycle
364 const std::set<Engine*>& engines = EnginesReader.Lock();
365 #if CONFIG_RT_EXCEPTIONS
366 try
367 #endif // CONFIG_RT_EXCEPTIONS
368 {
369 std::set<Engine*>::iterator iterEngine = engines.begin();
370 std::set<Engine*>::iterator end = engines.end();
371 for (; iterEngine != end; iterEngine++) {
372 int res = (*iterEngine)->RenderAudio(Samples);
373 if (res != 0) result = res;
374 }
375 }
376 #if CONFIG_RT_EXCEPTIONS
377 catch (std::runtime_error se) {
378 std::cerr << "std::runtime_error: " << se.what() << std::endl << std::flush;
379 exit(EXIT_FAILURE);
380 }
381 #endif // CONFIG_RT_EXCEPTIONS
382 EnginesReader.Unlock();
383
384 // 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 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 (*iterChannels)->Clear(Samples); // zero out audio buffer
413 }
414
415 return 0;
416 }
417
418 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC