/[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 1722 - (show annotations) (download)
Thu Apr 10 17:41:32 2008 UTC (16 years ago) by schoenebeck
File size: 13113 byte(s)
* minor preparations for internal effects support
* bumped version to 0.5.1.5cvs

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

  ViewVC Help
Powered by ViewVC